业务场景
后台管理系统一般为了代码复用,会把新增、修改、编辑的逻辑写到一个vue文件里。此时有个业务场景就是只在修改的时候监听某个字段,处理对应的业务逻辑。在watch里面写判断其实还是会进行监听,只是不处理后面的业务了。为了解决这个问题,下面展开讨论一下。
最初的写法
new Vue({
data: {
type: 'add',
shouldWatch: false,
a: 1
},
watch: {
type:{
// 当 a 的值发生改变时,开始监听 b
handler(val){
this.shouldWatch=val==='edit'?true:false;
},
immediate:true
},
a: function (val) {
// 只有当 shouldWatch 为 true 时,才处理 a 的变化
if (this.shouldWatch) {
// 处理对应的逻辑变化
}
}
}
})
在这个例子中,我们在 type 的 watch
回调函数中设置 shouldWatch
为 true
,这样,只有当 type 的值发生改变时,我们才会开始监听 a 的变化。对于业务逻辑,type对应的是新增、修改、详情对应的标识。
但是对于vue2而言,只要下面写了watch监听,就会进入监听逻辑,就算在watch里面写了if判断,只是不进入后面的监听,但是每次a进行变化的时候,其实还是会进入监听逻辑的。在if判断之前打印一下就能看出来。所以为了解决这个问题,更好的优化,这里采用第二种写法。
最终写法
data(){
return {
watchRoute:()=>{},
type:'add',
a: 1
}
}
//定义监听函数
created(){
if(type==='edit'){//在编辑的时候进行监听
this.watchRoute=this.$watch(
()=>{ return this.a}, //此处被监听的对象必须是一个函数,否则会报错
(newval,oldval)=>{
//do some thing (如果监听的是个对象,则newval和oldval一样,不会发生变化)
},
{immediate:true}
)}
}
destroyed(){
//页面销毁的时候调用监听函数,就可以移除watch
this.watchRoute()
}
这段代码是在 Vue 组件中定义了一个 watchRoute
的属性,并将其初始化为一个空函数。在 created
生命周期钩子中,通过 this.$watch
方法来监听 type的变化,并将监听函数赋值给 watchRoute
。同时,通过设置 immediate: true
,确保在页面加载时立即执行一次监听函数。在 destroyed
生命周期钩子中,调用 this.watchRoute()
来移除监听。
这种写法的作用是在组件创建时开始监听 type的变化,并在组件销毁时移除监听,调用 this.watchRoute()
来移除监听。
这种写法的作用是在组件创建时开始监听 a对象的变化,并在组件销毁时移除监听。通过将监听函数赋值给 watchRoute
,可以在其他地方引用该函数,以便在需要的时候手动调用或取消监听。
需要注意的是,被监听的对象必须是一个函数,而不是一个直接的对象。这是因为 watch
选项中的属性值必须是一个函数,用于返回被监听的对象。在这个例子中,我们使用 ()=>{ return this.a }
来返回 a对象。这样做是为了确保在每次访问 a对象时都能获取到最新的值。这样写的话只有编辑的时候才会对a开启监听,销毁页面的时候将watch移除。
此外,这里在处理业务的时候还遇到一个问题,业务中其实监听是一整个对象,所以此时的newVal和oldVal一样,是不会发生改变的,引用地址相同,所以处理的时候是通过记录之前的值进行一个拷贝记录然后处理的。