看到这个标题就知道这篇文章接下来要讲的内容,我们在使用 vue 的时候 methods、watch、computed 这三个特性一定经常使用,因为它们是非常的有用,但是没有彻底的理解它们的区别和各自的使用场景,也很难用好它们,希望接下来的介绍为你答疑解惑。
computed
我们先来看计算属性:computed,光看名字也知道是用来干什么的,计算属性当然是用来计算的,但是是怎么计算的呢?计算属性有两个显著的特点:
计算属性计算时所依赖的属性一定是响应式依赖,否则计算属性不会执行
计算属性是基于依赖进行缓存的,就是说在依赖没有更新的情况,调用计算属性并不会重新计算,可以减少开销
我们来看一个相关的例子:
<div id=”app”>
<div>{{arr.join(”) }}</div>
<div>{{arr1}}</div>
<div>{{getDate}}</div>
<div>{{getDate1}}</div>
</div>
var app = new Vue({
el: ‘#app’,
data: {
date: ”,
arr: [‘a’, ‘b’, ‘c’]
},
computed: {
getDate () {
return Date.now()
},
getDate1 () {
return this.date
},
arr1 () {
return this.arr.join(”)
}
},
created () {
setInterval(() => {
this.date = Date.now()
}, 1000)
}
})
看上面的例子,我们在写 vue 的时候,经常会碰到要对 data 的值进行操作的情况,为了方便,总是会有人直接在模版中对 data 的值进行计算操作,就像我上面例子中写的在模版中将数组转化为字符串,这样写有问题吗?语法没有问题,但是在模版中使用太多的计算,维护会是个问题,换个人来看代码的时候会很痛苦,这种写法就好像在 html 中插入 js 的逻辑运算,可维护性极差。另外一个展示的就是 computed 的响应式依赖的问题,当我们调用 getDate 的时候返回的 Date.now() 返回的是一个非响应式的依赖因此 getDate 返回的值不会变。
应用场景
看了 computed 的特点之后,那么它的应用场景是什么呢?个人看法,但不限于以下场景:
复杂的渲染数据计算,用 computed 计算属性可以减少一定计算开销,增加可维护性
从 Vuex Store 中收集相关信息,对 Vuex 中的数据做计算的时候的要特别注意 computed 的缓存属性,在对 Vuex 中的对象值进行属性修改的时候,并不会触发 computed 的中值的变化,这时需要 Object.assign({},obj) 对依赖对象进行跟新返回一个新对象触发依赖跟新
表单校验,这个应用场景应该是比较常见的,利用正则表达式对每个表单项的实时监控,判断表单是否可以提交
methods
methods 大家应该都会用,是 vue 中的方法属性,所有的方法调用都会写到这里面,大家用的最多也是在累似 @click 这样事件调用中使用,但是很多人都忽视 methods 的另一个用法,就是在模版中使用 methods,下面来看一个例子:
<div id=”app”>
<div v-for=”(item, idx) in arr”>
{{matching(item) }}
</div>
</div>
var app = new Vue({
el: ‘#app’,
data: {
arr: [‘a’, ‘b’, ‘c’],
obj: {a: ‘hello’, b: ‘world’}
},
methods: {
matching (key) {
if (this.obj[key]) {
return this.obj[key]
} else {
return ‘not found’
}
}
}
})
上面的例子就是 methods 在模版中常常使用的一个场景,当模版中的某个循环的值需要进行一定逻辑运算时,这时候你就可以使用 methods 方法,将对应的值传入,然后计算出结果返回到模版显示,这个时候用 computed 是没法实现的,computed 中你无法传参,methods 和 computed 除了这个不一样之外,还有就是在 methods 中的计算是不会做缓存的,也就是你调用多少次就会计算多少次,相对 computed 的开销要大一些。
watch
侦听属性是专门用来观察和响应 vue 实例上的数据变动,能使用 watch 属性的场景基本上都可以使用 computed 属性,而且 computed 属性开销小,性能高,因此能使用 computed 就尽量使用 computed 属性,那么 watch 属性是不是就没用武之地了呢?当执行异步操作的时候你可能就必须用 watch 而不是 computed 了,下面看一个例子:
<div id=”app”>
<div>{{obj1.a}}</div>
</div>
var app = new Vue({
el: ‘#app’,
data: {
obj: {a: ‘hello’},
obj1: {a: ‘hello’},
test: ‘aaa’
},
computed: {
getObj () {
setTimeout(() => {
this.obj.a = this.test + ‘word’
return this.obj
}, 1000)
}
},
watch: {
test () {
setTimeout(() => {
this.obj1.a = this.test + ‘word’
}, 1000)
}
},
mounted () {
this.test = ‘hello’
}
})
上述例子中,当在模版中调用 getObj.a 时,如果没有 setTimeout 这异步操作,直接返回一个值是可以直接在模版中显示的,但是由于加异步操作就会导致没有返回值同时调用对象的属性,就会报错,而调用 obj1.a 却不一样,模版会先显示 hello,然后在触发了 watch 属性时,setTimeout 触发,一秒钟之后模版会显示 helloword,这就 watch 中可以使用异步函数,而 computed 不行的原因
总结
希望看了这篇文章能对你区分 methods、computed、watch 的用法能有所帮助。这篇文章如果有错误或不严谨的地方,欢迎批评指正,如果喜欢,欢迎点赞收藏