Vue.Jsの計算されたプロパティにパラメーターを渡すことはできますか


199

これは、Vue.Jsの計算されたプロパティでパラメーターを渡すことが可能ですか?ゲッター/セッターが計算されたものを使用すると、パラメーターを取得して変数に割り当てることができます。ドキュメントからここのように:

// ...
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
// ...

これも可能ですか?

// ...
computed: {
  fullName: function (salut) {
      return salut + ' ' + this.firstName + ' ' + this.lastName    
  }
}
// ...

計算されたプロパティは引数を取り、必要な出力を返します。しかし、これを試すと、次のエラーが発生します。

vue.common.js:2250 Uncaught TypeError:fullName is not a function(…)

このような場合にメソッドを使用する必要がありますか?


5
いいえ、パラメータを計算されたプロパティに渡すことはできません。はい、メソッドを使用するのが最も簡単な方法です。
16年

回答:


266

おそらくあなたはメソッドを使いたいです

<span>{{ fullName('Hi') }}</span>

methods: {
  fullName(salut) {
      return `${salut} ${this.firstName} ${this.lastName}`
  }
}

より長い説明

技術的には、次のようなパラメーターを持つ計算プロパティを使用できます。

computed: {
   fullName() {
      return salut => `${salut} ${this.firstName} ${this.lastName}`
   }
}

(このUnirgyための基本コードをありがとう。)

計算されたプロパティとメソッドの違いは、計算されたプロパティはキャッシュされ、依存関係が変更された場合にのみ変更されることです。この方法は、それが呼ばれていますたびに評価します

パラメータが必要な場合、通常、そのような場合に、計算されたプロパティ関数をメソッドに使用する利点はありません。これにより、パラメーター化されたゲッター関数をVueインスタンスにバインドできますが、キャッシュが失われるため、実際には何も得られず、実際に反応性が失われる可能性があります(AFAIU)。詳細については、Vueのドキュメントhttps://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methodsをご覧ください。

唯一の有用な状況は、ゲッター使用する必要があり、それをパラメーター化する必要がある場合です。この状況は、たとえばVuexで発生します。Vuexでは、ストアからパラメーター化された結果を同期的に取得する唯一の方法です(アクションは非同期です)。したがって、このアプローチは、ゲッターの公式Vuexドキュメントにリストされてい ますhttps://vuex.vuejs.org/guide/getters.html#method-style-access


1
<span v-text="fullName('Hi')"></span>代わりに使用することもできます。
SalchiPapa 2017

2
問題は、<span :text="message"></span>Vue 2.0では機能しなくなったため、代わりに使用する必要があることです。<span v-text="message"></span>または<span>{{ message }}</span>、このcodepenに示すように:codepen.io/Ismael-VC/pen/dzGzJa
SalchiPapa

1
あなたが正しい。これは2.0で変更されていることに気付きませんでした。訂正ありがとうございます!
damienix 2017

4
計算されたプロパティはES5ゲッター構文​​を使用しますが、パラメーターでの呼び出しはサポートされていません(括弧はありません)。したがって、これは言語レベルの制限であり、それがVue.jsに組み込まれる方法です。
damienix 2018

1
@PedroMoreiraの返信が非常に遅くなって申し訳ありません。これを分析する時間を見つけました。確かに、私が書いた内容が明確で混乱していないことは間違いありません:)私は答えを修正し、より明確かつ正確になるように言い換えるために最善を尽くしました。明確になったらお知らせください。ありがとう。
damienix

27

メソッドを使用することもできますが、データを変更していない場合や外部に影響がない場合は、メソッドではなく計算されたプロパティを使用することをお勧めします。

次のようにして、計算されたプロパティに引数を渡すことができます(ドキュメントには記載されていませんが、メンテナーによって提案されています。場所は覚えていません)。

computed: {
   fullName: function () {
      var vm = this;
      return function (salut) {
          return salut + ' ' + vm.firstName + ' ' + vm.lastName;  
      };
   }
}

