1.computed:计算属性
- Vue的进阶属性
- 计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。
- 也就是说某个依赖 (比如非响应式属性) 在该vm实例范畴之外,则计算属性是不会被更新的。
- 所以我们不希望使用依赖缓存的时候可以使用基本属性methods代替之。
- 注意如果你为一个计算属性使用了箭头函数,则 this 不会指向这个vm组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问。
用法
官方
{ [key: string]: Function | { get: Function, set: Function } }
var vm = new Vue({
data: { a: 1 },
computed: {
// 仅读取
aDouble: function () {
return this.a * 2
},
// 读取和设置
aPlus: {
get: function () {
return this.a + 1
},
set: function (v) {
this.a = v - 1
}
}
}
})
vm.aPlus // => 2
vm.aPlus = 3
vm.a // => 2
vm.aDouble // => 4
- aDouble 值是个函数,可以直接通过key值调用函数
- aPlus 值是个对象且有get和set属性
2.watch:监听属性
- Vue的进阶属性
- Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动。
- 数据变化,执行一个异步的函数(且非箭头函数)。
- 有immediate和deep属性。
- 而且不应该使用箭头函数来定义watch函数,因为箭头函数绑定了父级作用域的上下文,所以this不会按照期望指向vue实例,此时的this将会是undefined。
用法
{ [key: string]: string | Function | Object | Array }
官方实列
var vm = new Vue({
data: {
a: 1,
b: 2,
c: 3,
d: 4,
e: {
f: {
g: 5
}
}
},
watch: {
a: function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
},
// 等价写法
b(val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
},
// 方法名
b: 'someMethod',
// 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
c: {
handler: function (val, oldVal) { /* ... */ },
deep: true
},
// 该回调将会在侦听开始之后被立即调用
d: {
handler: 'someMethod',
immediate: true
},
e: [
'handle1',
function handle2 (val, oldVal) { /* ... */ },
{
handler: function handle3 (val, oldVal) { /* ... */ },
/* ... */
}
],
// watch vm.e.f's value: {g: 5}
'e.f': function (val, oldVal) { /* ... */ }
}
})
vm.a = 2 // => new: 2, old:
import Vue from "vue";
new Vue({
data: {n: 0,},
watch: {
n() {console.log(`n发生变化时会执行我`);}
},
methods: {
add() {this.n += 1;}
},
template: `
<div>
{{n}}
<button @click=add>点我+1</button>
</div>
`
}).$mount("#app");
每次n发生变化时,就会出发watch的n方法
3.computed vs watch
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用watch。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。细想一下这个例子:
<div id="demo">{{ fullName }}</div>
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
'data.firstName': function (val) {
this.fullName = val + ' ' + this.lastName
},
'data.lastName'() {
this.fullName = this.firstName + ' ' + val
}
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
}
})
computed是不是比watch简洁!!!! watch
- 第一次刷新的时候的时候页面显示为空,因为firstName和lastName只是从无到有,称不上为变化。
- 怎么样使第一次也运行结果呢
watch:{
'data.firstName':{
handler(){
this.fullName = val + ' ' + this.lastName
},
immediate:true //第一次也运行一下结果
},
'data.lastName'() {
handler(){
this.fullName = this.firstName + ' ' + val
},
immediate:true //第一次也运行一下结果
}
- 什么又是watch的deep属性呢
- 此处的意思是比如我监听data的时候,是否忘深了看, 比如data.fullName变化的时候,data是否也变了呢
- 这根据你的需求来,认为data也变了那么,deep:ture
- 反之认为data没变那么,deep:false 就是不往内部看
总结
- 如果一个数据依赖于其他数据,那么把这个数据设计为computed的
- 如果你需要在某个数据变化的时候做一些事情,使用watch来观察这个数据变化
- 当你有一些数据需要随着其它数据变动而变动时,通常更好的做法是使用计算属性而不是命令式的 watch回调。