前言
项目中产品有这么个要求,有些文字展示单行/2/3行,超出隐藏,鼠标移入想要知道看全文本全部信息,有时候这个文本信息还想要支持复制粘贴 类似这样的一个实现
分析
提示: 由于实现的项目主要用的element-plus库, 后面的实现可能会用到element-plus 的组件,如果是其他组件库 可以做相关替换
1.n行显示溢出控制
scss
// 单行文本超出 用以下样式即可
.text-overflow_ellipsis {
overflow: hidden; /* 隐藏超出元素框的内容 */
text-overflow: ellipsis; /* 文本溢出时,使用省略号(...)表示溢出的文本 */
white-space: nowrap; /* 设置文本不换行 */
}
// 多行文本超出 可以使用以下样式
.text-overflow_ellipsis_line($line: 2) {
white-space: normal; // 允许内容自然换行
text-overflow: -o-ellipsis-lastline; // 仅适用于旧版本浏览器,指定最后一行文本溢出显示省略号
overflow: hidden; // 隐藏超出容器的内容
text-overflow: ellipsis; // 文本溢出时显示省略号(此设置实际在多行文本中不起作用,主要是用于单行)
display: -webkit-box; // 作为弹性伸缩盒子模型显示。
-webkit-box-orient: vertical; // 设置伸缩盒子的子元素排列方式--从上到下垂直排列
-webkit-line-clamp: $line; // 显示的最大行数
word-break: break-all; // 允许单词在任何字符间断行
}
2.复制文案
ts
/**
* 复制文字
* @param val
* @param sucTxt
* @returns {boolean}
*/
export function copyText(val: string, sucTxt = '复制成功~') {
const textarea: any = document.createElement('textarea')
// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
textarea.readOnly = 'readonly'
textarea.style.position = 'absolute'
textarea.style.left = '-9999px'
textarea.value = val
document.body.appendChild(textarea)
textarea.select()
const res = document.execCommand('copy')
document.body.removeChild(textarea)
if (res) {
ElMessage.success(sucTxt)
}
return res
}
3.文本超出设定的最多行数判断
- 可以通过 触发元素的
clientHeight
和scrollHeight
高度比较
具体实现
html
<template>
<section class="le-text-wrap" ref="textTooltipRef">
<el-tooltip v-if="value" :visible="isShowTooltip" :placement="placement">
<template #content>
<span>{{ value }}</span>
</template>
<div class="le-text" @mouseover="handleElTooltip" @mouseleave="isShowTooltip = false">
<slot>
<el-text v-bind="textProps" class="text-overflow_ellipsis_line_2" :style="textStyle">{{ value }}</el-text>
</slot>
<!-- 复制按钮 -->
<el-icon class="action-icon" v-if="copy">
<DocumentCopy @click.stop="copyText(value)" />
</el-icon>
</div>
</el-tooltip>
<span v-else>-</span>
</section>
</template>
ts
<script lang="ts" setup name="LeText">
import { computed, ref } from 'vue'
import type { PropType } from 'vue'
import { copyText } from '@/utils'
defineOptions({ name: 'LeText' })
const props = defineProps({
value: {
type: String,
default: ''
},
copy: {
type: Boolean,
default: false
},
// tooltip 配置
placement: {
type: String,
default: 'top'
},
// text 配置
lineClamp: {
type: [String, Number],
default: 1
},
type: {
type: String as PropType<'primary' | 'success' | 'warning' | 'danger' | 'info'>
},
tag: {
type: String,
default: 'span'
}
})
const textProps = computed(() => {
const { lineClamp, type, tag } = props
return {
lineClamp,
type,
tag
}
})
const textStyle = computed((): string => {
const lineClamp = +props.lineClamp || 1
return `line-clamp: ${lineClamp}; -webkit-line-clamp: ${lineClamp}`
})
const textTooltipRef = ref()
const visible = ref(false)
const isShowTooltip = ref(false)
function handleElTooltip(e: any): void {
const base: number = textTooltipRef.value.clientHeight
isShowTooltip.value = e.target.scrollHeight > base
}
</script>
scss
// Text 样式
.le-text {
//font-size: 14px;
font-size: var(--el-font-size-base);
display: inline-flex;
&-wrap {
}
.action-icon {
margin-left: 2px;
padding-top: 4px;
//color: var(--el-color-primary);
color: var(--el-text-color-secondary);
cursor: pointer;
&:hover {
//color: var(--el-color-primary-light-5);
color: var(--el-color-primary);
}
}
}
.text-overflow_ellipsis_line_2 {
white-space: normal;
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
word-break: break-all;
}
以上就是完整的LeText组件逻辑
组件文件地址: src/components/Text.vue
项目源代码参考下面推荐
推荐
分享给大家一个Vue3 + Ts + Element-plus & Vite
搭建,开箱即用的后台管理项目, 手机端已兼容,如果觉得不错希望可以得到各位大佬的star
项目链接 github.com/LanceJiang/...
访问链接 lancejiang.github.io/Lance-Eleme...