編集:このソリューションは使用しないでください。コードを複雑にするだけで、メリットはありません。


参考にしていただけると助かります。これはうまくいくはずです。
Saurabh 2017年

@saurabh申し訳ありませんが、githubのあまり説明的ではない問題の解決策でした。現在、それを見つけることができません...
2017年

これは私にとってはうまくいきますが、私がファンではないのは、実際のプロパティではなく関数を返すという点だけなので、VueJS devtoolsは結果をどこにも表示しません。これが計算されたプロパティで一般的なものかどうかはわかりませんが、トラブルシューティングが少し難しくなります。
ネイトリッター

4
キャッシュはどのように処理されますか?パラメータが変更されても正常に動作しますか?
damienix

私はそれがreturn関数の中に何かをキャッシュするとは思わない。メソッドとの違いは、純粋に慣例によるものです(メソッドには効果があり、計算は取得のみを目的としています)
Unirgy

8

まあ、技術的に言えば、vuexのゲッター関数にパラメーターを渡すのと同じ方法で、計算された関数にパラメーターを渡すことができます。このような関数は、関数を返す関数です。

たとえば、ストアのゲッターでは:

{
  itemById: function(state) {
    return (id) => state.itemPool[id];
  }
}

このゲッターは、コンポーネントの計算された関数にマッピングできます。

computed: {
  ...mapGetters([
    'ids',
    'itemById'
  ])
}

また、この計算された関数をテンプレートで次のように使用できます。

<div v-for="id in ids" :key="id">{{itemById(id).description}}</div>

同じアプローチを適用して、パラメーターを受け取る計算メソッドを作成できます。

computed: {
  ...mapGetters([
    'ids',
    'itemById'
  ]),
  descriptionById: function() {
    return (id) => this.itemById(id).description;
  }
}

そしてそれを私たちのテンプレートで使用します:

<div v-for="id in ids" :key="id">{{descriptionById(id)}}</div>

これは、Vueで物事を行う正しい方法であるとは言っていません。

ただし、指定されたIDのアイテムがストアで変更されると、ビューはそのコンテンツをこのアイテムの新しいプロパティで自動的に更新します(バインディングは正常に機能しているようです)。


すごいので、これはvuexを使用せずに私にとってはうまくいきました。これが計算されたプロパティを実行する正当な方法であるかどうかも知りたいです。
yeahdixon

1
これは機能しますが、基本的には計算されたプロパティをメソッドと同じように扱います。つまり、計算されたプロパティのキャッシュの利点を失います。そのため、これを使用する方法よりも実際の利益はありません。「メソッドを介してアクセスされるゲッターは、それらを呼び出すたびに実行され、結果はキャッシュされないことに注意してください。」vuex.vuejs.org/en/getters.htmlを
ジェームズ

@ james.brndwgnしかし、基礎となるデータが変更されたときにメソッドが再実行されないと確信しています。私が本当に探しているのはそれだけです。
Alex

@Alexの場合、ウォッチャーを使用する必要があります。vuejs.org/v2/guide/computed.html#Watchers
James

@ james.brndwgn可能であれば、ウォッチャーよりもむしろ計算されたプロパティを使用したいと思います。私はあなたの発言のみに問題を抱えていました:「それで、これよりも方法を使って実際に利益を上げることはできません。」キャッシングなしでも大きな違いがあるからです。
Alex

4

フィルターは、Vueコンポーネントが提供する機能であり、テンプレートの動的データの任意の部分にフォーマットと変換を適用できます。

コンポーネントのデータなどは変更されませんが、出力にのみ影響します。

名前を印刷するとします。

