记录我的Vue.js从会用到精通之路 5

205 阅读2分钟

计算属性的奥妙

让我们来看一小行代码

<div class="juejin">
    {{ number1 + number2}}
</div>

我们立马就可以表达式的目的是求两数和 但如果是这样呢?

<div class="juejin>
    {{ message.split('').reverse().join('') }} 
</div>

这次是不是就得琢磨一下了,最后我们知道是要翻转字符串。

但是这是我们的View层呀,过多的逻辑不应该出现在这里,应该使用计算属性

计算属性computed是如何实现的呢?

computed:{
    myMessage (){
        return this.message.split('').reverse().join('');
    }
}

我们在这里声明了一个计算属性:myMessage。而我们提供的函数,将作为vm.myMessage的getter函数。巧妙的是,随着vm.message的更改,vm.myMessage的值也会变,我们用声明的方式创建了这种依赖关系。

计算属性的setter

通过上面我们知道了计算属性computed的实现实际上是重写了属性对应的getter方法,那我们不禁想问setter也可以重写吗? 可以

const vm = new Vue({
    // ...
    computed : {
        myMessage : {
            get(){
                return this.message + 'juejin';
            },
            set(){
                // ...
            }
        }
    }
})

值得注意的是,如果我们没有给计算属性声明一个set方法,那么vm.myMessage会直接报错:

[Vue warn]: Computed property "myMessage" was assigned to but it has no setter.

计算属性与方法该如何取舍?

或许有的同志要问了:我用方法也可以达到同样的效果,他俩有什么不同吗?

不同点就在于: 计算属性是基于他们的响应式依赖进行缓存的,只有在相关的响应式依赖发生改变的时候,他们才会重新求值,以上述为例,如果vm.message的值没有发生改变,那么多次访问vm.myMessage的话,返回的是之前的计算结果,因为它的依赖vm.message没有发生改变。

举个栗子

computed:{
    nowTime : function(){
        return Date.now();
    }
}

多次访问vm.nowTime但是得到的都是一个值,不会实时返回,这是因为Date.now()不是响应式依赖。但是由于缓存的存在,我们可以避免重复的进行多次大量数据的计算。

如果我们不用computed而用methods,那么每次触发重新渲染,都会再次执行函数。如果你不希望有缓存这个玩意儿,用methods代替computed。

大家都知道watch这个API,他也可以实现computed的功能,那他俩有什么区别呢?下一篇文章再论