98世界杯主题曲_世界杯4强 - dajimy.com

文章目录

一、概述1. 响应式核心原理

二、Ref 和 Reactive对比三、 Reactive 实现原理1. 核心实现2. 完整的 reactive 实现

四、 ref 实现原理1. 基础 ref 实现2. 完整的 ref 系统

五、 完整的响应式系统实现六、关键点解析七、与真实 Vue 3 的差异

好的,我们来深入剖析 Vue 3 中

ref 和

reactive 的核心原理,并手写一个简化但能体现核心思想的实现。

一、概述

1. 响应式核心原理

Vue3 的响应式系统基于 ES6 的 Proxy 实现,相比 Vue2 的 Object.defineProperty 有以下优势:

可以监听数组变化可以监听对象属性的添加和删除性能更好

二、Ref 和 Reactive对比

以下是 ref 和 reactive的核心概念与区别

特性refreactive适用类型原始值 (number, string, boolean) 和 对象仅对象 (包括数组、Map、Set 等复杂类型)访问方式.value 访问/修改值直接访问/修改属性底层实现包装成一个带有 .value 属性的对象,用 Proxy 拦截 .value 的读写直接用 Proxy 包装目标对象本身解构问题解构会失去响应性解构会失去响应性 (... 扩展运算符也会)内部转换reactive 内部如果遇到 ref,会自动解包 (unwrap)

三、 Reactive 实现原理

1. 核心实现

// 响应式处理

function reactive(target) {

return createReactiveObject(target);

}

// 创建响应式对象

function createReactiveObject(target) {

// 如果不是对象,直接返回

if (typeof target !== 'object' || target === null) {

return target;

}

// 如果已经是代理对象,直接返回

if (target.__v_isReactive) {

return target;

}

const proxy = new Proxy(target, {

get(target, key, receiver) {

// 内置属性标识

if (key === '__v_isReactive') {

return true;

}

const res = Reflect.get(target, key, receiver);

// 依赖收集

track(target, key);

// 递归处理嵌套对象

return isObject(res) ? reactive(res) : res;

},

set(target, key, value, receiver) {

const oldValue = target[key];

const result = Reflect.set(target, key, value, receiver);

// 触发更新

if (oldValue !== value) {

trigger(target, key);

}

return result;

},

deleteProperty(target, key) {

const hadKey = hasOwn(target, key);

const result = Reflect.deleteProperty(target, key);

if (hadKey && result) {

trigger(target, key);

}

return result;

}

});

return proxy;

}

// 工具函数

function isObject(val) {

return val !== null && typeof val === 'object';

}

function hasOwn(target, key) {

return Object.prototype.hasOwnProperty.call(target, key);

}

2. 完整的 reactive 实现

// 依赖收集和触发

const targetMap = new WeakMap();

let activeEffect = null;

function track(target, key) {

if (!activeEffect) return;

let depsMap = targetMap.get(target);

if (!depsMap) {

targetMap.set(target, (depsMap = new Map()));

}

let dep = depsMap.get(key);

if (!dep) {

depsMap.set(key, (dep = new Set()));

}

dep.add(activeEffect);

}

function trigger(target, key) {

const depsMap = targetMap.get(target);

if (!depsMap) return;

const dep = depsMap.get(key);

if (dep) {

dep.forEach(effect => effect());

}

}

// 完整的 reactive 函数

function reactive(target) {

if (!isObject(target)) {

console.warn(`value cannot be made reactive: ${String(target)}`);

return target;

}

if (target.__v_isReactive) {

return target;

}

const handler = {

get(target, key, receiver) {

if (key === '__v_isReactive') {

return true;

}

const res = Reflect.get(target, key, receiver);

track(target, key);

return isObject(res) ? reactive(res) : res;

},

set(target, key, value, receiver) {

const oldValue = target[key];

const result = Reflect.set(target, key, value, receiver);

if (oldValue !== value) {

trigger(target, key);

}

return result;

},

deleteProperty(target, key) {

const hadKey = hasOwn(target, key);

const result = Reflect.deleteProperty(target, key);

if (hadKey && result) {

trigger(target, key);

}

return result;

}

};

return new Proxy(target, handler);

}

四、 ref 实现原理

1. 基础 ref 实现

function ref(value) {

return createRef(value);

}

function createRef(rawValue) {

// 如果已经是 ref,直接返回

if (isRef(rawValue)) {

return rawValue;

}

return new RefImpl(rawValue);

}

class RefImpl {

constructor(value) {

this.__v_isRef = true;

this._value = isObject(value) ? reactive(value) : value;

this.dep = new Set();

}

get value() {

trackRefValue(this);

return this._value;

}

set value(newVal) {

if (newVal !== this._value) {

this._value = isObject(newVal) ? reactive(newVal) : newVal;

triggerRefValue(this);

}

}

}

function isRef(r) {

return !!(r && r.__v_isRef === true);

}

