注意事项:
1.计算属性的结果,不用挂载在data下面进行数据的初始化,在vue模板中可以直接使用。
2.简单的逻辑可以放在模板中处理,太多的逻辑会让模板过重且难以维护,也不直观。
3.对于复杂逻辑,可以使用计算属性和methods方法。(计算属性的 getter 函数是没有副作用,计算属性在计算数量量比较大,具有缓存计算结果的作用,性能更高;使用methods频繁调用方法,解析模板,渲染页面,是比较消耗性能的)。
4.计算属性是基于它们的响应式依赖进行缓存的,只在相关响应式依赖发生改变时它们才会重新求值,相比于methods普通方法的调用,每当触发重新渲染时,调用方法执行函数,会解析vue模板。
5.被
vue
管理的函数,最好写成普通函数,这样this
的指向才是vm
或组件实例对象。6.所有不被
vue
所管理的函数(定时器的回调函数,ajax
的回调函数等Promise
的回调函数)最好写成箭头函数,这样this
的指向才是vm或组件实例对象。总结:
在vue中实现同一个功能,对于简单的逻辑功能,可以使用模板,其次是methods方法(但不具备数据缓存的能力),若逻辑很复杂,需要缓存数据,则使用计算属性,computed能做的,watch属性也能做,但反过来,却不行,因为watch属性可以执行异步任务。
分别介绍如下:
模板:在
vue
模板中,插值表达式中可以做简单的逻辑判断。使用表达式处理简单的逻辑,非常便利,但是它只适合于简单的运算
<div class="box">
A: <input type="number" v-model:value="A" />
<span>+</span>
B: <input type="number" v-model:value="B" />
<button>=</button>
<span>{{ parseInt(A)+parseInt(B) }}</span><br />
<div>
结果: {{A}} +{{B}} = {{parseInt(A)+parseInt(B)}}
methods:每当触发方法,都会引起页面重新渲染,执行方法函数,它是没有缓存的。如果有一个性能开销比较大的计算属性,它需要遍历一个很大的数组,并做大量的计算,而这个计算属性又有其他依赖,如果没有缓存,不用计算属性,那么就会不断的执行收集属性的
getter。
如果不希望有缓存,就用方法。
methods: {
addResult() {
return parseInt(this.A)+parseInt(this.B);
}
}
computed:
在vue
实例配置选项中,添加computed
属性,值是一个对象,并且添加与之相对应的计算属性,计算属性得到的值是之前缓存的计算结果,不会多次执行。
computed: {
addResult: { // 原始书写的方式
get() {
return parseInt(this.A)+parseInt(this.B)
};
set() {
Do something
};
}
}
如果计算属性只读取(get
),而不去修改set
,确定了只读不改,可以使用简写形式。
computed:{
addResult() {
return parseInt(this.A)+parseInt(this.B)
},
}
watch监听:
通过
vm
对象的$watch()
或watch
配置来监视指定的属性;当属性变化时,回调函数自动调用,在函数内部进行计算;
支持异步任务维持数据;
watch: {
A: {
immediate: true, // 初始化时让handler调用一下,默认是false
handler(newVal,oldVal) {
console.log("A数据改变了","最新的:",newVal,"旧的:",oldVal);
this.addResult = parseInt(newVal)+parseInt(this.B)
const result = parseInt(this.addResult);
}
},
B: {
immediate: true,
handler(newVal, oldVal) {
console.log("B数据变了","最新的",newVal,"旧的",oldVal);
this.addResult = parseInt(this.A)+parseInt(newVal);
const result = parseInt(this.addResult);
}
}
}
如果写成简写的方式,那么就无法写配置选项
watch: {
// 等价于如下
A(newVal) { // 这里的newVal指的是当前监视属性,最新的值,也可以写成(newVal,oldVal)
this.addResult = parseInt(newVal)+parseInt(this.B)
const result = parseInt(this.addResult);
}
B(newVal) {
console.log("B数据变了","最新的",newVal,"旧的");
this.addResult = parseInt(this.A)+parseInt(newVal);
const result = parseInt(this.addResult);
}
}
Vue
提供了$watch
实例方法,也可以这么写:
// 等价于如下方式
vm.$watch('A',{
immediate: true, // 初始化时让handler调用一下,默认是false,不写则第一次不会调用handler函数
handler(newVal,oldVal) {
console.log("A数据改变了","最新的:",newVal,"旧的:",oldVal);
this.addResult = parseInt(newVal)+parseInt(this.B)
const result = parseInt(this.addResult);
}
}
// 等价于如下所示,监视B属性
vm.$watch('B', {
immediate: true,
handler(newVal, oldVal) {
console.log("B数据变了","最新的",newVal,"旧的",oldVal);
this.addResult = parseInt(this.A)+parseInt(newVal);
const result = parseInt(this.addResult);
}
}
关于watch与$.watch写的时机:
1.如果很明确你要监视哪个数据,在创建实例时,就写watch;
2.如果在创建实例的时候,你不知道要监视哪个数据,后续会根据用户的一些行为,监测哪些数据,那么就可以使用$watch这个API;
3.当被监视的属性变化时,回调函数自动调用,进行相关操作;
4.监视的属性必须存在,才能进行监视;
5.监视数据有两种方式一种实例化Vue对象时,传入watch配置选项,另一种是vm.$watch;
watch中的深度监视:
上面都是直接的监听data
下面直接挂载的属性,当我们想要监听某个对象下的单个属性时:
// 监听多级结构中某个属性的变化
watch: {
'info.name': {
console.log("info下面的name属性改变了");
}
}
在Vue
中,默认不监测对象内部值的改变,如果想要监测对象下的每个属性的变化(也就是监测多层级结构),可以设置开启deep: true
配置,如下所示:
// 监听多级结构中某个属性的变化
watch: {
info: {
immediate: true, // 初始化时,立即调用handler函数
deep: true, // 开启深度监测,监测多层级结构
handler() {
console.log("name和age都改变触发了");
}
}
}
// 等价于下面这种写法
vm.$watch('info',{
immediate: true, // 初始化时,立即调用handler函数
deep: true, // 开启深度监测
handler() {
console.log("name和age都改变触发了");
}
})
computed
和watch
之间的区别:
computed
能完成的功能,watch
都可以完成
watch
能完成的功能,computed
不一定能完成,例如:watch
可以进行开启异步任务