vue 计算属性怎么传参

计算属性怎么传参?

<ul>
    <li v-for="item in goods" :style="goodsType" v-text="item.name"></li>
</ul>

data: {
    goods: [{
        id: 2,
        type: 3,
        name: '薯片'
      },{
        id: 3,
        type: 5,
        name: '冰红茶'    
    }]
},
computed: {
    goodsType: function(type){
        switch (type) {
            case 3:
                return "color: #ff9900"
                break;
            case 5:
                return "color: #00BC0C"
                break;
        }
    }
}
阅读 50.4k
8 个回答

传不了参的,你可以写成methods

谁说传不了参的,闭包忘了?

:data="closure(item, itemName, blablaParams)"

computed: {
 closure () {
   return function (a, b, c) {
        /** do something */
        return data
    }
 }
}

亲测有效

btw: 所有说传不了的,我都给了 踩

能不能传参取决于你的计算属性值是什么,如果这个计算属性值不是Function,那么自然不能传参,只有当计算属性值是Function的时候才能够传参,不然你会得到一个xxx is not a function 的错误。

如果这个函数的逻辑不依赖于任何的该实例的data里面的属性,那么它是完全没问题的,但是这样子的话就跟普通的methods没有任何区别了。还不如直接使用methods更清晰简单。

但是如果这个计算属性的函数依赖于实例data中的内容,那么很可能就不会如我们期望的那样。
看下面的例子

data(){
    return {
        firstName: ''
    }
},
computed: {
    fullName(){
        return lastName => this.firstName + secondName
    }
}

// 使用
<span>{{ fullName('lee') }}</span>

我们希望this.firstName 变化的时候,fullName也能够做出响应变化(这是计算属性最基本的功能要求呀),
但事实却并不是这样。

为什么?因为在fullName这个计算属性收集依赖的时候,根本就无法感知闭包函数里面的firstName,也就没有收集到firstName的依赖,自然也就不会响应firstName的变化。那么这个计算属性就完全不如我们预期的那样工作。

如何跟我们预期的一样?
很简单,我们只需要在vue第一次收集计算fullName的时候,明确让其收集firstName的依赖即可。

data(){
    return {
        firstName: ''
    }
},
computed: {
    fullName(){
        this.firstName // 这句话什么都不做,但是是必须的,作用是让vue收集到firstName的依赖。
        return lastName => this.firstName + secondName
    }
}

// 使用
<span>{{ fullName('lee') }}</span>

当我们加了这个看起来啥都没用 的 this.firstName 的时候,此时fullName才会随着firstName的响应式而跟着重新计算。

所以在题主的这个例子中根本就没有必要使用传参的计算属性,methods才是最直观最不会出错的做法。

没必要传参,不管用闭包还是什么魔法,都会影响到你对 Vue 数据响应的理解。

把你想传的参数变成 Vue 实例数据,以及考虑如何在需要传参的地方改变这些数据,才能够推动你按照 Vue 的思维方式去思考。

这个需求用一个对象实例数据不就可以解决了吗?

colors: {
  3: '#ff9900',
  5: '#00BC0C'
}

绑定 style 为 {color: colors[item.type]}

https://cn.vuejs.org/v2/guide...计算-setter

计算属性默认只有 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]
    }
  }
}
// ...

首先,计算属性里的方法是传不了参的,根据你的代码我想你想要实现的是根据type的改变去返回颜色,那么你应该明白的是计算属性返回的值只跟它里面的依赖有关,当依赖改变的时候就会触发计算属性去重新计算然后改变值,所以你应该让type变成该vm的一个数据,进而成为该计算属性的依赖。简单代码如下:

data: {
    goods: [],
    type: 0  //这个type作为你后面计算属性的依赖项,通过其他方法改变它的值即可。
},
computed: {
    goodsType: function(){
        //这里将会依赖于此vm的type值,当type值改变,就会重新计算
        switch (this.type) {
            case 3:
                return "color: #ff9900"
                break;
            case 5:
                return "color: #00BC0C"
                break;
        }
    }
}

computed的源码实现依旧是做依赖收集后的data值,它只是被提供了一个默认的getter值,所以无法为它传递参数。

但是依旧可以使用闭包,此时data依赖依然有效。因为computed的每一个key都是被包装为一个watcher的,对它的响应更新粒度在computed层面。

或者提供setter,在setter去改vuex或者全局变量的值曲线救国。

新手上路,请多包涵
 <el-table-column prop="pics"
                             label="图片"
                             width="150"
                             align="center">
              <template slot-scope="scope">
                <el-image style="width: 60px; height: 60px"
                          :src="imageUrl + scope.row.pics[0]"
                          :preview-src-list="formatImgList(scope.row)">
                </el-image>
              </template>
            </el-table-column>
formatImgList() {
      return function(row) {
        let array = [];
        row.pics.forEach(element => {
          array.push(this.imageUrl + element);
        });
        return array;
      };
    }

3Q[8LQRT2%B0SJT3NKMYDQ6.png
使用elementUI组件,el-image组件中preview-src-list属性接收的是一个数组,而我需要对数据进行处理,为每个图片数据加上服务器路径,此时使用闭包就解决了问题,

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