今天在重构项目的时候,发现了一个有关父子组件之间实时通讯的问题。在上个版本中,代码如下:
props: {
// 接收父组件传递过来的信息
chartData: {
type: Object,
default: ()=>[]
}
},
data () {
return {
}
},
watch: {
'chartData.data': function (n, o) {
this.$nextTick (() => {
console.log(n, o)
})
}
}
之前执行起来一点问题都没有(我也郁闷为什么。。。)。但是今天,明明是一样的代码,完全监听不到啊!
开始查文档,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,我传的就是Object,所以无法获取到对象内部的改变。
OK。开始笔记吧。
watch的用法大概有三种。
1、基本用法:(注意:只能watch基础类型的变量)
<div>
<p>fname: <input type="text" v-model="fname"></p>
<p>name: {{name}}</p>
</div>
new Vue({
el: '#root',
data: {
fname: '肖战',
name: ''
},
watch: {
fname (n, o) {
console.log(n, o)
}
}
})
2、handler方法和immediate属性
这种方法的特点是,当值第一次绑定的时候不会执行监听函数,只有值发生改变才会执行。如果我们需要在最开始绑定值的时候也执行函数,就需要用到immediate属性。
比如当父组件向子组件动态传值时,子组件props首次获取到父组件传来的默认值时,也需要执行函数,此刻就需要将immediate设置为true。
props: {
chartData: {
type: Object,
default: () => []
}
},
watch: {
// 对象监听
chartData: {
handler (newValue, oldValue) {
console.log(newValue, oldValue)
},
immediate: true
}
},
监听的数据后面写成对象形式。之前我们写的函数其实就是再写handler这个方法;
immediate表示在watch中首次绑定的时候,是否执行handler,值为true表示在watch中声明的时候,立即执行。值为false就和一般使用watch一样,在数据发生变化的时候才执行。
3、deep属性(深度监听,常用语对象下面属性的改变)
当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。
<input type="text" v-model="chartData.data"/>
data () {
return {
chartData: {
data: '肖战'
}
}
},
watch: {
// 对象监听
chartData: {
handler (newValue, oldValue) {
console.log(newValue, oldValue)
},
deep: true
}
},
设置deep:true,可以监听到chartData.data的变化,此时会给chartData的所有属性都加上这个监听器,当对象属性较多时,每个属性值的变化都会执行handler。如果只需要监听对象中的一个属性值,可以做个优化:使用字符串的形式来监听对象属性:
watch: {
// 对象监听
'chartData.data': {
handler (newValue, oldValue) {
console.log(newValue, oldValue)
},
deep: true
}
},
这样只会给对象的某个特定的属性加监听器。
数组(一维、多维)的变化不需要通过深度监听,对象数组中对象的属性变化则需要deep深度监听。
如果你有更好的方法,可以给我点意见哦。