![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7cf4d2caf8f146109a487b158ac50813.png)
APIs
Ellipsis
参数 | 说明 | 类型 | 默认值 | 必传 |
---|
maxWidth | 文本最大宽度 | number | string | ‘100%’ | false |
line | 最大行数 | number | undefined | false |
expand | 是否启用点击文本展开全部 | boolean | false | false |
tooltip | 是否启用文本提示框 | boolean | true | false |
tooltipProps | tooltip 组件属性配置,参考 Tooltip Props | object | {} | false |
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?: number | string
line?: number
expand?: boolean
tooltip?: boolean
tooltipProps?: object
}
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"
:overlayStyle="{ 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', { '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', { '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;
}
.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="{
fontSize: 16,
backgroundColor: '#4096ff',
overlayStyle: { padding: '12px 16px', borderRadius: '12px' }
}"
>
住在我心里孤独的 孤独的海怪 痛苦之王 开始厌倦 深海的光 停滞的海浪
</Ellipsis>
</div>
</template>