在系统中,内容过长需要省略,鼠标移上显示全部,这个是常用的功能,也有很多方案解决这种。
单行内容超出处理
常用的css方案:
css
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
该样式在宽度有限制的情况下使用,超出容器宽度的文本将被隐藏,并显示省略号。
注意flex布局flex:1的时候,需要设置min-width:0,否则无效;
但是实际情况下,系统希望超出部分,在鼠标移上显示全部,这时候可能就需要el-tooltip、title、或者popup处理,鼠标移上显示,但是这样会导致,没有超出的情况,鼠标经过也会有提示,不完美。
改进版本方案:
xml
<template>
<el-tooltip effect="light" :content="content" placement="top" :disabled="isDisabled">
<div class="cm-tooltip" @mouseover="mouseoverHandle">
<span ref="contentRef">{{ content }}</span>
</div>
</el-tooltip>
</template>
<script>
export default {
props: {
content: [String, Number],
},
data() {
return {
isDisabled: false,
};
},
methods: {
mouseoverHandle() {
const parentWidth = this.$refs.contentRef.parentNode.offsetWidth;
const width = this.$refs.contentRef.offsetWidth;
this.isDisabled = width <= parentWidth;
},
},
};
</script>
通过一个全局组件,来是现实,使用类似el-tooltip,方便简单。
通过行内元素(span)不能设置高宽,高宽是根据它实际内容撑起来的,如果内容超出,其宽度一定会比实际父元素(块元素)宽度大,所以能实现,超出时才有tooltip,没超出就隐藏tooltip;
编辑
多行内容超出处理
常用的css方案:
css
.ellipsis-line-2 {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
line-break: anywhere;
-webkit-box-orient: vertical;
}
主要通过-webkit-line-clamp处理,超出多行;
改进方案
xml
<template>
<el-tooltip effect="light" :content="content" placement="top" :disabled="isDisabled">
<div class="cm-two-tooltip" @mouseover="mouseoverHandle">
<span ref="contentRef">{{ content }}</span>
</div>
</el-tooltip>
</template>
<script>
export default {
props: {
content: [String, Number],
},
data() {
return {
isDisabled: false,
};
},
methods: {
mouseoverHandle() {
const parentHeight = this.$refs.contentRef.parentNode.offsetHeight;
const height = this.$refs.contentRef.offsetHeight;
this.isDisabled = height <= parentHeight ;
},
},
};
</script>
这个方案跟单行改进方案思路一样,只是多行需要用到了高度来处理。
带查看全部按钮
xml
<script setup>
import { ref, watch, nextTick } from 'vue';
const props = defineProps({
chanceData: { type: Array, default: () => [] },
});
const chanceContainer = ref(null);
const showViewBtn = ref(false);
const moreHandler = () => {
let height = chanceContainer.value.scrollHeight;
if (height > 106) {
showViewBtn.value = true;
} else {
showViewBtn.value = false;
}
};
watch(
() => props.chanceData,
() => {
nextTick(() => {
moreHandler();
});
},
{ immediate: true }
);
</script>
<template>
<div class="chance-item" :class="{ 'chance-border': chanceData.length }" ref="chanceContainer">
<div v-for="item in chanceData" class="chance-li">{{ item.name }}</div>
<div class="view-btn" v-popover:chancePopover v-show="showViewBtn">查看全部</div>
<el-popover ref="chancePopover" width="600" trigger="click">
<div v-for="item in chanceData" class="chance-li">{{ item.name }}</div>
</el-popover>
</div>
</template>
<style scoped lang="less">
.chance-item {
height: 104px;
padding: 9px 12px;
overflow: hidden;
position: relative;
&.chance-border {
border: 1px solid #dcdee0;
border-radius: 2px;
}
}
.view-btn {
position: absolute;
color: #3874c5;
background-color: #fff;
right: 12px;
bottom: 9px;
cursor: pointer;
}
.chance-li {
position: relative;
padding-left: 12px;
line-height: 22px;
&::before {
content: '';
position: absolute;
background-color: #595f6d;
width: 6px;
height: 6px;
border-radius: 50%;
left: 0;
top: 8px;
}
}
</style>
编辑
实现思路也是一致,也是通过css和js判断来实现!
大家有更好更优雅的方案,欢迎给我提意见