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;
        }
    }
}
阅读 20k
评论
    8 个回答
    • 314

    传不了参的,你可以写成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才是最直观最不会出错的做法。

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

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

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

            • 9k

            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;
                      }
                  }
              }
                • 58

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

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

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

                  • 1
                  • 新人请关照
                   <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属性接收的是一个数组,而我需要对数据进行处理,为每个图片数据加上服务器路径,此时使用闭包就解决了问题,

                    撰写回答

                    登录后参与交流、获取后续更新提醒

                    相似问题
                    推荐文章