美文网首页
Vue数据响应原理

Vue数据响应原理

作者: Pamcore | 来源:发表于2018-04-25 18:57 被阅读0次

Vue 数据响应依赖于Object.defineProperty,这也是Vue不支持IE8的原因。Vue通过设定对象属性的setter/getter方法来监听数据的变化。通过getter进行依赖收集,而每个setter方法就是一个观察者,在数据变更的时候通知订阅者更新视图。


看看简单的双向绑定实现

const obj = {

object.defineProperty(obj, 'hello', {
  get(value) {
    console.log('use get')
  },
  set(newVal, oldVal) {
    console.log('user')
  }

<input type="text" id="a"/>
<span id="b"></span>

<script>
    const obj = {};
    Object.defineProperty(obj,'hello',{
      get(){
        console.log("啦啦啦,方法被调用了");
      },
      set(newVal){
        document.getElementById('a').value = newVal;
        document.getElementById('b').innerHTML = newVal;
      }
    })
    document.addEventListener('keyup',function(e){
      obj.hello = e.target.value;
    })
</script>

将数据data变成可观察(observable)

function observer(val) {
  Object
    .key
    .forEach((val) => {
       defineReactive(val, key, value[key], cb)
    })
}
function defineReactive(obj, key, val, cb) {
  Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get: () => {
        /*....依赖收集等....*/
            /*Github:https://github.com/answershuto*/
      },
      set: newVal => {
        cb();/*订阅者收到消息的回调*/
      }
   })
}
class Vue {
   constructor(options) {
      this._data = options.data;
      observer(this._data, options.render)
    }
 }
let app = new Vue({
    el: '#app',
    data: {
        text: 'text',
        text2: 'text2'
    },
    render(){
        console.log("render");
    }
})

为了便于理解,首先考虑一种最简单的情况,不考虑数组等情况,代码如上所示。在initData中会调用observe这个函数将Vue的数据设置成observable的。当_data数据发生改变的时候就会触发set,对订阅者进行回调(在这里是render)。

那么问题来了,需要对app._date.text操作才会触发set。为了偷懒,我们需要一种方便的方法通过app.text直接设置就能触发set对视图进行重绘。那么就需要用到代理。

代理

我们可以在Vue的构造函数constructor中为data执行一个代理proxy。这样我们就把data上面的属性代理到了vm实例上。

_proxy(options.data);/*构造函数中*/

/*代理*/
function _proxy (data) {
   const that = this;
   Object.keys(data).forEach(key => {
       Object.defineProperty(that, key, {
           configurable: true,
           enumerable: true,
           get: function proxyGetter () {
               return that._data[key];
           },
           set: function proxySetter (val) {
               that._data[key] = val;
           }
       })
   });
}

我们就可以用app.text代替app._data.text了。

下面是一个模拟Vue数据绑定的方法


image

相关文章

  • 前端面试题【Day02】

    本篇绪论 1,Vue响应式原理 1,Vue响应式原理 在vue实例中声明的数据就是响应式的。响应式:数据发生改变,...

  • Vue的34道题

    1、如何理解MVVM原理? MVVM的实现原理 2、响应式数据的原理是什么? 响应式数据与数据依赖基本原理vue双...

  • 双向绑定

    数据响应式原理 vue实现数据响应式的原理就是利用了Object.defineProperty(),重新定义了对象...

  • 面试总结之基础(2)

    Vue2响应式原理 Vue3响应式原理

  • 手写 Vue Router、手写响应式实现、虚拟 DOM 和 D

    模拟 Vue.js 响应式原理 一、数据驱动 准备工作 数据驱动 响应式的核心原理 发布订阅模式和观察者模式 数据...

  • VUE中数据响应式原理

    1.vue数据响应式的原理2.数据属性的四大特性3.访问器属性4.getter和setter vue数据响应式主要...

  • vue系列--- vue响应式原理

    vue响应式原理 要说vue响应式原理首先要说的是Object.defindProperty(),这个是响应式原理...

  • Vue原理

    vue原理相关 Vue核心概念 vue实例化 虚拟dom 模板编译 数据绑定(响应式) 组件化 MVVM mode...

  • Vue数据响应原理

    Vue 数据响应依赖于Object.defineProperty,这也是Vue不支持IE8的原因。Vue通过设定对...

  • Vue数据响应原理

    我们知道当Vue data实例对象下的数据发生改变,视图会随之改变,那么它是遵循的什么底层原理呢?相信大家一定很...

网友评论

      本文标题:Vue数据响应原理

      本文链接:https://www.haomeiwen.com/subject/cegylftx.html