简介
Vue中的响应式是指在Vue中当data中的数据改变后,如果视图上有用到该数据,那么视图也会“自动”更新。代码如下:
<div id="app">{{ message }}</div>
const vm = new Vue({
el: '#app',
data: {
message: 'hi'
}
})
这里 id为app的div中会显示 hi
vm.message = 'hello'
当message改变了之后 div 中的内容也会更新为hello。
如何实现?
实际上,是vue通过对传入data的代理和监听来实现数据响应式的。如下:
const myData = { message: 'hi' }
function proxy({ data }) {
// 监听data中的message
// 实际上vue监听了data中所有的属性,此处只用message属性作为展示
const obj = {}
Object.defineProperty(obj, 'message', {
get() {
return data.message
},
set(newValue) {
data.message = newValue
console.log('通知更新视图')
}
})
return obj
}
const newData = proxy({ data: myData })
newData.message = 'hello' // 通知更新视图
上面代码监听了代理对象obj。
这也就是为什么Vue 无法检测 property 的添加或移除的原因, 因为在new Vue({data})时给data做了监听和代理,而新增的属性没有做,所以新增的属性没有响应式的原因,通过提供的API
Vue.set(vm.someObject, 'b', 2)
会自动创建代理和监听。
数组也是如此,不过Vue侦听了数组的变更的一些方法,听过这些方法也可以实现响应式。详见列表渲染
如下图为Vue实现响应式的流程,核心机制是观察者模式。(图片来自官方)
v-model
所谓的双向绑定,在Vue中指的是v-model,实际上是 v-bind:value 和 v-on:input的语法糖。本质是发布订阅模式。