vue2.0双向绑定原理简单解析

vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。

1、订阅者模型

// 订阅器模型
let Dep = {
  clientList: {}, // 深拷贝与浅拷贝
  // 添加订阅者
  listen: function(key, fn) {
    (this.clientList[key] || (this.clientList[key] = [])).push(fn)
  },
  // 发布消息
  trigger: function() {
    console.log(arguments);
    let key = Array.prototype.shift.call(arguments) // arguments是类数组对象,不能直接用shift
    let fns = this.clientList[key];
    if (!fns || fns.length === 0) {
      return false
    }
    console.log(key, arguments);
    for (let i = 0, fn; fn = fns[i++];) {
      fn.apply(this, arguments)
    }
  }
}

2、发布订阅模式 + 数据劫持

// 发布订阅模式 + 数据劫持

// 劫持方法
let dataHijack = function({data, tag, datakey, selector}) {
  let value = ''
  let el = document.querySelector(selector)
  Dep.listen(tag, function(text) {
    el.innerHTML = text
  })
  // 数据劫持
  Object.defineProperty(data, datakey, {  // 访问器属性:setter、getter
    get: function() {
      console.log('获取到值了!');
      return value
    },
    set: function(newValue) {
      console.log('设置值了!');
      value = newValue
      Dep.trigger(tag, newValue)
    }
  });
}

3、测试用例

<body>
  订阅视图-1:<span class="box-1"></span>
  订阅视图-2:<span class="box-2"></span>
</body>
<script src="./test.js"></script>
<script>
  let dataObj = {}
  dataHijack({
    data: dataObj,
    tag: 'view-1',
    datakey: 'one',
    selector: '.box-1'
  })
  dataHijack({
    data: dataObj,
    tag: 'view-2',
    datakey: 'two',
    selector: '.box-2'
  })
  dataObj.one = '你好'


  let obj = {
    name: '一然',
    age: 23
  }
  function method() {
    console.log(this.age);
  }
  method.call(obj)
</script>
image
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容