Vue六大基本类型中的原始值响应式
知奕奕 人气:0所谓原始值即针对六大基本类型的值的响应式
ref
由于 proxy 无法阻止原始值的修改,故此方法在这里不管用
我们可以创建一个包裹对象把原始值包起来;
然后在使用 reactive 将该包裹对象变成响应式的即可
__v_isRef 属性是用来判断是否为 ref 包裹对象的判据
function ref(val) { // 包裹对象 const wrapper = { value: val, }; // 是否为ref的判据 Object.defineProperty(wrapper, "__v_isRef", { value: true, }); // 返回响应式数据 return reactive(wrapper); }
响应丢失
响应丢失问题:使用 reactive 创建响应式对象后,使用多参的形式 return,则实际上返回的是普通对象而非响应式对象!
export default { setup() { const obj = reactive({ a: 1, b: 2 }); return { ...obj, }; }, };
响应关系建立
obj 为原响应对象
newobj 内拥有与 obj 同名的所有属性值,且均一一编写访问器属性 value
value 执行后返回原响应对象中的值
这样一来,修改 obj 属性后,便会自动触发副作用函数执行!
const obj = reactive({ a: 1, b: 2 }); const newobj = { a: { get value() { return obj.a; }, }, b: { get value() { return obj.b; }, }, }; console.log(newobj.a.value);
toRef 函数的实现
使用包裹 wrapper,内部加上 getter、setter 方法实现响应式
function toRef(obj, key) { const wrapper = { get value() { return obj[key]; }, set value(val) { obj[key] = val; }, }; Object.defineProperty(wrapper, "__v_isRef", { value: true, }); return wrapper; }
自动脱 ref
使用 proxy 代理
判断如果存在属性 __v_isRef
,表示其为 ref,则返回该 ref 的值;
如果只是普通对象,那原样返回即可
function proxyRefs(target) { return new Proxy(target, { get(target, key, receiver) { const value = Reflect.get(target, key, receiver); return value.__v_isRef ? value.value : value; }, }); }
reactive 就是一个自动脱 ref 的例子,使用他的时候无需额外调用 value 即可获取值
加载全部内容