APIs
Ellipsis
参数 |
说明 |
类型 |
默认值 |
maxWidth |
文本最大宽度,单位 px |
number | string |
‘100%’ |
line |
最大行数 |
number |
undefined |
expand |
是否启用点击文本展开全部 |
boolean |
false |
tooltip |
是否启用文本提示框 |
boolean |
true |
tooltipProps |
Tooltip 组件属性配置,参考 Tooltip Props |
object |
{} |
Events
名称 |
说明 |
类型 |
expandChange |
点击文本展开收起时的回调 |
(expand: boolean) => void |
创建文本省略组件Ellipsis.vue
其中引入使用了以下组件和工具函数:
<script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import Tooltip from '../tooltip'
import { useResizeObserver } from '../utils'
interface Props {
maxWidth?: string | number // 文本最大宽度,单位 px
line?: number // 最大行数
expand?: boolean // 是否启用点击文本展开全部
tooltip?: boolean // 是否启用文本提示框
tooltipProps?: object // Tooltip 组件属性配置,参考 Tooltip Props
}
const props = withDefaults(defineProps<Props>(), {
maxWidth: '100%',
line: undefined,
expand: false,
tooltip: true,
tooltipProps: () => ({})
})
const showTooltip = ref(false) // 是否显示提示框
const showExpand = ref(false) // 是否可以启用点击展开
const ellipsisRef = ref()
const defaultTooltipMaxWidth = ref()
const textMaxWidth = computed(() => {
if (typeof props.maxWidth === 'number') {
return props.maxWidth + 'px'
}
return props.maxWidth
})
watch(
() => [props.maxWidth, props.line, props.tooltip],
() => {
if (props.tooltip) {
showTooltip.value = getTooltipShow()
}
},
{
deep: true,
flush: 'post'
}
)
useResizeObserver(ellipsisRef, () => {
if (props.tooltip) {
showTooltip.value = getTooltipShow()
}
})
onMounted(() => {
if (props.tooltip) {
showTooltip.value = getTooltipShow()
}
})
function getTooltipShow() {
const scrollWidth = ellipsisRef.value.scrollWidth
const scrollHeight = ellipsisRef.value.scrollHeight
const clientWidth = ellipsisRef.value.clientWidth
const clientHeight = ellipsisRef.value.clientHeight
if (scrollWidth > clientWidth || scrollHeight > clientHeight) {
defaultTooltipMaxWidth.value = ellipsisRef.value.offsetWidth + 24
if (props.expand) {
showExpand.value = true
}
return true
} else {
if (props.expand) {
showExpand.value = false
}
return false
}
}
const emit = defineEmits(['expandChange'])
function onExpand() {
if (ellipsisRef.value.style['-webkit-line-clamp']) {
if (props.tooltip) {
showTooltip.value = false
nextTick(() => {
ellipsisRef.value.style['-webkit-line-clamp'] = ''
})
} else {
ellipsisRef.value.style['-webkit-line-clamp'] = ''
}
emit('expandChange', true)
} else {
if (props.tooltip) {
showTooltip.value = true
}
ellipsisRef.value.style['-webkit-line-clamp'] = props.line
emit('expandChange', false)
}
}
</script>
<template>
<Tooltip
v-if="showTooltip"
:max-width="defaultTooltipMaxWidth"
:tooltip-style="{ padding: '8px 12px', textAlign: 'justify' }"
v-bind="tooltipProps"
>
<template #tooltip>
<slot name="tooltip">
<slot></slot>
</slot>
</template>
<div
ref="ellipsisRef"
class="m-ellipsis"
:class="[line ? 'ellipsis-line' : 'not-ellipsis-line', { 'ellipsis-cursor-pointer': showExpand }]"
:style="`-webkit-line-clamp: ${line}; max-width: ${textMaxWidth};`"
@click="showExpand ? onExpand() : () => false"
v-bind="$attrs"
>
<slot></slot>
</div>
</Tooltip>
<div
v-else
ref="ellipsisRef"
class="m-ellipsis"
:class="[line ? 'ellipsis-line' : 'not-ellipsis-line', { 'ellipsis-cursor-pointer': showExpand }]"
:style="`-webkit-line-clamp: ${line}; max-width: ${textMaxWidth};`"
@click="showExpand ? onExpand() : () => false"
v-bind="$attrs"
>
<slot></slot>
</div>
</template>
<style lang="less" scoped>
.m-ellipsis {
overflow: hidden;
cursor: text;
}
.ellipsis-line {
display: -webkit-inline-box;
-webkit-box-orient: vertical;
}
.not-ellipsis-line {
display: inline-block;
vertical-align: bottom;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-cursor-pointer {
cursor: pointer;
}
</style>
在要使用的页面引入
<script setup lang="ts">
import Ellipsis from './Ellipsis.vue'
</script>
<template>
<div>
<h1>{
{ $route.name }} {
{ $route.meta.title }}</h1>
<h2 class="mt30 mb10">基本使用</h2>
<Ellipsis :maxWidth="240">住在我心里孤独的 孤独的海怪 痛苦之王 开始厌倦 深海的光 停滞的海浪</Ellipsis>
<h2 class="mt30 mb10">多行省略</h2>
<Ellipsis :line="2">
电灯熄灭 物换星移 泥牛入海
<br />
黑暗好像 一颗巨石 按在胸口
<br />
独脚大盗 百万富翁 摸爬滚打
<br />
黑暗好像 一颗巨石 按在胸口
</Ellipsis>
<h2 class="mt30 mb10">点击展开</h2>
<Ellipsis expand :line="2">
电灯熄灭 物换星移 泥牛入海
<br />
黑暗好像 一颗巨石 按在胸口
<br />
独脚大盗 百万富翁 摸爬滚打
<br />
黑暗好像 一颗巨石 按在胸口
</Ellipsis>
<h2 class="mt30 mb10">定制 Tooltip 内容</h2>
<Ellipsis :max-width="240">
住在我心里孤独的 孤独的海怪 痛苦之王 开始厌倦 深海的光 停滞的海浪
<template #tooltip>
<div style="text-align: center">
《秦皇岛》
<br />
住在我心里孤独的
<br />
孤独的海怪 痛苦之王
<br />
开始厌倦 深海的光 停滞的海浪
</div>
</template>
</Ellipsis>
<h2 class="mt30 mb10">自定义 Tooltip 样式</h2>
<Ellipsis
:max-width="240"
:tooltip-props="{
bgColor: '#4096ff',
tooltipStyle: {
padding: '12px 16px',
borderRadius: '12px',
fontSize: '16px',
backgroundColor: '#4096ff'
}
}"
>
住在我心里孤独的 孤独的海怪 痛苦之王 开始厌倦 深海的光 停滞的海浪
</Ellipsis>
</div>
</template>