import { reactive, onBeforeUnmount, type Reactive } from 'vue' import type { IObservable } from '@/core/state/IObservable.ts' /** * Vue Hook: useObservable * 支持深层解构赋值,直接修改触发 ObservableImpl 通知 + Vue 响应式更新 * @example * interface AppState { * count: number * user: { name: string; age: number } * items: number[] * } * * // 创建 ObservableImpl * const obs = new ObservableImpl({ * count: 0, * user: { name: 'Alice', age: 20 }, * items: [] * }) * * export default defineComponent({ * setup() { * // 深层解构 Hook * const { count, user, items } = useObservable(obs) * * const increment = () => { * count += 1 // 触发 ObservableImpl 通知 + Vue 更新 * } * * const changeAge = () => { * user.age = 30 // 深层对象也能触发通知 * } * * const addItem = () => { * items.push(42) // 数组方法拦截,触发通知 * } * * return { count, user, items, increment, changeAge, addItem } * } * }) */ export function useObservable(observable: IObservable): Reactive { // 创建 Vue 响应式对象 const state = reactive({} as T) /** * 将 ObservableImpl Proxy 映射到 Vue 响应式对象 * 递归支持深层对象 */ function mapKeys(obj: any, proxy: any) { (Object.keys(proxy) as (keyof typeof proxy)[]).forEach(key => { const value = proxy[key] if (typeof value === 'object' && value !== null) { // 递归创建子对象 Proxy obj[key] = reactive({} as typeof value) mapKeys(obj[key], value) } else { // 基本类型通过 getter/setter 同步 Object.defineProperty(obj, key, { enumerable: true, configurable: true, get() { return proxy[key] }, set(val) { proxy[key] = val }, }) } }) } // 获取 ObservableImpl 的 Proxy const refsProxy = observable.toRefsProxy() mapKeys(state, refsProxy) // 订阅 ObservableImpl,保持响应式同步 const unsubscribe = observable.subscribe(() => { // 空实现即可,getter/setter 已同步 }) onBeforeUnmount(() => { unsubscribe() }) return state }