<template>
<div class="content">
<div class="text" :class="[isAll ? props.longClass : '']">
<label for="exp" class="btn" v-if="showCtro" @click.stop="isAll = !isAll">
<span class="words">{{ isAll ? '展开' : '收起' }}</span>
</label>
<span ref="reportText" v-html="textHtml" />
</div>
</div>
</template>
<script setup>
import { defineComponent, ref, watch, onMounted, nextTick } from 'vue'
const props = defineProps({
text: {
type: String,
default: ''
},
textHtml: {
type: String,
default: ''
},
longClass: {
type: String,
default: 'long'
}
})
const showCtro = ref(false)
const isAll = ref(false)
const reportText = ref('')
const classObj = ref({
long: 75
})
watch(
() => props.text,
async () => {
isAll.value = false
showCtro.value = false
await nextTick()
const key = props.longClass
if (props.text) {
showCtro.value = isAll.value = reportText.value?.offsetHeight > classObj.value[key]
}
},
{
immediate: true
}
)
</script>
<style lang="less" scoped>
.content {
height: 100%;
display: flex;
}
.text {
width: 100%;
color: #333;
font-size: 14px;
}
.long {
height: 64px;
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
.btn {
float: right;
clear: both;
margin-right: 8px;
color: #514def;
cursor: pointer;
}
.text::before {
content: '';
float: right;
width: 0;
height: calc(100% - 20px);
}
.exp:checked + .text {
-webkit-line-clamp: 999; /*设置一个足够大的行数就可以了*/
}
</style>
实现思路:
1、 利用css样式让展开收起按钮浮动后,与文本处在同一个空间内
2、通过动态样式,来切换展开和收起的不同文本样式和高度