Files
vue-desktop/src/core/state/useObservableVue.ts
2025-08-26 17:04:31 +08:00

39 lines
1002 B
TypeScript

import type { Observable } from '@/core/state/Observable.ts'
import { onUnmounted, ref, type Ref } from 'vue'
/**
* vue使用自定义的 observable
* @param observable
* @param keys
* @returns
* @example
* const app = new Observable({ count: 0, isOpen: false, title: "Demo" })
* // 多字段订阅
* const state = useObservable(app, ["count", "isOpen"])
* // state.value.count / state.value.isOpen 响应式
*/
export function useObservable<T extends object, K extends keyof T>(
observable: Observable<T>,
keys?: K[] | K
): Ref<Pick<T, K> | T> {
const state = ref({} as any) // 响应式
const keyArray = keys ? (Array.isArray(keys) ? keys : [keys]) : null
// 订阅回调
const unsubscribe = keyArray
? observable.subscribeKey(keyArray as K[], changed => {
// 更新响应式 state
Object.assign(state.value, changed)
})
: observable.subscribe(s => {
state.value = { ...s }
})
onUnmounted(() => {
unsubscribe()
})
return state
}