watch
在Vue中用来监听数据变化,是一个对象,内部由键和值构成,键是需要监听的data,值是监听的data变化时触发的函数。举个栗子:
<template>
<div>
<div>{{name}}</div>
<button @click="fun">点击我</button>
</div>
</template>
export default {
data(){
return {
name: "小明"
}
},
watch:{
name: {
handler(newVal, oldVal){
//当name发生改变是触发该函数
console.log(newVal,oldValue)
}
}
},
methods: {
fun(){
this.name = "小红";
}
},
}
</script>
这样就可以监听普通类型的data的变化,那么数组和对象如何监听呢?
$set
首先看数组的监听,再举个栗子
<div>
<ul>
<li v-for="(item, i) in arr" :key="i">
{{item}}
</li>
</ul>
<button @click="fun">点击我</button>
</div>
data(){
return {
arr: [1,2,3,4,5],
}
},
watch: {
arr: {
handler(newVal, oldVal){
console.log(oldVal,8888)
console.log(newVal,44444)
}
},
},
methods: {
fun(){
this.arr[2] = 999;
}
},
这个时候会发现,在监听的函数里无法打印arr的newVal和oldVal,说明这个事件是没有触发的,这个时候就需要使用到$set。
methods: {
fun(){
//参数列表
// $set("data", index, value)
this.$set(this.arr,2,999);
}
},
此时点击按钮之后就可以监听到数组的变化。
deep
监听对象的变化,用监听普通对象的方式监听对象,是没有办法触发watch的,需要添加deep属性,深度监听对象,为每一个对象的值都添加一个监听器。
data(){
return {
obj: {
a: "1",
b: "2"
},
}
},
watch:{
obj:{
handler(newval,oldval){
console.log(newval,oldval)
},
deep: true
}
}
这样在对象的值发生改变的时候,就可以监听到数组的变化。也可以只监听对象中某一个key的变化,这样不添加deep属性也可以监听:
watch: {
"obj.a": {
handler(newval,oldval){
console.log(newval,oldval)
},
}
}
watch监听时,key后面除了可以写函数,也可以写在methods中当以的方法名:
watch: {
name: "fun"
},
methods: {
fun(){
//函数体
}
}
除此之外,监听的变量需要再data中定义,实际上提倡所有用到的变量都在data中定义,尽量避免在方法中为Vue添加新的data,一是为了消除依赖项跟踪系统的边界(在我理解看来就是为了更好地监听数据),而是为了提高代码的可维护性。