每天一个前端小知识14——手写Vue2响应式

总结

发布订阅模式 + 双向数据绑定 = vue2响应式

效果图

在这里插入图片描述

代码

vue2.js

// vue2响应式

// 订阅器模型
let Dep = {
    
    
  clientList: {
    
    },
  // 添加订阅者
  listen: function (key, fn) {
    
    
    (this.clientList[key] || (this.clientList[key] = [])).push(fn)
  },
  // 推送方法
  trigger: function () {
    
    
    let key = Array.prototype.shift.call(arguments),
      fns = this.clientList[key]
    if (!fns || fns.length === 0) {
    
    
      return false
    }

    for (let i = 0, fn; fn = fns[i++];) {
    
    
      fn.apply(this, arguments)
    }
  }
}

// 数据劫持
let dataHiBeiZhen = function ({
    
     data, tag, datakey, selector }) {
    
    
  let value = '',
    el = document.querySelector(selector)

  Object.defineProperty(data, datakey, {
    
    
    get: function () {
    
    
      console.log('取值')
      return value
    },
    set: function (val) {
    
    
      console.log('设置值')
      value = val
      // 数据变化
      Dep.trigger(tag, val)
    }
  })
  // 添加订阅者
  Dep.listen(tag, function (text) {
    
    
    el.innerHTML = text
  })
}

vue2.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue2响应式</title>
</head>

<body>
  <div id="id">
    视图1<span class="box1">11</span><br />
    视图2<span class="box2">22</span>
  </div>

  <script src="./vue2.js"></script>
  <script>
    let dataObj = {
    
    }

    dataHiBeiZhen({
    
    
      data: dataObj,
      tag: 'view1',
      datakey: 'one',
      selector: '.box1'
    })
    dataHiBeiZhen({
    
    
      data: dataObj,
      tag: 'view2',
      datakey: 'two',
      selector: '.box2'
    })

    dataObj.one = 'beizhen'
    dataObj.two = 'beizhen2'
  </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/qq_33591873/article/details/128364879