Skip to the content.

useCompExp: Data Sharing Within a Vue Component Tree

useCompExp is built on Vue’s provide / inject to share data and methods within a component tree, simplifying typescript types and eliminating the need to pass props / emit down through every level.

1. Difference from Pinia

2. Basic Usage

Use useCompExp to declare the type.

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

Root component

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

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

Child component

const { funcs, registerFunc } = useActivity()

// Register your own capabilities back to the master
registerFunc({ 
  keyword: ref('')
})

// Click the search button to trigger a list refresh
const onSearch = function () {
  funcs.freshList()
}

Note: the master must be an ancestor, otherwise you get an empty object without any error; also, child components should not pass isMaster: true by mistake.

3. Implementation Principle

The core is only a dozen or so lines:

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 }
}

Key points:

Conclusion

Treat it as a complement to Pinia: leave global state to Pinia, and hand over capability exchange within a component tree to useCompExp.