Skip to content

Vue中关于HOC的实现:使用defineComponent,然后使用provide和inject来实现,最后return一个h函数;

ts
export function withConfigProvider(App: Component) {
  return defineComponent({
    name: 'ConfigProvider',
    setup(_, { slots }) {
      const { theme, localeIndex } = useData()
      const config = computed(() => resolveConfig(theme.value, localeIndex.value))

      provide(configSymbol, config)

      const activeTag = ref<Theme.activeTag>({
        label: '',
        type: ''
      })
      provide(activeTagSymbol, activeTag)

      const pageNum = ref(1)
      provide(currentPageNum, pageNum)

      const mode = useColorMode({
        attribute: 'theme',
        modes: {
          // 内置的颜色主题
          'vp-default': 'vp-default',
          'vp-green': 'vp-green',
          'vp-yellow': 'vp-yellow',
          'vp-red': 'vp-red',
          'el-blue': 'el-blue',
          'el-yellow': 'el-yellow',
          'el-green': 'el-green',
          'el-red': 'el-red'
        }
      })
      watch(config, () => {
        mode.value = config.value.blog?.themeColor ?? 'vp-default'
      }, {
        immediate: true
      })

      return () => h(App, null, slots)
    }
  })
}

相关知识:

h 函数是 Vue 3 中的渲染函数(render function),用于创建虚拟 DOM 节点(VNode)。它是 createElement 的简写(hyperscript 的简写)。

ts
// 完整参数签名
function h(
  type: string | Component,
  props?: object | null,
  children?: Children | Slot | Slots
): VNode

// 省略 props
function h(type: string | Component, children?: Children | Slot): VNode

type Children = string | number | boolean | VNode | null | Children[]

type Slot = () => Children

type Slots = { [name: string]: Slot }
ts
// 默认插槽
h(MyComponent, null, {
  default: () => h('div', null, 'Default slot content')
})

// 具名插槽
h(MyComponent, null, {
  header: () => h('div', null, 'Header content'),
  footer: () => h('div', null, 'Footer content')
})
本站访客数 人次 本站总访问量