Vue的响应式数据与非响应式数据及原理

 一.概念及使用

响应式:

  1. 当Vue组件的实例初始化的时候已有的数据就是响应式数据
  2. 通过Object.defineProperty代理实例this身上的
  3. 响应式属性的值发生改变会触发视图更新

非响应式:

  1. 当Vue组件的实例初始化的时候没有,后期添加的属性
  2. 没有通过Object.defineProperty代理实例this身上的
  3. 非响应式属性的值发生改变不会触发视图更新
  • 非响应式情况

1.直接在vm实例对象上添加属性



2.列表渲染通过下标更改列表中的值

需求:点击按钮更改列表中的第0号元素





这种情况数据其实已经改变了,但是视图没变

Vue的响应式数据与非响应式数据及原理_第1张图片 

解决方法: Vue.set || this.$set

this.arr[0]='a'
改为
this.$set(this.arr,0,'a')


或者import Vue from 'vue'
Vue.set(this.arr,0,'a')

 那么Vue数据响应式是如何实现的呢?

二.响应式底层原理

实现数据的双向绑定有几个重要的部分:

  1. 数据代理
  2. 数据劫持
  3. 模板解析

1.数据代理 =>简化对组件对象中data中属性的操作(读/写)

vm(Vue的实例对象)如果想要访问data的数据需要this._data.xxx,但是如果每个数据都这样访问太麻烦了,而Vue中是可以通过{{xxx}}或者this.xxx的形式直接访问到data中的数据,这里就使用到了数据代理

this.data.xxx => this.xxxx

Vue的响应式数据与非响应式数据及原理_第2张图片

数据代理原理: 

2.数据劫持 => 实现数据双向绑定

M:data

VM:在observer(一个监视函数)中,通过object.defineProperty为data中每个层次的属性重写get,set方法,并且为每个属性创建dep对象

  get:建立dep与watcher的联系

  set:数据发生改变去更新界面

V:在模板解析时,为每个节点创建watcher对象

  • this.msg='abc 
  • 由于数据代理 data.msg变成了'abc'
  • 由于数据劫持  创建dep和watcher的关系 ,通过对应的dep去通知所有的watcher去更新节点

3.模板解析

在实例化Vue时会传入一个配置对象,配置对象中包括el,data....其中el就是将对应节点传入Vue中,Vue底层进行遍历所有节点,应为节点内还会有子节点,这其中需要递归调用,遍历所有的节点属性,如果节点属性中有v-开头,那就是Vue中的指令语法,再查看节点属性有无on开头,有就是原生的指令,通过调用方法对截取的指令通过Dom2的addeventListener('事件名',{})实现是事件的绑定

//实例化Vue new Vue({ el:'#app', data(){ return{} }, methods:{test(){}} })

 三.扩展

v-model实现数据双向绑定的本质

将data中的数据渲染到input的value上,通过input标签上的onchange方法实现data中的值改变,从而实现v-model的数据双向绑定.

你可能感兴趣的:(vue,vue.js)