前端界面中存在展开收起功能,dome高度超过100px,前端展示展开收起功能。收起->100px,展开->自适应高度;dome高度小于100px,不展示操作按钮。dome高度存在动态变化的可能
<template>
<div class="content">
<div class="info-box" v-for="(item, index) in list" :key="index" :class="{'min-box':!item.expend}">
<p ref="info-container" :data-id="item.id">{{item.label}}</p>
</div>
<div class="more-btn" v-if="moreState[item.id]" :key="index" @click="changeExpend(id)">
{{item.expend ? "收起" : "展开"}}
<i :class="item.expend ? 'icon-up' : 'icon-down'"></i>
</div>
</div>
</template>
<script>
export default {
name:"",
components:{},
props:{
list:{
required:true,
type:Array
}
},
data(){
return {
moreState:{}
}
},
mounted(){
this.handleUnfold();
},
updated(){
this.handleUnfold();
},
methods:{
handleUnfold(){
this.$refs["info-container"] && this.$refs["info-container"].forEach(item=>{
if(item.scrollHeight && item.attributes && item.attributes["data-id"] && item.attributes["data-id"].value){
this.$set(this.moreState, item.attributes["data-id"].value, item.scrollHeight > 100)
}
})
},
changeExpend(id){
this.list = this.list.map(item=>{
if(item.id === id){
item.expend = !item.expend;
}
return item;
})
}
}
}
</script>
<style scoped lang="less">
.info-box{
&.min-box{
max-height: 100px;
overflow: hidden;
}
}
</style>
首次渲染完成进入钩子mounted,对dome高度进行判断,并修改moreState,调用vue函数this.$forceUpdate()更新dome,并保存原始状态orginState
界面存在更新,导致dome高度变化触发钩子updated,对dome高度判断,并修改moreState,与原本保存的orginState进行比对(避免重复触发updated),若存在变化则moreState赋值orginState,调用函数this.$forceUpdate()更新dome
该示例用于vue2.0+;vue3.0+无需手动触发更新, 当moreState改变时,vue3.0将直接触发dome渲染
单个展开收起不需要列表
<div class="page_info" :style="isFold ? 'height:auto':''" ref="container" data-id="itemdata">
<span v-html="tip" :class=" ShowFold&&!isFold ?'isActived userTip' :'userTip'"></span>
</div>
<div class="unfold" @click="expandFun" v-if="ShowFold" >
<div v-if="!isFold">
<span>展开</span>
<img src="../../../../assets/fold.png" alt="">
</div>
<div v-if="isFold">
<span>收起</span>
<img src="../../../../assets/unfold.png" alt="" class="icon2">
</div>
</div>
export default {
data() {
return {
isFold:false,
ShowFold:false,
}
},
mounted(){
this.handleUnfold();
},
updated(){
this.handleUnfold();
},
methods:{
handleUnfold(){
if(this.$refs.container.scrollHeight > 105){
this.ShowFold = true
}
},
expandFun(){
this.isFold = !this.isFold
},
}
}
<style lang="scss">
.isActived{ //盒子中内容竖直排列
white-space: normal;
word-break: break-word;
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
}
.page_info{
height: 4.5rem;
overflow: hidden;
}
.userTip{
font-size: 0.6rem;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #9DA0A3;
line-height: 0.85rem;
}
.unfold{
display: flex;
justify-content: center;
padding: 0.98rem 0 0.73rem 0rem;
span{
font-size: 0.6rem;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #389CFF;
}
img{
margin: 0.17rem 0rem 0.13rem 0rem;
width: 0.51rem;
height: 0.34rem;
}
.icon2{
transform: rotate(180deg);
}
}
</style>