【Vue2】最基础的原理

2021-03-15  本文已影响0人  睡神疯子

Vue2.X 双向数据绑定使用的是 Object.defineProperty(),Vue3 使用的是 Proxy

Object.defineProperty()

Object.defineProperty(obj, prop, descriptor)
obj 要定义属性的对象。
prop 要定义或修改的属性的名称或 Symbol
descriptor 要定义或修改的属性描述符。

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <input class="inp-text" type="text">
    <div class="text-box"></div>
  </body>
  <script>
    let obj = {};
    Object.defineProperty(obj, 'name', {
        set: function(newValue){
            console.log('触发setter');
            document.querySelector('.text-box').innerHTML = newValue;
            document.querySelector('.inp-text').value = newValue;
        },
        get: function(){
            console.log('触发getter');
        }
    });
    document.querySelector('.inp-text').addEventListener('input', function(e){
        obj.name = e.target.value;
    }, false);
  </script>
</html>
Proxy

const p = new Proxy(target, handler)
target 要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="div1">
      <input type="text" v-model="name"><br>
      姓名:{{name}}<br>
      年龄:{{age}}
    </div>
  </body>
  <script>
  let el=document.getElementById('div1');
  let template=el.innerHTML;
  let _data={
    name: 'liangzai',
    age: 18
  };
  let data=new Proxy(_data, {
    set(obj, name, value){
      //alert(`有人视图设置 ${name}=>${value}`);
      obj[name]=value;
      //数据变了
      //console.log('数据变了');
      render();
    }
  });
  render();
  function render(){
    //渲染
    el.innerHTML=template.replace(/\{\{\w+\}\}/g, str=>{
      str=str.substring(2, str.length-2);
      return _data[str];
    });
    //找所有的v-model
    Array.from(el.getElementsByTagName('input'))
      .filter(ele=>ele.getAttribute('v-model'))
      .forEach(input=>{
        let name=input.getAttribute('v-model');
        input.value=_data[name];
        input.oninput=function (){
          console.log(1)
          data[name]=this.value;
        };
      });
  }
  </script>
</html>
上一篇下一篇

猜你喜欢

热点阅读