UNPKG

@vitarx/responsive

Version:
160 lines (159 loc) 5.33 kB
import { EffectScope } from '../../../effect/index.js'; import { DEEP_SIGNAL_SYMBOL, REF_SIGNAL_SYMBOL, type RefSignal, SIGNAL_RAW_VALUE_SYMBOL, SIGNAL_SYMBOL } from '../../core/index.js'; import type { ComputedOptions } from './types.js'; /** * # 计算属性 * * 计算属性是一种特殊的响应式数据,它的值由一个getter函数计算得出。 * 当依赖的响应式数据发生变化时,计算属性会自动重新计算并更新其值。 * * @template T - 计算结果的类型 * @implements {RefSignal<T>} - 实现RefSignal接口,使其可以像普通的响应式引用一样使用 * * @example * ```ts * const count = ref(0) * const double = new Computed(() => count.value * 2) * console.log(double.value) // 0 * count.value = 2 * console.log(double.value) // 4 * ``` */ export declare class Computed<T> implements RefSignal<T> { /** * 标识是否为深度响应式对象 * 计算属性不支持深度响应,始终为false */ readonly [DEEP_SIGNAL_SYMBOL]: boolean; /** * 标识为引用类型的响应式信号 */ readonly [REF_SIGNAL_SYMBOL]: true; /** * 标识为响应式信号对象 */ readonly [SIGNAL_SYMBOL]: true; /** * 计算结果缓存 * @private */ private _computedResult; /** * 计算属性的getter函数 * @private */ private readonly _getter; /** * 计算属性的配置选项 * @private */ private readonly _options; /** * 依赖变化的订阅处理器 * @private */ private _handler; /** * 作用域 * @private */ private _scope; /** * 构造一个计算属性对象 * * @param {(oldValue: T | undefined) => T} getter - 计算属性的getter函数,接收上一次的计算结果作为参数 * @param {ComputedOptions<T>} [options={}] - 计算属性的配置选项 * @param {(newValue: T) => void} [options.setter] - 计算属性的setter函数,用于处理对计算属性的赋值操作 * @param {boolean} [options.immediate=false] - 是否立即计算,默认为false,首次访问时才计算 * @param {boolean} [options.scope=true] - 是否添加到当前作用域,默认为true,作用域销毁时自动清理 * @param {boolean} [options.batch=true] - 是否使用批处理模式,默认为true,多个连续的变更会合并为一次计算 */ constructor(getter: (oldValue: T | undefined) => T, options?: ComputedOptions<T>); /** * 是否已初始化 * @private */ private _initialize; /** * 获取初始化状态的访问器 * 返回一个布尔值,表示对象是否已初始化 * @returns {boolean} 返回内部的_initialize属性值 */ get initialize(): boolean; /** * 获取计算属性的原始值 * 实现BaseSignal接口的SIGNAL_RAW_VALUE_SYMBOL属性 * * @returns {T} 计算结果的原始值 */ get [SIGNAL_RAW_VALUE_SYMBOL](): T; /** * 获取计算结果 * * 如果计算属性尚未初始化,则会先进行初始化。 * 每次访问都会追踪依赖,以便在依赖变化时能够正确地通知订阅者。 * * @returns {T} 计算结果 */ get value(): T; /** * 修改计算结果 * * 如果提供了setter函数,则调用setter函数处理新值; * 否则,输出警告信息,提示计算属性不应该被直接修改。 * * @param {T} newValue - 要设置的新值 */ set value(newValue: T); /** * 将计算属性转换为字符串 * * 如果计算结果有toString方法,则调用该方法; * 否则,返回格式化的类型描述。 * * @returns {string} 字符串表示 */ toString(): string; /** * 停止监听依赖变化 * * 调用此方法会停止对依赖的监听,并释放相关监听器。 * 计算属性将不再响应依赖的变化,但仍然保留最后一次计算的结果。 * * @returns {T} 最后一次的计算结果 */ stop(): T; /** * 定义当对象需要转换成原始值时的行为 * * 根据不同的转换提示返回适当的值: * - 'number': 返回计算结果,尝试进行数值转换 * - 'string': 调用toString方法获取字符串表示 * - 'default': 返回计算结果 * * @param {string} hint - 转换提示类型 * @returns {any} 根据提示类型转换后的原始值 */ [Symbol.toPrimitive](hint: string): any; /** * 设置作用域 * * 此方法仅在计算属性被初始化之前设置有效 * * @param {boolean | EffectScope} scope - 作用域或boolean值,表示是否允许添加到作用域 * @returns {this} 当前实例,支持链式调用 */ scope(scope: boolean | EffectScope): this; /** * 手动初始化计算属性 * * 执行以下步骤: * 1. 收集getter函数执行过程中的依赖 * 2. 缓存计算结果 * 3. 如果有依赖,创建订阅处理器监听依赖变化 * 4. 设置清理函数,在销毁时移除订阅 * * @returns {this} 当前实例,支持链式调用 */ init(): this; }