vue2和vue3的双向绑定原理

一、在vue2中

在vue2中:使用Object.defineProperty对象以及对象属性的劫持+发布订阅模式,只要数据发生变化直接通知变化 并驱动视图更新。

语法:

Object.defineProperty(目标对象,属性名,修饰符);

Object.defineProperty(obj, "name", { get:()=> {}, set:()=> {})

参数一: obj:劫持对象,参数二:"name":劫持对象属性 , 参数三:给属性添加set,get方法

示例:

let obj = { name: "tom", age: 10 };

   Object.defineProperty(obj, "name", {

     get: () => {

       console.log("访问了name属性");

     },

     set: (newVule) => {

       console.log("设置了name属性");

     },

   });

   obj.name; //触发get

   obj.name = "jack";//触发set

Vue2双向数据绑定存在的问题:

关于对象: Vue 无法检测 property 的添加或移除。

关于数组:不能利用索引直接设置一个数组项,也不能修改数组的长度。

二、在vue3中 

原理:Vue3.0中的响应式采用了ES6中的 Proxy 方法。Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)

语法:

let p =new Proxy(obj,{get:(target,prop,p)=>{},set:(target, prop, vaule, p)=>{}})

参数: target:劫持对象,参数二:prop:劫持对象属性 , 参数三:vaule:新的属性值, p:本身

示例

     let data = {
         name:"老王",
         age:18,
        fun(){
            console.log(this);
       },
        list:[1,2,3]
     }

     let proxy = new Proxy(data,{
         get(target,pro){
             console.log("get");
             return Reflect.get(target,pro);
             // return target[pro];
         },
         set(target,pro,value){
             console.log("set");
             // target[pro] = value;
             Reflect.set(target,pro,value);
         }
     })

     proxy.name = "小明";
     console.log(proxy.name);

     proxy.list[0] = 999;

总结:

vue2通过Object.defineProperty劫持的是对象中每一个属性

vue3通过Proxy劫持的是对象中每一个属性

为什么用Proxy代替Object.defineProperty?
        Vue2.X通过Object.defineProperty()来劫持各个属性的setter,getter,新版本通过Proxy劫持属性 Proxy优势 支持数组,其实还不止
        Object.defineProperty() 的问题主要有三个: 不能监听数组的变化 必须遍历对象的每个属性 必须深层遍历嵌套的对象
        1,Object.definedProperty作用是劫持一个对象的属性,劫持属性的getter和setter方法,在对象的属性发生变化时进行特定的操作。而 Proxy 劫持的是整个对象
Proxy 会返回一个代理对象,我们只需要操作新对象即可,而 Object.defineProperty只能遍历对象属性直接修改。
        2,Object.definedProperty不支持数组,更准确的说是不支持数组的各种API,因为如果仅仅考虑arry[i] = value 这种情况,是可以劫持的,但是这种劫持意义不大。而Proxy 可以支持数组的各种API。
        3,尽管 Object.defineProperty 有诸多缺陷,但是其兼容性要好于 Proxy.
PS: Vue2.x 使用 Object.defineProperty 实现数据双向绑定,V3.0 则使用了 Proxy

你可能感兴趣的:(前端,vue)