文本溢出移入Tooltip提示,我的LeText组件

前言

项目中产品有这么个要求,有些文字展示单行/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.文本超出设定的最多行数判断

  • 可以通过 触发元素的 clientHeightscrollHeight 高度比较

具体实现

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...

相关推荐
大龄大专大前端1 小时前
JavaScript闭包的认识/应用/原理
前端·javascript·ecmascript 6
字节源流1 小时前
【SpringMVC】常用注解:@SessionAttributes
java·服务器·前端
Json____1 小时前
SpringBoot 和vue前后端配合开发网页拼图10关游戏源码技术分享
vue.js·spring boot·游戏·html·游戏机·拼图游戏·拼图小游戏
肥肠可耐的西西公主1 小时前
前端(vue)学习笔记(CLASS 4):组件组成部分与通信
前端·vue.js·学习
烛阴1 小时前
JavaScript 函数绑定:从入门到精通,解锁你的代码超能力!
前端·javascript
花椒和蕊1 小时前
【vue+excel】导出excel(目前是可以导出两个sheet)
javascript·vue.js·excel
泫凝1 小时前
使用 WebP 优化 GPU 纹理占用
前端·javascript
magic 2451 小时前
CSS块元素、行内元素、行内块元素详解
前端·css
returnShitBoy2 小时前
前端面试:React hooks 调用是可以写在 if 语句里面吗?
前端·javascript·react.js
love黄甜心2 小时前
Sass:深度解析与实战应用
前端·css·sass