web-dev-qa-db-ja.com

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

vue.Jsの計算プロパティにパラメータを渡すことができるかどうかgetter/setterを使って計算すると、パラメータを取り、それを変数に割り当てることができます。こちらは のドキュメント のように:

// ...
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捕捉されないTypeError:fullNameは関数ではありません(…)

そのような場合にはメソッドを使うべきですか?

119
Saurabh

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

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

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

より長い説明

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

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

(これに対するベースコードをありがとうUnirgy。)

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

パラメータが必要な場合は、このような場合にメソッドに対して計算プロパティ関数を使用する利点は通常ありません。それはあなたがVueインスタンスに束縛されたパラメータ化されたgetter関数を持つことを可能にするけれども、あなたはそこに実際に少しの利益もないので実際には、あなたは反応性を壊すかもしれません(AFAIU)。これについての詳細はVueのドキュメント https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods にあります。

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

155
damienix

メソッドを使用することはできますが、データを変更していない場合や外部効果がない場合は、メソッドの代わりに計算プロパティを使用することをお勧めします。

このようにして計算プロパティに引数を渡すことができます(文書化されていませんが、メンテナから提案されています。場所は覚えていないでください)。

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

編集:この解決策を使用しないでください、それは何の利点もなくコードを複雑にするだけです。

22
Unirgy

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

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

{
  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を持つアイテムがストア内で変更されると、ビューはこのアイテムの新しいプロパティを使用してその内容を自動的に更新します(バインディングは問題なく機能しているようです)。

7

あなたはパラメータを渡すことができますが、それはvue.jsのやり方ではないか、あなたがしているやり方は間違っています。

しかし、そうする必要がある場合もあります。getterおよびsetterを使用して計算プロパティに値を渡す簡単な例を示します。

<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'に名前を変更します。

以下は、computeが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>
2
roli roli
computed: {
  fullName: (app)=> (salut)=> {
      return salut + ' ' + this.firstName + ' ' + this.lastName    
  }
}

使いたいとき

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

はい、paramsを使う方法はあります。上記の回答と同様に、あなたの例では実行が非常に軽いのでメソッドを使うのが最善です。

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

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

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

注意:これを使うとき、数千を扱うならメモリに気をつけて

0
Isometriq

フィルタは、テンプレートの動的データの任意の部分にフォーマットや変換を適用できるようにする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テンプレートに実際に印刷されているものです。

0
Diego Pereira

関数を返すことで引数をゲッターに渡すこともできます。これは、ストア内の配列をクエリしたいときに特に便利です。

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

メソッドを介してアクセスされるゲッターは、それらを呼び出すたびに実行され、結果はキャッシュされません。

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

0
vnbrs