function trackRefValue(ref) {

if (activeEffect) {

ref.dep.add(activeEffect);

}

}

function triggerRefValue(ref) {

ref.dep.forEach(effect => effect());

}

2. 完整的 ref 系统

// 完整的 ref 实现

class RefImpl {

constructor(value) {

this.__v_isRef = true;

this._rawValue = value;

this._value = convert(value);

this.dep = new Set();

}

get value() {

trackRefValue(this);

return this._value;

}

set value(newVal) {

if (hasChanged(newVal, this._rawValue)) {

this._rawValue = newVal;

this._value = convert(newVal);

triggerRefValue(this);

}

}

}

// 工具函数

function convert(val) {

return isObject(val) ? reactive(val) : val;

}

function hasChanged(value, oldValue) {

return !Object.is(value, oldValue);

}

function ref(value) {

return createRef(value, false);

}

function createRef(rawValue, shallow) {

if (isRef(rawValue)) {

return rawValue;

}

return new RefImpl(rawValue);

}

// 自动解构 ref

function unref(ref) {

return isRef(ref) ? ref.value : ref;

}

// 在模板中自动解构

function proxyRefs(objectWithRefs) {

return new Proxy(objectWithRefs, {

get(target, key, receiver) {

return unref(Reflect.get(target, key, receiver));

},

set(target, key, value, receiver) {

const oldValue = target[key];

if (isRef(oldValue) && !isRef(value)) {

oldValue.value = value;

return true;

} else {

return Reflect.set(target, key, value, receiver);

}

}

});

}

五、 完整的响应式系统实现

// 完整的响应式系统

class ReactiveEffect {

constructor(fn) {

this.fn = fn;

}

run() {

activeEffect = this;

return this.fn();

}

}

function effect(fn) {

const _effect = new ReactiveEffect(fn);

_effect.run();

return _effect;

}

// 响应式系统核心

const reactiveMap = new WeakMap();

function reactive(target) {

const existingProxy = reactiveMap.get(target);

if (existingProxy) {

return existingProxy;

}

const proxy = createReactiveObject(

target,

baseHandlers,

collectionHandlers

);

reactiveMap.set(target, proxy);

return proxy;

}

const baseHandlers = {

get(target, key, receiver) {

if (key === '__v_isReactive') return true;

const res = Reflect.get(target, key, receiver);

track(target, key);

if (isObject(res)) {

return reactive(res);

}

return res;

},

set(target, key, value, receiver) {

const oldValue = target[key];

const result = Reflect.set(target, key, value, receiver);

if (hasChanged(value, oldValue)) {

trigger(target, key);

}

return result;

},

deleteProperty(target, key) {

const hadKey = hasOwn(target, key);

const result = Reflect.deleteProperty(target, key);

if (hadKey && result) {

trigger(target, key);

}

return result;

}

};

// 测试用例

function testReactiveSystem() {

console.log('=== Testing Reactive System ===');

// 测试 reactive

const state = reactive({ count: 0, user: { name: 'John' } });

effect(() => {

console.log('Count changed:', state.count);

});

effect(() => {

console.log('User name:', state.user.name);

});

state.count = 1;

state.user.name = 'Jane';

// 测试 ref

const count = ref(0);

effect(() => {

console.log('Ref count:', count.value);

});

count.value = 10;

}

// 运行测试

testReactiveSystem();

六、关键点解析

ref 的本质:

它是一个对象,这个对象有一个 .value 属性。我们对 .value 的读写进行拦截,从而让原始值具备了响应性。__v_isRef 是一个标志位,告诉 reactive 系统“这是一个 ref,请在访问时自动解包”。 reactive 的深度响应式:

在 get 拦截器中,如果发现获取的值是一个对象,会递归调用 reactive,确保嵌套对象也是响应式的。 自动解包 (Auto-unwrapping):

当 ref 被放入 reactive 对象中时,在模板或 effect 中访问 user.age 时,reactive 的 get 拦截器检测到 age 是一个 ref(通过 __v_isRef),于是返回 age.value,实现了自动解包。这是 Vue 3 模板语法简洁的关键。 computed 的惰性求值:

computed 返回的也是一个 ref。它内部有一个 dirty 标志位,只有当依赖的数据变化时才标记为脏。只有当有人读取 .value 且 dirty 为 true 时,才会重新执行 getter 函数。

七、与真实 Vue 3 的差异

性能优化:真实的 trigger 有更复杂的调度机制(queueJob)和 flush 时机(pre, post, sync)。边界情况:真实实现处理了 Symbol、in 操作符、has 拦截器、数组索引变化等。shallowReactive / shallowRef:浅层响应式。toRefs:解决解构失去响应性的问题。readonly:只读代理。effectScope:副作用作用域管理。

这个手写版本虽然简化,但已经完整地体现了 ref 和 reactive 的核心设计思想和交互逻辑,是理解 Vue 3 Composition API 响应式原理的绝佳起点。