一、Vue的响应式数据原理
Vue.js是一款构建用户界面的渐进式框架,Vue.js采用MVVM模式(Model-View-ViewModel),核心是实现了数据双向绑定。
Vue中是如何实现数据绑定的呢?当Vue实例中的数据发生改变时,Vue会自动触发某些操作来更新页面上的数据,这其中的核心原理是Vue利用了ES6中的Object.defineProperty()方法来实现数据观测(数据代理),从而实现了双向数据绑定。
在Vue中,每个Vue实例都会对应一个单独的Watcher实例,用于监听数据的变化;而每个Watcher实例都会对应一个单独的Dep实例,用于存储Watcher实例,同时当数据发生改变时会通知所有存储在Dep实例中的Watcher实例。以下是Vue的响应式数据原理的示意图:
// 示例代码
var data = {price: 100, quantity: 2}
function defineReactive(obj, key, val) {
var dep = new Dep()
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function() {
if (Dep.target) {
dep.addSub(Dep.target)
}
return val
},
set: function(newVal) {
if (val === newVal) {
return
}
val = newVal
dep.notify()
}
})
}
function observe(data) {
if (!data || typeof data !== 'object') {
return
}
Object.keys(data).forEach((key) => {
defineReactive(data, key, data[key])
})
}
class Dep {
constructor() {
this.subs = []
}
addSub(sub) {
this.subs.push(sub)
}
notify() {
this.subs.forEach((sub) => {
sub.update()
})
}
}
class Watcher {
constructor(vm, exp, cb) {
this.vm = vm
this.exp = exp
this.cb = cb
Dep.target = this
this.value = this.get()
Dep.target = null
}
get() {
var value = this.vm
this.exp.split('.').forEach((key) => {
value = value[key]
})
return value
}
update() {
this.cb.call(this.vm, this.get())
}
}
var vm = observe(data)
new Watcher(vm, 'price', function() {
console.log('price变化了')
})
data.price = 200 // price变化了
二、Vue的动态数据绑定
动态绑定是Vue中的重要功能之一,通过它,我们可以在页面上动态地改变数据,而不需要刷新整个页面。在Vue中使用动态数据绑定非常简单,只需要在数据引用的位置加上双花括号{{}}就可以了。
// 示例代码
{{message}}
var vm = new Vue({
el: '#app',
data: {
message: 'Hello, world!'
}
})
上述代码中,我们将Vue实例中的message数据,绑定到了页面上的{{message}}中。当我们修改message的值时,页面中{{message}}的内容也会相应地更新,这就是Vue实现数据动态绑定的效果。
三、Vue的响应式数据绑定应用场景
Vue的响应式数据绑定可以应用于多种场景中,下面我们来介绍其中的两种常见场景。
1、表单验证
// 示例代码
var vm = new Vue({
el: '#app',
data: {
name: '',
email: '',
},
computed: {
isValid: function() {
return this.name.trim() !== '' && this.email.trim() !== ''
}
}
})
在上述代码中,我们用到了Vue的计算属性computed,来实现表单验证功能。当我们在输入框中输入内容时,计算属性会根据输入框中的值来计算是否禁用提交按钮,如果输入框中的值为空,那么提交按钮就会被禁用。
2、动态样式
// 示例代码
var vm = new Vue({
el: '#app',
data: {
isActive: true
}
})
在上述代码中,我们用到了Vue的动态绑定class属性的功能。当isActive的值为true时,div标签会自动添加active类,从而实现样式的动态切换。