企业的网站品牌推广,专业制作教学课件,第三方电子商务平台有哪些优势,重庆景点文章目录 前言✅ 当前已实现模块汇总#xff08;mini-vue#xff09;✅ 每个模块简要源码摘要1. reactive.ts2. effect.ts3. computed.ts4. ref.ts5. toRef.ts6. toRefs.ts ✅ 下一阶段推荐目标所有核心模块对应的 __tests__ 测试文件#xff0c;**带完整注释**✅ reactive.… 文章目录 前言✅ 当前已实现模块汇总mini-vue✅ 每个模块简要源码摘要1. reactive.ts2. effect.ts3. computed.ts4. ref.ts5. toRef.ts6. toRefs.ts ✅ 下一阶段推荐目标所有核心模块对应的 __tests__ 测试文件**带完整注释**✅ reactive.spec.ts✅ effect.spec.ts✅ computed.spec.ts✅ ref.spec.ts✅ toRefs.spec.ts✅ 总结你已支持的模块对应测试 前言
当前已完成的 mini-vue 项目功能模块列表以及每个模块对应 Vue 3 中的核心功能对照和简要源码说明 ✅ 当前已实现模块汇总mini-vue
模块文件名对应 Vue 3 功能描述响应式核心reactive.tsVue.reactive通过 Proxy 实现深层响应式对象追踪副作用收集effect.tsVue.effect依赖自动收集、调度器scheduler、懒执行lazy计算属性computed.tsVue.computed支持懒计算、缓存、依赖追踪、调度触发基本 Refref.tsVue.ref包装原始值为响应式对象追踪 value 的读写操作对象属性转 ReftoRef.tsVue.toRef将 reactive 对象的某个属性变为可独立响应式的 Ref批量属性转 ReftoRefs.tsVue.toRefs将整个对象的所有属性都转为 Ref支持结构保持响应式 ✅ 每个模块简要源码摘要 1. reactive.ts
import { track, trigger } from ./effectexport function reactiveT extends object(target: T): T {return new Proxy(target, {get(target, key, receiver) {track(target, key)return Reflect.get(target, key, receiver)},set(target, key, value, receiver) {const result Reflect.set(target, key, value, receiver)trigger(target, key)return result}})
}2. effect.ts
type EffectFn () void
interface EffectOptions {lazy?: booleanscheduler?: () void
}let activeEffect: EffectFn | null null
const targetMap new WeakMap()export function effect(fn: EffectFn, options: EffectOptions {}) {const effectFn () {activeEffect effectFnconst result fn()activeEffect nullreturn result}if (options.scheduler) effectFn.scheduler options.schedulerif (!options.lazy) effectFn()return effectFn
}export function track(target: object, key: string | symbol) { ... }
export function trigger(target: object, key: string | symbol) { ... }3. computed.ts
export function computedT(getter: () T) {let value: Tlet dirty trueconst runner effect(getter, {lazy: true,scheduler: () {dirty truetrigger(obj, value)}})const obj {get value() {track(obj, value)if (dirty) {value runner()dirty false}return value}}return obj
}4. ref.ts
export class RefImplT {private _value: Tconstructor(value: T) {this._value value}get value() {track(this, value)return this._value}set value(newVal: T) {if (newVal ! this._value) {this._value newValtrigger(this, value)}}
}export function refT(value: T) {return new RefImpl(value)
}5. toRef.ts
export function toRefT extends object, K extends keyof T(obj: T, key: K) {return {get value() {track(obj, key)return obj[key]},set value(val) {obj[key] valtrigger(obj, key)}}
}6. toRefs.ts
import { toRef } from ./toRefexport function toRefsT extends object(obj: T) {const result: any {}for (const key in obj) {result[key] toRef(obj, key)}return result
}✅ 下一阶段推荐目标
模块Vue 功能说明isRefVue.isRef()判断对象是否为 ref 实例unrefVue.unref()解包 ref 或返回原始值watchVue.watch()监听响应式值变化执行回调readonlyVue.readonly()创建只读响应式对象禁止写入shallowRefVue.shallowRef()创建浅层响应式对象 所有核心模块对应的 __tests__ 测试文件带完整注释
✅ reactive.spec.ts
import { describe, it, expect } from vitest
import { reactive } from ../src/reactive
import { effect } from ../src/effectdescribe(mini-vue: reactive, () {it(should track and trigger on get/set, () {const obj reactive({ count: 0 })let dummy: number 0effect(() {dummy obj.count})expect(dummy).toBe(0)// 修改属性 → 触发 trigger → 重新执行 effectobj.countexpect(dummy).toBe(1)})
})✅ effect.spec.ts
import { describe, it, expect, vi } from vitest
import { reactive } from ../src/reactive
import { effect } from ../src/effectdescribe(mini-vue: effect, () {it(should re-run effect on dependency change, () {const state reactive({ num: 1 })let dummyeffect(() {dummy state.num})expect(dummy).toBe(1)state.numexpect(dummy).toBe(2)})it(should allow scheduler, () {const state reactive({ foo: 1 })const scheduler vi.fn()const runner effect(() state.foo, { scheduler })// 不会立即运行 effect而是执行 schedulerstate.fooexpect(scheduler).toHaveBeenCalled()})
})✅ computed.spec.ts
import { describe, it, expect, vi } from vitest
import { reactive } from ../src/reactive
import { computed } from ../src/computed
import { effect } from ../src/effectdescribe(mini-vue: computed, () {it(should compute lazily and cache, () {const state reactive({ count: 1 })const getter vi.fn(() state.count 1)const c computed(getter)// 没访问前不会调用 getterexpect(getter).not.toHaveBeenCalled()// 第一次访问计算并缓存expect(c.value).toBe(2)expect(getter).toHaveBeenCalledTimes(1)// 第二次访问走缓存c.valueexpect(getter).toHaveBeenCalledTimes(1)// 修改依赖缓存失效state.countexpect(c.value).toBe(3)expect(getter).toHaveBeenCalledTimes(2)})it(should work inside effect, () {const state reactive({ count: 1 })const c computed(() state.count)let dummyeffect(() {dummy c.value})expect(dummy).toBe(1)state.countexpect(dummy).toBe(2)})
})✅ ref.spec.ts
import { describe, it, expect } from vitest
import { ref } from ../src/ref
import { effect } from ../src/effectdescribe(mini-vue: ref, () {it(should hold a value, () {const r ref(1)expect(r.value).toBe(1)})it(should be reactive, () {const r ref(1)let dummyeffect(() {dummy r.value})expect(dummy).toBe(1)r.valueexpect(dummy).toBe(2)})it(should not trigger if value not changed, () {const r ref(1)let dummy 0let calls 0effect(() {callsdummy r.value})expect(calls).toBe(1)r.value 1 // 设置相同值effect 不应重新执行expect(calls).toBe(1)})
})✅ toRefs.spec.ts
import { describe, it, expect } from vitest
import { reactive } from ../src/reactive
import { toRef } from ../src/toRef
import { toRefs } from ../src/toRefs
import { effect } from ../src/effectdescribe(mini-vue: toRef / toRefs, () {it(toRef should convert property to ref, () {const obj reactive({ count: 1 })const countRef toRef(obj, count)let dummyeffect(() {dummy countRef.value})expect(dummy).toBe(1)obj.countexpect(dummy).toBe(2)countRef.value 3expect(obj.count).toBe(3)})it(toRefs should convert all properties to refs, () {const obj reactive({ count: 1, name: vue })const refs toRefs(obj)expect(refs.count.value).toBe(1)expect(refs.name.value).toBe(vue)refs.count.valueexpect(obj.count).toBe(2)obj.name mini-vueexpect(refs.name.value).toBe(mini-vue)})
})✅ 总结你已支持的模块对应测试
模块名测试文件已验证功能reactivereactive.spec.tsget/set 追踪触发effecteffect.spec.ts基础响应式绑定、scheduler 调度computedcomputed.spec.ts懒计算、缓存、响应式依赖更新refref.spec.tsvalue 包装、响应式触发、去重toRef/toRefstoRefs.spec.ts属性映射为 ref、保持响应式联动