@mxydl2009/vue3-responsive
v1.2.1
Published
simulate vue3 responsive system for learning
Downloads
12
Maintainers
Readme
Modules
computed
computed API的具体实现
module.exports(getter) ⇒ object ⏏
计算属性的实现方案
- 实现懒计算:在读取计算属性的值时才真正计算;
- 实现缓存:多次读取计算属性值时,如果源值没有变化,则不需要重新计算: dirty标志位
- 源数据变更不会立即触发getter执行,而是读取值时才触发getter执行: 源数据变更触发dirty标志位变为true
Kind: Exported function
Returns: object - 计算属性返回的对象,读取该对象的value可以得到计算属性值
Title: 计算属性
| Param | Type | Description | | --- | --- | --- | | getter | function | getter函数,返回一个值(由其他响应式数据派生) |
core
响应式系统的核心文件, 包含了响应式系统的核心思想和方法,暴露给外部实现更加丰富的响应式功能API
- core
- static
- .effect(fn) ⇒ undefined | function
- .track(target, key) ⇒ undefined
- .trigger(target, key) ⇒ undefined
- inner
- static
core.effect(fn) ⇒ undefined | function
将全局指针activeEffect指向副作用函数fn, 在读取字段时通过activeEffect指针收集依赖, 注册函数只调用一次,用于建立对象读取与副作用函数的响应式联系
Kind: static method of core
Returns: undefined | function - 根据是否配置lazy选项而是否返回副作用函数引用还是undefined
Title: 注册副作用函数fn
| Param | Type | Description | | --- | --- | --- | | fn | function | 副作用函数 |
core.track(target, key) ⇒ undefined
对target[key]进行读取时,收集依赖副作用到target[key]对应的依赖集合
Kind: static method of core
Title: 追踪依赖
| Param | Type | Description | | --- | --- | --- | | target | object | 要追踪的目标对象 | | key | string | symbol | 要追踪的目标对象的属性 |
core.trigger(target, key) ⇒ undefined
触发target[key]对应的依赖函数执行
Kind: static method of core
Title: 触发依赖
| Param | Type | Description | | --- | --- | --- | | target | object | 目标对象,根据目标对象获取要触发的副作用函数 | | key | string | symbol | 目标对象的属性,根据目标对象的该属性可以获取要触发的副作用函数 |
core~cleanup()
从所有包含副作用函数的依赖集合中删除该副作用函数
Kind: inner method of core
Title: 清理副作用函数
queue
任务队列的操作和刷新
queue.enqueue(job)
入队, 调度任务(缓存到微任务队列中)执行
Kind: static method of queue
| Param | Type | Description | | --- | --- | --- | | job | function | 要调度执行的函数 |
queue.flushJob()
刷新队列 在微任务中,将队列中的函数依次执行, 清理队列
Kind: static method of queue
reactive
reactive 模块,提供reactive API,将原始对象转换为响应式对象
- reactive
- module.exports(data) ⇒ Proxy ⏏
- .shallowReactive(data) ⇒ Proxy
- module.exports(data) ⇒ Proxy ⏏
module.exports(data) ⇒ Proxy ⏏
深层响应
根据原始数据生成代理对象,代理对象的读写操作会进行依赖收集和依赖触发, 原型上的属性以及symbol除外, 因此, 不要使用symbol类型作为数据属性
Kind: Exported function
Returns: Proxy - 由原始数据生成的代理对象
| Param | Type | Description | | --- | --- | --- | | data | object | 原始数据 |
module.exports.shallowReactive(data) ⇒ Proxy
浅层响应
根据原始数据生成代理对象,代理对象的读写操作会进行依赖收集和依赖触发,原型上的属性以及symbol除外, 因此, 不要使用symbol类型作为数据属性
Kind: static method of module.exports
Returns: Proxy - 由原始数据生成的代理对象
| Param | Type | Description | | --- | --- | --- | | data | object | 原始数据 |
ref
ref 相关API的具体实现
- ref
- module.exports(val) ⇒ object ⏏
- .toRef(obj, key) ⇒ object
- .toRefs(obj) ⇒ object
- .proxyRefs(target) ⇒ object
- module.exports(val) ⇒ object ⏏
module.exports(val) ⇒ object ⏏
ref函数,将原始值转换为响应式对象,通过对象的value属性操作来实现原始值的响应式
Kind: Exported function
Returns: object - 转化后的响应式对象
用法示例
const foo = 'foo';
const fooObj = ref(foo);
effect(() => {
console.log(fooObj.value); // foo
});
fooObj.value = 'bar'; // 打印bar
Title: ref function
| Param | Type | Description | | --- | --- | --- | | val | string | number | symbol | bigint | boolean | 原始值 |
module.exports.toRef(obj, key) ⇒ object
将响应式对象的属性操作(读取/写入)进行ref转换,转换后的对象可以通过解构赋值等浅拷贝操作而不会丢失响应
Kind: static method of module.exports
Returns: object - 转换后的值
Title: toRef
| Param | Type | Description | | --- | --- | --- | | obj | object | 待转换的响应式对象 | | key | string | symbol | 待转换的属性名 |
module.exports.toRefs(obj) ⇒ object
将响应式对象obj进行ref转换,保证转换后的对象通过解构或者浅拷贝也不会丢失响应
Kind: static method of module.exports
Returns: object - 转换后的对象
用法示例
const obj = shallowReactive({ foo: 'foo', bar: 'bar' });
const refObj = toRefs(obj);
console.log(refObj.foo.value); // foo
const copy = { ...refObj }; // copy.foo.value不会丢失响应
Title: toRefs
| Param | Type | Description | | --- | --- | --- | | obj | object | 待转换的响应式对象 |
module.exports.proxyRefs(target) ⇒ object
自动脱ref:如果访问的属性是ref对象,那么直接返回ref对象的value值
Vue中,setup函数返回的对象会经过proxyRefs处理,所以如果返回的对象包含属性值为ref的值,就会在访问时自动脱ref
Kind: static method of module.exports
Returns: object - 已脱ref的对象
用法示例
const obj = shallowReactive({ foo: 'foo', bar: 'bar' });
const refObj = toRefs(obj); // refObj的属性都是ref对象
const decaRef = proxyRef(refObj); // 访问decaRef的属性值时不再需要加上.value了
console.log(decaRef.foo) // foo
console.log(decaRef.bar) // bar
| Param | Type | Description | | --- | --- | --- | | target | object | 待脱ref的对象 |
watch
watch API具体实现
- watch
- module.exports(source, cb) ⇒ undefined ⏏
- ~traverse(obj, readAlready) ⇒ obj | function | undefined
- module.exports(source, cb) ⇒ undefined ⏏
module.exports(source, cb) ⇒ undefined ⏏
侦听器: 侦听响应式数据变化并通知回调函数 通常副作用函数内部在读取属性值时会被搜集到该属性的依赖集合中,但是如果副作用函数没有触发读取操作时,就无法自动触发搜集依赖的操作; 因此,侦听器就需要手动触发搜集依赖的操作。
- 第一种方式:递归地对source对象的属性进行手动追踪依赖,在set trap中触发cb,这种方式适合source是plain object;
- 第二种方式:使用effect函数,传入的fn递归地读取source的属性(自动追踪依赖,因为此时的source已经是响应式数据了),options.scheduler函数调用cb,这样响应式副作用就变成了scheduler函数了;
Kind: Exported function
| Param | Type | Description | | --- | --- | --- | | source | object | getter | 被侦听的响应式数据或者getter函数 | | cb | function | 数据变化触发的回调函数 |
module.exports~traverse(obj, readAlready) ⇒ obj | function | undefined
深度读取obj数据
Kind: inner method of module.exports
| Param | Type | Description | | --- | --- | --- | | obj | * | 要深度读取的数据 | | readAlready | * | 已经读取过的数据,避免因为循环引用导致的无限递归 |