new Vue({
  el: '#container',
  data() {
    return {
      name: 'Maria',
      lastname: 'Silva'
    }
  },
  filters: {
    prepend: (name, lastname, prefix) => {
      return `${prefix} ${name} ${lastname}`
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="container">
  <p>{{ name, lastname | prepend('Hello') }}!</p>
</div>

フィルターを適用する構文に注意してください。filterName。Unixに慣れている場合、それはUnixパイプ演算子です。これは、操作の出力を入力として次の演算子に渡すために使用されます。

コンポーネントのfiltersプロパティはオブジェクトです。単一のフィルターは、値を受け入れて別の値を返す関数です。

戻り値は、Vue.jsテンプレートに実際に出力される値です。


3

関数を返すことで、ゲッターに引数を渡すこともできます。これは、ストア内の配列を照会する場合に特に役立ちます。

getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

メソッドを介してアクセスされるゲッターは、それらを呼び出すたびに実行され、結果はキャッシュされないことに注意してください。

これはメソッドスタイルアクセスと呼ばれ、Vue.jsのドキュメントに記載されています。


2

パラメーターを渡すことはできますが、それがvue.jsの方法ではないか、実行方法が間違っています。

ただし、そうする必要がある場合もあります。ゲッターとセッターを使用して計算されたプロパティに値を渡す簡単な例を紹介します。

<template>
    <div>
        Your name is {{get_name}} <!-- John Doe at the beginning -->
        <button @click="name = 'Roland'">Change it</button>
    </div>
</template>

そしてスクリプト

export default {
    data: () => ({
        name: 'John Doe'
    }),
    computed:{
        get_name: {
            get () {
                return this.name
            },
            set (new_name) {
                this.name = new_name
            }
        },
    }    
}

ボタンをクリックすると、計算されたプロパティに「Roland」という名前が渡されset()、名前が「John Doe」から「Roland」に変更されます。

以下は、getterとsetterで計算を使用する場合の一般的な使用例です。次のVuexストアがあるとします。

export default new Vuex.Store({
  state: {
    name: 'John Doe'
  },
  getters: {
    get_name: state => state.name
  },
  mutations: {
    set_name: (state, payload) => state.name = payload
  },
})

そして、コンポーネントにv-model入力に追加したいが、vuexストアを使用します。

<template>
    <div>
        <input type="text" v-model="get_name">
        {{get_name}}
    </div>
</template>
<script>
export default {
    computed:{
        get_name: {
            get () {
                return this.$store.getters.get_name
            },
            set (new_name) {
                this.$store.commit('set_name', new_name)
            }
        },
    }    
}
</script>

1

あなたが達成しようとしていることは完全にはわかりませんが、計算の代わりにメソッドを使用すると完全にうまくいくようです!


1
computed: {
  fullName: (app)=> (salut)=> {
      return salut + ' ' + this.firstName + ' ' + this.lastName    
  }
}

使いたい時

<p>{{fullName('your salut')}}</p>

1

計算は、関数を持っていると考えることができます。したがって、valdiationの例として、次のようなことを明確に実行できます。

    methods: {
        validation(attr){
            switch(attr) {
                case 'email':
                    const re = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
                    return re.test(this.form.email);
                case 'password':
                    return this.form.password.length > 4
            }
        },
        ...
    }

次のように使用します:

  <b-form-input
            id="email"
            v-model="form.email"
            type="email"
            :state="validation('email')"
            required
            placeholder="Enter email"
    ></b-form-input>

計算されたものに固有のキャッシングを見逃すことを覚えておいてください。


0

はい、paramsを使用するためのメソッドがあります。上記の回答のように、例では実行が非常に軽いため、メソッドを使用するのが最適です。

参考までに、メソッドが複雑でコストが高い状況では、次のように結果をキャッシュできます。

data() {
    return {
        fullNameCache:{}
    };
}

methods: {
    fullName(salut) {
        if (!this.fullNameCache[salut]) {
            this.fullNameCache[salut] = salut + ' ' + this.firstName + ' ' + this.lastName;
        }
        return this.fullNameCache[salut];
    }
}

注:これを使用する場合、数千を処理する場合はメモリに注意してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.