使用 JavaScript Proxy 实现简单的数据绑定

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>proxy</title>
</head>
<body>
  <h1>使用Proxy 和 Reflect 实现双向数据绑定</h1>
  <input type="text" id="input">
  <h2>您输入的内容是: <i id="txt"></i></h2>
  <script>
    //获取dom元素
    let oInput = document.getElementById("input");
    let oTxt = document.getElementById("txt");

    //初始化代理对象
    let obj = {};
    //给obj增加代理对象
    let newProxy = new Proxy(obj, {
      get: (target, key, recevier) => {
        return Reflect.get(target, key, recevier);
      },
      set: (target, key, value, recevier) => {
        //监听newProxy是否有新的变化
        if (key == "text") {
          oTxt.innerHTML = value;
        }
        //将变化反射回原有对象
        return Reflect.set(target, key, value, recevier);
      }
    })
    //监听input输入事件
    oInput.addEventListener("keyup", (e) => {
      //修改代理对象的值
      newProxy.text = e.target.value;
    })
  </script>
</body>
</html>

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue的双向数据绑定是通过使用数据劫持和发布-订阅模式来实现的。以下是一个简单实现: 首先,我们需要创建一个观察者对象,它将负责收集依赖项和通知订阅者更新: ```javascript class Watcher { constructor(vm, expOrFn, cb) { this.vm = vm; this.getter = parsePath(expOrFn); this.cb = cb; this.value = this.get(); } get() { Dep.target = this; const value = this.getter.call(this.vm, this.vm); Dep.target = null; return value; } update() { const oldValue = this.value; this.value = this.get(); this.cb.call(this.vm, this.value, oldValue); } } ``` 接下来,我们需要创建一个依赖项对象,它将负责管理依赖项和通知观察者更新: ```javascript class Dep { constructor() { this.subs = []; } addSub(sub) { this.subs.push(sub); } removeSub(sub) { remove(this.subs, sub); } depend() { if (Dep.target) { Dep.target.addDep(this); } } notify() { const subs = this.subs.slice(); for (let i = 0, l = subs.length; i < l; i++) { subs[i].update(); } } } Dep.target = null; ``` 最后,我们需要创建一个代理对象,它将负责将实际的数据对象和观察者对象联系起来: ```javascript function observe(value) { if (!value || typeof value !== 'object') { return; } Object.keys(value).forEach(key => { defineReactive(value, key, value[key]); }); } function defineReactive(obj, key, val) { const dep = new Dep(); Object.defineProperty(obj, key, { enumerable: true, configurable: true, get() { dep.depend(); return val; }, set(newVal) { if (val === newVal) { return; } val = newVal; dep.notify(); }, }); } function proxy(target, sourceKey) { Object.keys(target[sourceKey]).forEach(key => { Object.defineProperty(target, key, { enumerable: true, configurable: true, get() { return target[sourceKey][key]; }, set(newVal) { target[sourceKey][key] = newVal; }, }); }); } class Vue { constructor(options) { this.$options = options; this._data = options.data; observe(this._data); proxy(this, '_data'); } } ``` 这就是一个简单的Vue双向数据绑定实现。当数据发生变化时,观察者对象将会被通知,并且视图将会自动更新。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值