我们首先在官网看下对技术属性computed的介绍:
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。
{{ message.split('').reverse().join('') }}在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量
message
的翻转字符串。当你想要在模板中的多处包含此翻转字符串时,就会更加难以处理。所以,对于任何复杂逻辑,你都应当使用计算属性。
你可以像绑定普通 property 一样在模板中绑定计算属性。Vue 知道
vm.reversedMessage
依赖于vm.message
,因此当vm.message
发生改变时,所有依赖vm.reversedMessage
的绑定也会更新。
computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;
计算属性由两部分组成:get和set,分别用来获取计算属性和设置计算属性。默认只有get,如果需要set,要自己添加。另外set设置属性,并不是直接修改计算属性,而是修改它的依赖。
一个例子
-
firstName: {{ firstName }}
-
lastName: {{ lastName }}
-
fullName: {{ fullName }}
现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。
另一个例子
可以像绑定普通属性一样在模板中绑定计算属性,在定义上有区别:计算属性的属性值必须是一个函数。
data() { // 普通属性
return {
msg: ''
};
},
computed: { // 计算属性
reverseMsg: function () { // 该函数必须有返回值,用来获取属性,称为get函数
// 可以包含逻辑处理操作,同时reverseMsg依赖于msg,一旦msg发生变化,reverseMsg也会跟着变化
return this.msg.split(' ').reverse().join(' ');
}
},
计算属性缓存是定义在计算属性 computed
里的,调用 methods
里的方法也可以与计算属性起到同样的作用。
Reversed message: "{{ reversedMessage() }}"
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
两者最主要的区别:computed 是可以缓存的,methods 不能缓存;
:data="closure(item, itemName, blablaParams)"
computed: {
closure() {
return function (a, b, c) {
/** do something */
return data;
};
}
},
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性watch。watch中可以执行任何逻辑,如函数节流,Ajax异步获取数据,甚至操作 DOM(不建议)。
常规用法
watch属性
{{ $data }}
两者之间的对比
从上面流程图中,我们可以看出它们之间的区别:
除此之外,有点很重要的区别是:计算属性不能执行异步任务,计算属性必须同步执行。也就是说计算属性不能向服务器请求或者执行异步任务。如果遇到异步任务,就交给侦听属性。watch也可以检测computed属性。
注意,不应该使用箭头函数来定义计算属性函数 (例如 aDouble: () => this.a * 2
)。理由是箭头函数绑定了父级作用域的上下文,所以 this
将不会按照期望指向 Vue
实例,this.a
将是 undefined
。当然有很多this需要指向vue实例的时候,都需要慎用箭头函数。
计算属性适合用在模板渲染中,某个值是依赖了其它的响应式对象甚至是计算属性计算而来;而侦听属性适用于观测某个值的变化去完成一段复杂的业务逻辑。
更进一步了解可参考:https://juejin.cn/post/6844904185217957902