39 lines
1002 B
TypeScript
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
|
|
}
|