利用proxy实现简单的双向绑定

Vue中的双向绑定,让开发者能够更加集中精力于业务逻辑而不是操作dom。
实现数据响应式的原理主要有Object.defineProperty为对象设置存取器属性,以及ES6的proxy对象代理。
这里我通过proxy实现了简单的数据响应式。

数据渲染

  <div id="app">    
    <div>
      {
  {msg1}}
    </div>
    {
  {msg1}} ~~ {
  {msg2}}
    <form>
      <input type="text" v-model="msg1">
    </form>
  </div>
  
  <script>
    var data = {
    
      msg1: 'hello world',
      msg2: 'bye world'
    }
    var vm = new MyVue ({
    
      el: '#app',
      data
    })

    vm.data.msg2 = 'ok'
</script>

我们想通过将data中的数据渲染到页面上,即将html中的标签模版替换为对应的数据,这部分通过正则表达式即可实现。
具体来说,对div#app遍历子节点,文本节点即替换,元素节点就递归遍历子节点。
同时对元素节点,判断v-model属性是否存在,若存在,则设置其value为对应的数据。

数据单向绑定

单向绑定就是,如果在代码中改变了数据的值,那么页面立即重新渲染对应的元素。如上面代码中页面渲染后,执行代码vm.data.msg2 = 'ok',那么会自动更新页面内容。
简单说就是 data -> DOM 的绑定。
如何实现呢?可以分为两步:

  1. 监听到数据的变化
  2. 数据变化后,相应节点的重新渲染

监听数据变化可以通过Object.defineProperty,但这里采用了proxy的方式数据对象创建代理。

observe (data) {
   
  return new Proxy (data, {
   
    set: (target, prop, newValue) => {
   
      console.log('数据正在被修改:', prop, newValue)
      return Reflect.set(target, prop, newValue)
    }
  })
}

监听到数据变化后如何让相应的元素立即重新渲染呢?我是这样考虑的:
在第一次数据渲染的同时,为每个node注册自定义事件’dataChanged’,可以通过事件对象e.detail.newValue获取到新设定的值。对于文本节点,则用正则替换内容,元素节点则根据v-model属性中的值设定其value。

// 文本节点 注册自定义事件
node.addEventListener('dataChanged', (e) => {
   
  node.textContent = templateText.replace(reg,
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值