vue-数据劫持

数据劫持

什么是数据劫持

  1. Object.defineProperty()

  2. 给一个对象添加get和set方法,在我们通过类似于obj.

    attribute获取属性的时候会调用get方法,通过obj.attribute = ***设置属性的时候会调用set方法,我们通过重写这个get,set方法就可以达到我们不可告人的目的-实现数据劫持

vue双向绑定原理

  1. Vue内部通过Object.defineProperty方法属性拦截的方式,把data对象里每个数据的读写转化成getter/setter,当数据变化时通知视图更新

  2. 在new Vue的时候,在Observer中通过Object.defineProperty()达到数据劫持,代理所有数据的getter和setter属性,在每次触发setter的时候,都会通过Dep来通知Watcher,Watcher作为Observer数据监听器与Compile模板解析器之间的桥梁,当Observer监听到数据发生改变的时候,通过Updater来通知Compile更新视图

  3. VUE实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。它接收三个参数,要操作的对象,要定义或修改的对象属性名,属性描述符。重点就是最后的属性描述符。属性描述符是一个对象,主要有两种形式:数据描述符和存取描述符。这两种对象只能选择一种使用,不能混合两种描述符的属性同时使用。上面说的get和set就是属于存取描述符对象的属性。

  4. 在面试中如何应对?面试官:说一下VUE双向绑定的原理?答:VUE实现双向数据绑定的原理就是利用了Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。

  5. 代码演示:defineProperty的用法var obj = { };var name;//第一个参数:定义属性的对象。//第二个参数:要定义或修改的属性的名称。//第三个参数:将被定义或修改的属性描述符。Object.defineProperty(obj, "data", {//获取值get: function () {return name;},//设置值set: function (val) {name = val;console.log(val)}})//赋值调用setobj.data = 'aaa';//取值调用getconsole.log(obj.data);代码演示:defineProperty的双向绑定var obj={};Object.defineProperty(obj, 'val',{set:function (newVal) {document.getElementById("a").value =newValundefined?'':newVal;document.getElementById("b").innerHTML=newValundefined?'':newVal;}});document.getElementById("a").addEventListener("keyup",function (e) {obj.val = e.target.value;})

  6. vue双向数据绑定是通过数据劫持结合发布订阅者模式来实现的。

    也就是数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也跟着变化,核心方法是Object.defineProperty()

数据劫持示例

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

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <!-- <input type="" name="" id="input" value="" /><br />
  <span id="span">我是初始值</span>
  <script type="text/javascript">
    const obj = {};
    let text = ''
    Object.defineProperty(obj, 'text', {
      get: function () {
        console.log('get val');
        return text
      },
      set: function (newVal) {
        console.log('set val:' + newVal);
        text = newVal
      }
    });
    const input = document.getElementById('input');
    input.addEventListener('keyup', function (e) {
      document.getElementById('span').innerHTML = obj.text = e.target.value;
    })
  </script> -->

  <script type="text/javascript">
    var Book = {};
    var name = '';
    Object.defineProperty(Book, 'name', {
      set: function (value) {
        name = value;
        console.log('你取了一个书名叫:' + value);
      },
      get: function () {
        console.log('get方法被监听到');
        return '<' + name + '>';
      }
    });
    Book.name = '人性的弱点'; //你取了一个书名叫:人性的弱点
    console.log(Book.name); //<人性的弱点>
  </script>
  <!-- <script>
    var obj3 = {};
    var newv = {
      a: 666
    }
    Object.defineProperty(obj3, 'newv', {
      set(v) {
        console.log(v);
      },
      get() {
        return newv
      }
    })
    obj3.newv.a = 222
  </script> -->
  <!-- <script>
     var obj = {
       name: 'tom'
     }
     var age = 24
     Object.defineProperty(obj, 'age', {
       enumerable: true,
       configurable: false,
       get() {
         console.log('get', age);
         return age
       },
       set(newVal) {
         console.log('set', age, newVal);
         age = newVal
       }
     })
     obj.age = 20
     console.log(obj);
   </script> -->
</body>

</html>
posted @ 2021-05-25 09:30  有风吹过的地方丨  阅读(255)  评论(0编辑  收藏  举报