Vue三种响应式对比

170 阅读1分钟

我们简单分析三种响应式的方法:

Vue2.0中的definedProperty

利用definedProperty并不是真正的代理,只是对属性做了劫持,比如对象删除或者数组的一些操作都是不能劫持到的。

const obj = { a: 0 };
Object.defineProperty(obj, "a", {
    get() {
      console.log("obj1 -> get");
    },
    set() {
      console.log("obj1 -> set");
    },
});
obj.a;
obj.a = 2;

Vue3.0中的reactive

Proxy是真正的代理,有13种操作(包括数组)都能劫持到。再配合Reflect使用起来更方便。

const obj2 = { a: 0 };
const obj2Proxy = new Proxy(obj2, {
    get(key) {
      console.log("obj2 -> get");
    },
    set() {
      console.log("obj2 -> set");
    },
    deleteProperty() {
      console.log("obj2 -> delete");
    },
});
obj2Proxy.a;
obj2Proxy.a = 2;
delete obj2Proxy.a;

Vue3.0中的ref

reactive一般用来劫持对象,如果我们想把一个简单的String、Number等基本类型的数据变成响应式。使用vue3中的ref方法,实现如下:

const tar = {
    get value() {
    console.log("tar -> get");
    return 1111;
    },
    set value(val) {
    console.log("tar -> set");
    }
};
tar.value;
tar.value = 2;

注意: 我们平时实际开发中很多场景都能用响应式来快速实现业务,大家可以关注VueUse,举例: 用响应式来实现localStorage数据的自动写入:

import { ref, watchEffect, computed } from "vue";
let title = ref("");
let todos = ref(JSON.parse(localStorage.getItem('todos')||'[]'));
watchEffect(()=>{ 
    localStorage.setItem('todos',JSON.stringify(todos.value))
});
function addTodo() { 
    todos.value.push({ title: title.value, done: false, }); 
    title.value = "";
}