实现效果
代码片段
<div class="app-extend-card-content">
<div
:class="['text', textClassName]"
ref="textRef"
>
<span
class="other"
v-if="textClassName === 'outer' && props.text"
@click="otherShow(true)"
>【展开】</span>
<span
class="other"
v-if="textClassName === 'inner' && oShow && props.text"
@click="otherShow(false)"
>【收起】</span>
{{ props.text }}
</div>
</div>
注意点: 按钮需要放在文本之前
.app-extend-card-content {
width: 100%;
padding: 20px 25px;
box-sizing: border-box;
background-color: #fff;
display: flex;
.text {
font-size: 26px;
font-weight: 400;
color: #666666;
line-height: 36px;
margin: 0;
&::before{
content: '';
float: right;
width: 0px;
height: calc(100% - 33px);
background: red
}
&.outer {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;//控制行数
-webkit-box-orient: vertical;
line-height: 36px;
}
&.inner {
display: block;
oveflow: auto;
}
.other {
float: right;
clear: both;
font-size: 26px;
font-weight: 400;
color: rgba(31, 126, 255, 1);
line-height: 36px;
margin: 0;
}
}
}
display: -webkit-box;存在浏览器的兼容问题在safair和火狐上会出现文本不现实的问题,解决方案如下
&.outer {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
//display: -webkit-box;
//-webkit-line-clamp: 2;//控制行数
//-webkit-box-orient: vertical;
line-height: 36px;
max-height: 72px;
.other::before {
content: '...';
font-size: 26px;
font-weight: 400;
color: #666666;
line-height: 36px;
}
}
设置内容的最大高度,做到限制行数,省略号使用给按钮添加伪元素来实现
const textRef = ref(null)
const oShow = ref(false)
const textClassName = computed(() => {
if(oShow.value === false && (textRef.value?.offsetHeight / 20) > 2) {
return 'outer'
}
return 'inner'
})
function otherShow(bol) {
oShow.value = bol
}
完成代码
<template>
<div class="app-extend-card">
<div class="app-extend-card-header">
<div class="header-box">
<p class="title">{{ props.title }}</p>
</div>
</div>
<div class="app-extend-card-content">
<div
:class="['text', textClassName]"
ref="textRef"
>
<span
class="other"
v-if="textClassName === 'outer' && props.text"
@click="otherShow(true)"
>【展开】</span>
<span
class="other"
v-if="textClassName === 'inner' && oShow && props.text"
@click="otherShow(false)"
>【收起】</span>
{{ props.text }}
</div>
</div>
<div class="app-extend-card-footer">
<div class="time" />
<div class="grade">--</div>
</div>
</div>
</template>
<script>
export default {
name: 'AppExtendCard'
}
</script>
<script setup>
import {ref, computed} from 'vue'
const props = defineProps({
title: {
type: String,
default: '--'
},
text: {
type: String,
default: '--'
}
})
const textRef = ref(null)
const oShow = ref(false)
const textClassName = computed(() => {
if(oShow.value === false && (textRef.value?.offsetHeight / 20) > 2) {
return 'outer'
}
return 'inner'
})
function otherShow(bol) {
oShow.value = bol
}
</script>
<style lang='scss'>
.app-extend-card{
width: 100%;
border-radius: 20px;
overflow: hidden;
.app-extend-card-header {
width: 100%;
background-color: #fff;
.header-box {
width: calc(100% - 50px);
height: 80px;
border-bottom: 1px solid #ccc;
padding: 20px 0 0;
margin-left: 25px;
box-sizing: border-box;
.title {
font-size: 30px;
font-weight: 400;
color: #333333;
line-height: 40px;
margin: 0;
}
}
}
.app-extend-card-content {
width: 100%;
padding: 20px 25px;
box-sizing: border-box;
background-color: #fff;
display: flex;
.text {
font-size: 26px;
font-weight: 400;
color: #666666;
line-height: 36px;
margin: 0;
&::before{
content: '';
float: right;
width: 0px;
height: calc(100% - 33px);
background: red
}
&.outer {
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
//display: -webkit-box;
//-webkit-line-clamp: 2;//控制行数
//-webkit-box-orient: vertical;
line-height: 36px;
max-height: 72px;
.other::before {
content: '...';
font-size: 26px;
font-weight: 400;
color: #666666;
line-height: 36px;
}
}
&.inner {
display: block;
oveflow: auto;
}
.other {
float: right;
clear: both;
font-size: 26px;
font-weight: 400;
color: rgba(31, 126, 255, 1);
line-height: 36px;
margin: 0;
}
}
}
.app-extend-card-footer {
width: 100%;
height: 80px;
background-color: #fbfbfb;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 25px;
box-sizing: border-box;
position: relative;
&:before {
content: '';
display: inline-block;
width: 30px;
height: 30px;
background-color: #e7e8ea;
border-radius: 15px;
position: absolute;
left: 0;
top: 0;
transform: translate(-50%, -50%);
}
&:after{
content: '';
display: inline-block;
width: 30px;
height: 30px;
background-color: #e7e8ea;
border-radius: 15px;
position: absolute;
right: 0;
top: 0;
transform: translate(50%, -50%);
}
.grade {
font-size: 36px;
font-weight: 400;
color: #0C7E00;
line-height: 40px;
}
}
}
</style>