最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • ES5与ES6实现双向绑定(two-way-binding)的区别

    正文概述 掘金(bugvvd)   2021-02-12   645

    数据绑定

    单向绑定:将 Model 绑定到 View,当 Model 的数据被 JavaScript 代码更新时,View 就自动被更新。

    双向绑定:在单向绑定的基础上将 View 绑定到 Model,也即 ViewModel 当中任意一方的更新都会引起对方的更新。

    ES5:访问器实现数据劫持(Hijacking)

    利用ES5对象的访问器属性 gettersetter ,当用户读取和写入某个特定的对象属性时,通过劫持实现 View => Model (通常在 getter 内)以及 Model => View (通常在 setter 内)的更新。

    ES5 示例

    视图部分(View)

    <!--将视图部分中 foo 输入的值绑定到数据部分中的 input 变量上,并在 bar 的文本显示-->
    <div>
        <input type="text" id="foo">
        <span id="bar"></span>
    </div>
    

    数据部分(Model)

      let input = {}
      Object.defineProperty(input, 'inputValue', {
          configurable: true,
          enumerable: true,
          get: function(){
              // View => Model
              return document.getElementById("foo").value;
          },
          set: function(newVal){
              // Model => View
              document.getElementById("foo").value = newVal;
              document.getElementById("bar").textContent = newVal;
          }
      })
      document.getElementById("foo").addEventListener('keyup', function(e){
          // 仅仅是个展示问题
          // get
          document.getElementById("bar").textContent = input.inputValue;
          // 或者 set 
          // input.inputValue = e.target.value
    
      })
    

    ES6:代理器 Proxy 配合 Reflect

    Proxy

    Proxy 用于修改某些对目标对象的默认操作,可以理解为为在用户与目标对象之间假设一层拦截,or namely “代理”。用户对目标对象的访问,都必须先通过这层代理。因此通过 Proxy 的设置,我们可以对外加的访问进行过滤和改写。

    一个 new Proxy(target, handler) 对象由两个对象组成: targethandler

    • target 就是被代理的对象
    • handler 就是一个包含了13种代理操作的对象

    Reflect

    Reflect 的核心就是将原有的Object的部分方法放到了Reflect上,比如:

    Reflect.get(target, name, receiver)
    

    该方法被用来读取一个对象的属性。

    • target: 目标对象
    • name: 是我们要读取的属性。
    • receiver(可选): 可以理解为上下文this对象。

    以及

    Reflect.set(target,name,value,receiver)
    
    • receiver: 可以理解为上下文this对象。如果我们在设置值的时候遇到setter函数,该参数就指向与setter中上下文this对象。
    • 返回值:该函数会返回一个Boolean的值,代表在目标对象上设置属性是否成功。

    ES6 示例

    视图部分(View)

    <!--将视图部分中 foo 输入的值绑定到数据部分中的 input 变量上,并在 bar 的文本显示-->
    <div>
        <input type="text" id="foo">
        <span id="bar"></span>
    </div>
    

    数据部分(Model)

    // let input = { inputValue: "123", foo:"foo", bar:"bar" }
    // target 就是第一个参数,它是否是一个具名对象其实无所谓
    let inputProxy = new Proxy({}, {
        get: function (target, key, proxy) {
            console.log(target);
            return Reflect.get(target, key, proxy);
        },
        set: function (target, key, value, proxy) {
            document.getElementById("foo").value = value;
            document.getElementById("bar").textContent = value;
            return Reflect.set(target, key, value, proxy);
    
        }
    }
    );
    
    document.getElementById("foo").addEventListener('keyup', function (e) {
        // 显然由于 Proxy getter 这里没有绑定到视图,所以用 Proxy setter 来绑定
        inputProxy.inputValue = e.target.value;
    })
    

    监听 input 的时候如果用户修改 inputProxy 的值,因为 inputProxy 代理了 input 这个对象 (as target), 所以可以调用 Reflcet 反射到原 input 对象。但反过来说,直接修改 input 的值就对 inputProxy 没有任何影响,是故 target 是叫 input 还是张三李四王五事实上都无所谓,具名对象更多可能是处于管理上的遍历吧我猜?

    [TBA:ES6 Proxy 详解。以及 Reflect 详解 ]


    起源地下载网 » ES5与ES6实现双向绑定(two-way-binding)的区别

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元