Skip to the content.

useCompExp:Vue组件树内的数据共享

useCompExp 基于 Vue 的 provide / inject,在组件树内共享数据方法,简化typescript类型,无需层层透传 props / emit。

一、和 Pinia 的区别

二、基础用法

使用useCompExp规定类型

export const useActivity = ({ isMaster = false } = {}) =>
  useCompExp<{
    freshList: () => any
    keyword: Ref<string>
  }>({ isMaster, key: 'activity' })

根组件

const { registerFunc, funcs } = useActivity({ isMaster: true })

const list = ref([])
const freshList = function() {
  list.value = totalList.filter(item => item.name === funcs.keyword.value)
}
registerFunc({ freshList })

子组件

const { funcs, registerFunc } = useActivity()

// 反向注册自己的能力
registerFunc({ 
  keyword: ref('')
})

// 点击搜索按钮,触发列表刷新
const onSearch = function () {
  funcs.freshList()
}

注意:master 必须是祖先,否则拿到空对象且不报错;子组件别误传 isMaster: true

三、实现原理

核心只有十几行:

export const useCompExp = function <T>({ isMaster = true, key = 'compExp' } = {} as any) {
  if (isMaster) {
    const funcs = {} as T
    const registerFunc = funcList => Object.assign(funcs, funcList)
    provide(key, { funcs, registerFunc })
    return { funcs, registerFunc }
  }
  const { funcs, registerFunc } = inject(key, { funcs: {}, registerFunc: () => {} })
  return { funcs, registerFunc } as { funcs: T; registerFunc: (f: Partial<T>) => any }
}

要点:

结语

把它当 Pinia 的补充:全局状态交给 Pinia,组件树内的能力互通交给 useCompExp。