Vue 数据响应式

846 阅读1分钟

简介

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的语法糖。本质是发布订阅模式。