首先来看一下vue官方给出的文档描述
一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个 property。
类型: { 【key: string】: string | Function | Object | Array }
简单来说 watch可以监听一个数据的改变,并且改变后让vue做点什么
1.最基础的用法:
有一个vue的组件,data里面有个name=张三,有个按钮绑定了changeName方法让name发生改变
data() {
return {
name: "张三"
}
},
methods: {
changeName() {
this.name = "李四"
}
}
然后来监听name这个数据//代码效果参考:http://www.lyjsj.net.cn/wx/art_22758.html
,watch: {
name(newVal, oldVal) {
console.log(我改名了,我之前叫${oldVal},现在叫${newVal}
)
}
}
当我们点击这个按钮的时候,会发现控制台输出了"我改名了,我之前叫张三,现在叫李四"
可以发现监听对象触发的函数有两个形参,第一个形参是改变后的数据,而第二个形参是改变前的数据
这个时候我们把数据改造一下,实际工作中我们可能用到的数据是很复杂的.例如嵌套了好几层
data() {
return {
info: {
name: "张三"
}
}
},
methods: {
changeName() {
this.info.name= "李四"
}
},
watch: {
info(newVal, oldVal){
console.log("我发生了改变")
}
}
这个时候发现,控制台上并没有任何的打印.这个是因为一般的监听是监听不到该数据下属性值的变化的.
于是vue也给我们提供了深度监听的方法.
2.进阶用法
深度监听只用添加一个属性: deep = true即可
watch: {
info: {
handler(newVal, oldVal) {
console.log("我发生了改变", newVal, oldVal)
}
deep: true
}
}
加入了新属性之后,监听的数据对应的值不再是一个函数了,而是一个对象,原先的函数对应的是对象下面的handler的属性值,监听数组的话遵循vue的监听数组方法,这里不做多余的介绍
以上可知,watch能监听到数据的改变,并且触发对应的函数,那如果现在有一个新的需求, 就是我在组件初始化的时候就需要知道这个人的姓名怎么办的?
有人会说,那可以在created函数里面打印就可以了,但是这么做的话会造成代码的重复,如果是相同的功能的话就没有必要再去写一份重复的代码,vue也给我们提供了一个属性,那就是immediate,跟deep的用法一样,也是直接添加属性和属性值即可
watch: {
info: {
handler(newVal, oldVal) {
console.log("我发生了改变", newVal, oldVal)
}
deep: true,
immediate: true
}
}
这样的话当你的组件初始化的时候,其实是监听器第一次绑定监听数据的时候,handler的这个函数就可以直接触发了,不需要借用created函数了,而且触发的时机是在created函数之前的.
3.注意事项
1.监听所触发的函数不能用箭头函数,使用箭头函//代码效果参考:http://www.lyjsj.net.cn/wz/art_22756.html
数的时候,this指向的就不是当前的vue实例了4.拓展
1.与computed之间的区别
我们知道vue实例下还提供了一个computed的对象,学名计算属性.也是可以通过数据的改变来进行某些操作.下面就简单来总结一下他们之间的区别,有时面试的时候也会问到
(1) 功能方面,两者都可以通过数据的改变来进行某些操作.但是watch只能对某一个数据进行监听,而computed的只要函数内部涉及到的变量发生改变,就都会重新进行计算.当然有利也有弊,当需要在数据变化时执行异步或开销较大的操作时,watch方式是最有用的。简单来说就是涉及异步操作然后需要设定不同中间值等,这时候就使用watch。
(2) 性能方面,由于computed计算有缓存.所以watch性能方面是差于computed的.不过依照上一点.watch适用于执行异步或开销较大的操作