1. Vue.watch函数的用处
Vue.watch函数是Vue.js提供的一个API函数,用于监听Vue实例中的数据变化,当数据发生变化时,会自动调用指定的回调函数。在Vue.js的开发过程中,数据是一个非常重要的部分,而Vue.watch函数可以帮助我们实现对数据的监听,从而保证组件的数据和状态的及时更新。
1.1 Vue.watch函数的基本用法
Vue.watch函数的基本用法如下:
var vm = new Vue({
data: {
message: 'Hello Vue.js'
},
watch: {
message: function (newValue, oldValue) {
console.log('message changed from ' + oldValue + ' to ' + newValue)
}
}
})
上面的代码中,我们在Vue实例中定义了一个data属性message,然后在watch属性中添加了一个message监听器,当message属性的值发生变化时,Vue.js将自动调用指定的回调函数。在回调函数中,我们可以获取到新值和旧值,并对数据进行处理。
1.2 Vue.watch函数的高级用法
除了基本用法以外,Vue.watch函数还有一些高级用法。
1.2.1 深度监听
默认情况下,Vue.watch函数只能监听数据的第一层属性变化,也就是说,如果数据是一个对象或数组,那么当对象或数组中的属性或元素发生变化时,Vue.watch函数不会自动调用回调函数。如果想要深度监听,需要在Vue.watch函数中添加deep属性,如下所示:
var vm = new Vue({
data: {
user: {
name: 'Tom',
age: 18
}
},
watch: {
user: {
handler: function (newValue, oldValue) {
console.log('user changed from', oldValue, 'to', newValue)
},
deep: true
}
}
})
上面的代码中,我们在Vue实例中定义了一个data属性user,然后在watch属性中添加了一个user监听器,并设置了deep属性为true。这样,当user属性中的任何属性发生变化时,Vue.js将自动调用指定的回调函数。
1.2.2 立即监听
有时候,我们希望在watch属性添加监听器时,立即调用一次回调函数,可以在Vue.watch函数中添加immediate属性,如下所示:
var vm = new Vue({
data: {
message: 'Hello Vue.js'
},
watch: {
message: {
handler: function (newValue, oldValue) {
console.log('message changed from', oldValue, 'to', newValue)
},
immediate: true
}
}
})
上面的代码中,我们在Vue实例中定义了一个data属性message,然后在watch属性中添加了一个message监听器,并设置了immediate属性为true。这样,当Vue实例初始化完成后,将立即调用一次回调函数。
1.2.3 监听多个属性
除了监听单个属性以外,Vue.watch函数还可以监听多个属性。多个属性可以用数组来表示,如下所示:
var vm = new Vue({
data: {
name: '',
age: ''
},
watch: {
['name', 'age']: function (newValue, oldValue) {
console.log('name or age changed')
}
}
})
上面的代码中,我们在Vue实例中定义了两个data属性name和age,然后在watch属性中添加了一个监听器,使用数组来表示多个属性。当name或age属性发生变化时,Vue.js将自动调用指定的回调函数。
2. 如何实现数据监听
Vue.js是如何实现数据监听的呢?这其实和JavaScript的语言特性有关。在JavaScript中,对象和数组都是引用类型,也就是说,在内存中保存的是指向对象或数组的指针,而不是对象或数组本身。因此,当我们给对象或数组添加新的属性或元素时,实际上是修改了指针指向的对象或数组,而不是创建了新的对象或数组。
Vue.js利用了这一点,将数据的变化转化为对指针的修改,从而实现了数据监听。具体来说,Vue.js在生成每个Vue实例时,会根据data属性的属性值创建一个Observer对象。Observer对象的作用是将data属性中的所有数据转化为getter和setter方法,并在getter和setter方法中实现数据的监听。当数据发生变化时,Observer对象会触发依赖收集器Dep的notify方法,依赖收集器会遍历所有的监听器(Watcher对象),并调用监听器的callback方法,进而实现数据的更新。
下面的代码是Observer对象的简单实现:
function Observer (data) {
this.data = data
this.walk(data)
}
Observer.prototype = {
walk: function (data) {
var self = this
Object.keys(data).forEach(function (key) {
self.convert(key, data[key])
})
},
convert: function (key, val) {
this.defineReactive(this.data, key, val)
},
defineReactive: function (data, key, val) {
var dep = new Dep()
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function () {
if (Dep.target) {
dep.depend()
}
return val
},
set: function (newVal) {
if (newVal === val) {
return
}
val = newVal
dep.notify()
}
})
}
}
上面的代码中,我们定义了一个Observer对象,它接受一个参数data,并将data中的所有属性转化为getter和setter方法。在getter方法中,我们添加了一个依赖收集的过程,调用Dep.target的depend方法,将当前Watcher对象加入依赖收集器Dep中。在setter方法中,我们发送通知给依赖收集器,触发依赖收集器中所有监听器的更新操作。
3. 小结
Vue.watch函数是Vue.js提供的一个API函数,用于监听Vue实例中的数据变化,当数据发生变化时,会自动调用指定的回调函数。Vue.js利用数据的引用类型特性,通过Observer对象将数据转化为getter和setter方法,从而实现了数据的监听。