<template>
<component
:is="tag"
ref="_ref"
v-bind="_props"
:class="buttonKls"
:style="buttonStyle"
@click="handleClick"
>
<!-- 优先级 1: 如果用户提供了 loading 插槽,用插槽内容 -->
<template v-if="loading">
<slot v-if="$slots.loading" name="loading" />
<!-- 优先级 2: 否则使用 loadingIcon(可以是默认的,也可以是用户自定义的) -->
<el-icon v-else :class="ns.is('loading')">
<component :is="loadingIcon" />
</el-icon>
</template>
<el-icon v-else-if="icon || $slots.icon">
<component :is="icon" v-if="icon" />
<slot v-else name="icon" />
</el-icon>
<span
v-if="$slots.default"
:class="{ [ns.em('text', 'expand')]: shouldAddSpace }"
>
<slot />
</span>
</component>
</template>
本文主要分析以下代码
<span
v-if="$slots.default"
:class="{ [ns.em('text', 'expand')]: shouldAddSpace }"
>
<slot />
</span>
// :class="{ [ns.em('text', 'expand')]: shouldAddSpace }"
// 即 :class="{el-button__text--expand: shouldAddSpace}"
// 其中shouldAddSpace是一个Boolean类型
shouldAddSpace来自于:
const {
_ref,
_size,
_type,
_disabled,
_props,
_plain,
_round,
_text,
shouldAddSpace,
handleClick,
} = useButton(props, emit)
useButton中shouldAddSpace是一个computed计算属性
// add space between two characters in Chinese
const shouldAddSpace = computed(() => {
// 获取默认插槽内容
const defaultSlot = slots.default?.()
console.log('defaultSlot',defaultSlot)
// 检查是否启用自动加空格
// autoInsertSpace(来自 prop 或全局配置)
// defaultSlot?.length === 1 插槽只有一个节点
if (autoInsertSpace.value && defaultSlot?.length === 1) {
const slot = defaultSlot[0]
// 检查是否是纯文本节点
if (slot?.type === Text) {
const text = slot.children as string
// 检查是否是两个中文字符
return /^\p{Unified_Ideograph}{2}$/u.test(text.trim())
}
}
return false
})
shouldAddSpace:当 shouldAddSpace 为 true 时,会添加 el-button__text--expand 类名,CSS 会在两个中文字符之间添加空格。
<el-button auto-insert-space>提交</el-button> // 添加空格
<el-button auto-insert-space>提交表单</el-button> // 不添加
<el-button auto-insert-space>OK</el-button> // 英文或数字 不添加
hooks useSlots()
<div class="play-container">
<el-button auto-insert-space>
<template #loading>加载中...</template>
<template #icon>🚀</template>
提交手册
</el-button>
</div>
import { useSlots } from 'vue'
const slots = useSlots()
console.log('slots', slots)