Skip to content

监听插槽存在 useSlotsExist

监听给定名称或名称数组的插槽是否存在,支持监听单个插槽或一组插槽的存在

Show Source Code
ts
/**
 * 组合式函数
 * 监听给定名称或名称数组的插槽是否存在,支持监听单个插槽或一组插槽的存在
 * 
 * @param slotsName - 插槽的名称或名称数组,默认为 'default'
 * @returns 如果是单个插槽名称,则返回一个计算属性,表示该插槽是否存在
 *          如果是插槽名称数组,则返回一个 reactive 对象,其中的每个属性对应该插槽是否存在
 */
import { useSlots, reactive, computed } from 'vue'
export function useSlotsExist(slotsName: string | string[] = 'default') {
  const slots = useSlots() // 获取当前组件的所有插槽
  // 检查特定名称的插槽是否存在且不为空
  const checkSlotsExist = (slotName: string): boolean => {
    const slotsContent = slots[slotName]?.()
    const checkExist = (slotContent: any) => {
      if (typeof slotContent.children === 'string') {
        // 排除 v-if="false" 的插槽内容
        if (slotContent.children === 'v-if') {
          return false
        }
        return slotContent.children.trim() !== ''
      } else {
        if (slotContent.children === null) {
          if (slotContent.type === 'img' || typeof slotContent.type !== 'string') {
            return true
          }
        } else {
          return Boolean(slotContent.children)
        }
      }
    }
    if (slotsContent && slotsContent?.length) {
      const result = slotsContent.some((slotContent) => {
        return checkExist(slotContent)
      })
      return result
    }
    return false
  }
  if (Array.isArray(slotsName)) {
    const slotsExist = reactive<any>({})
    slotsName.forEach((slotName: string) => {
      const exist = computed(() => checkSlotsExist(slotName))
      slotsExist[slotName] = exist // 将一个 ref 赋值给一个 reactive 属性时,该 ref 会自动解包
    })
    return slotsExist
  } else {
    return computed(() => checkSlotsExist(slotsName))
  }
}

基本使用

vue
<script setup lang="ts">
import { ref } from 'vue'
import { useSlotsExist } from 'vue-amazing-ui'

// 监听单个插槽的存在
const slotsDefaultExist = useSlotsExist() // 等同于 useSlotsExist('default')
const slotsHeaderExist = useSlotsExist('header')
watchEffect(() => {
  console.log('slotsDefaultExist', slotsDefaultExist.value)
  console.log('slotsHeaderExist', slotsHeaderExist.value)
})

// 监听一组插槽的存在
const slotsExist = useSlotsExist(['default', 'header'])
watchEffect(() => {
  console.log('default', slotsExist.default)
  console.log('header', slotsExist.header)
})
</script>
<template>
  <div>
    <slot>{{ defaultContent }}</slot>
    <slot name="header">{{ headerContent }}</slot>
  </div>
</template>

Params

参数说明类型默认值
slotsName插槽的名称或名称数组string | string[]'default'

Released under the MIT License.