我们简单分析三种响应式的方法:
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 = "";
}