是否有可能在Vue.Js中传递计算属性中的参数。我可以看到,当有getter /setter使用computed时,他们可以接受一个参数并将其分配给一个变量。比如这里的文档:

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    
  }
}

其中computed属性接受一个参数并返回所需的输出。然而,当我尝试这样做时,我得到这个错误:

vue.common.js:2250 Uncaught TypeError: fullName不是函数(…)

我是否应该在这种情况下使用方法?


当前回答

Computed可以被认为是一个函数。举个关于验证的例子,你可以这样做:

    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>

请记住,您仍然会错过特定于computed的缓存。

其他回答

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

当你需要的时候

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

也可以通过返回函数将参数传递给getter。当你想查询存储中的数组时,这特别有用:

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

注意,通过方法访问的getter将在每次调用时运行,并且结果不会被缓存。

这被称为方法风格访问,它被记录在Vue.js文档中。

我想首先重申前面的警告,使用computed(被缓存的)参数只会使computed不被缓存,实际上只是使它成为一个方法。

然而,话虽如此,这里是我能想到的所有可能有边界情况的变化。如果你将其剪切并粘贴到演示应用中,你就会清楚发生了什么:

<template>
  <div>

    <div style="background: violet;"> someData, regularComputed: {{ someData }}, {{ regularComputed }} </div>
    <div style="background: cornflowerblue;"> someComputedWithParameterOneLine: {{ someComputedWithParameterOneLine('hello') }} </div>
    <div style="background: lightgreen;"> someComputedWithParameterMultiLine: {{ someComputedWithParameterMultiLine('Yo') }} </div>
    <div style="background: yellow"> someComputedUsingGetterSetterWithParameterMultiLine: {{ someComputedUsingGetterSetterWithParameterMultiLine('Tadah!') }} </div>

    <div>
      <div style="background: orangered;"> inputData: {{ inputData }} </div>
      <input v-model="inputData" />
      <button @click="someComputedUsingGetterSetterWithParameterMultiLine = inputData">
        Update 'someComputedUsingGetterSetterWithParameterMultiLine' with 'inputData'.
      </button>
    </div>

    <div style="background: red"> newConcatenatedString: {{ newConcatenatedString }} </div>

  </div>
</template>

<script>

  export default {

    data() {
      return {
        someData: 'yo',
        inputData: '',
        newConcatenatedString: ''
      }
    },

    computed: {

      regularComputed(){
        return 'dude.'
      },

      someComputedWithParameterOneLine(){
        return (theParam) => `The following is the Parameter from *One* Line Arrow Function >>> ${theParam}`
      },

      someComputedWithParameterMultiLine(){
        return (theParam) => {
          return `The following is the Parameter from *Multi* Line Arrow Function >>> ${theParam}`
        }
      },

      // NOTICE that Computed with GETTER/SETTER is now an Object, that has 2 methods, get() and set(), so after the name of the computed we use : instead of ()
      // thus we do: "someComputedUsingGetterSetterWithParameterMultiLine: {...}" NOT "someComputedUsingGetterSetterWithParameterMultiLine(){...}"
      someComputedUsingGetterSetterWithParameterMultiLine: {
        get () {
          return (theParam) => {
            return `As part of the computed GETTER/SETTER, the following is inside get() which receives a Parameter (using a multi-line Arrow Function) >>> ${theParam}`
          }
        },
        set(newSetValue) {
          console.log('Accessing get() from within the set()', this.someComputedUsingGetterSetterWithParameterMultiLine('hello from inside the Setter, using the Getter.'))
          console.log('Accessing newSetValue in set() >>>>', JSON.stringify(newSetValue))
          this.newConcatenatedString = `**(1)${this.someComputedUsingGetterSetterWithParameterMultiLine('hello from inside the Setter, using the Getter.')}**  This is a concatenation of get() value that had a Parameter, with newSetValue **(2)${newSetValue}** that came into the set().`
        }
      },

    },

  }

</script>

您可以使用方法,但我仍然倾向于使用计算属性而不是方法,如果它们不会改变数据或没有外部影响的话。

你可以通过这种方式将参数传递给计算属性(没有文档,但由维护者建议,不记得在哪里):

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

编辑:请不要使用此解决方案,它只会使代码复杂化,没有任何好处。

最可能的情况是使用方法

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

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

更详细的解释

从技术上讲,你可以像这样使用一个带有参数的computed属性:

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

(感谢Unirgy提供的基本代码。)

计算属性和方法之间的区别在于,计算属性是缓存的,仅当它们的依赖关系发生变化时才会更改。方法将在每次调用时求值。

如果需要参数,在这种情况下使用计算属性函数通常比使用方法没有任何好处。尽管它允许您将参数化getter函数绑定到Vue实例,但您将失去缓存,因此实际上没有任何增益,实际上,您可能会破坏反应性(AFAIU)。您可以在Vue文档https://v2.vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods中阅读更多相关内容

唯一有用的情况是当您必须使用getter并需要将其参数化时。例如,这种情况发生在Vuex中。在Vuex中,这是从存储中同步获取参数化结果的唯一方法(操作是异步的)。因此,官方Vuex文档列出了这种方法的getter https://vuex.vuejs.org/guide/getters.html#method-style-access