最近接触拉了一个项目,使用到 element-plus 中 el-collapse 折叠面板,发现在使用中利用高官网多多少少的会出现问题。
(1.直接默认一个展开值,发现时显时不显
2 . 数据渲染问题,接口请求了,页面数据不更新
3 样式问题,自定义表头title等等)
我们的数据结构是双数组,如果你和我一样直接copy, 如果是一个对象数组或者数组吧,只需把外层的数组转化即可
效果图 : 当点击 了查看按钮时,弹框出现,且默认展开第一个数据,且每次的展开或者收起都有对应的样式,可见下图左侧的图样,
我这里还用到了 el-steps ,最外层的 是自己写的样式,因为我一个页面中使用了两次el-steps ,发现样式会有干扰。所以我在最外层的el-steps是自己写的div标签。
注意 的是我们使用 官网说明的 const activeName = ref([]) 数组类型 ,且里面的值使用字符串类型。
当 弹框出现时,调用接口进行处理赋值 activeName,并转成 toString() 字符串,然后默认展开第一项
activeName.value.push(index.toString())
activeName.value = ['0']
在进行处理每个item之间的高和选中样式。
最后在处理点击@change 的事件
// 处理在展开折叠状态
const handleCollapseChange = (val: any) => {
// console.log(val, 'val');
PurchaseInfo.forEach((item:any, index:any)=>{
if(val){
if(val === index.toString()){
item.flagActive = true
item.height = myCollapseRef.value.$el.clientHeight + 20
} else{
item.flagActive = false
item.height = 38
}
}else{
item.flagActive = false
item.height = 38
}
})
// console.log(PurchaseInfo, 'PurchaseInfo')
}
上代码了。
<ProcessViewDialog
v-model:value="dialogFormVisible"
:projectDeviceId="projectDeviceId"
/>
自己 引入组件
<template>
<div>
<zmjDialog
v-model="show"
width="460"
@opened="init"
title="查看所有设备"
center
>
<div style="display:flex; width: 460px">
<div class="el-dialog-div">
<div class="el-dialog_divleft">
<div class=divleftlast v-for="(el, index) in PurchaseInfo" :key="index">
<p :class="el.flagActive ? 'arrdata1Active' : 'arrdata1'"></p>
<p :style="{width: 2 + 'px', height: el.height + 'px', background: '#E8F0FF', borderRadius: '0px 0px 0px 0px', marginLeft: '8px'}"></p>
</div>
</div>
<el-collapse
class="el-collapse-parent"
v-model="activeName"
accordion
@change="handleCollapseChange"
ref="myCollapseRef"
>
<el-collapse-item
v-for="(item, index) in PurchaseInfo"
:key="index"
:name="index.toString()"
style="margin-bottom: 10px;"
ref="itemHeight"
>
<template #title>
<div :class="item.flagActive ? 'headerRightTrue' : 'headerRightFlase'">
<span class="spanFalse"></span>
<div class="itemApproveTimeFalse">
{{ item.approveTime }}
</div>
<div class="top-right">
<div> {{item.operatorName}} <span v-if="item?.nodeId"> ({{item?.nodeId == 120 ? '方案' : ( item?.nodeId == 130 ? '商务活动' : (item?.nodeId == 140 ? '配套' : '' ))}}) </span> </div>
<span :class="item.flagActive ? 'headerRightspan1' : 'headerRightspan2'">{{ activeName.includes(index.toString()) ? '收起' : '展开' }}</span>
</div>
</div>
</template>
<div class="contntDiv">
<div class="contntDiv-1">
<div class="contntDiv-1">
<span class="contntDiv-1-span"> {{item.model}} </span>
<span class="contntDiv-2-span"> {{ item?.supportLabel === 1 ? '标准架型' : (item?.supportLabel === 3 ? '模块架型' : '非标架型')}} </span>
</div>
<div class="contntDiv-1-d"> {{ item?.deviceCount}}架 </div>
</div>
<div class="line"></div>
<div>
<div class="contntDiv-item-left"> 片区 </div>
<div class="contntDiv-item-right"> {{ item?.areaName }} </div>
</div>
<div>
<div class="contntDiv-item-left"> 支架类型 </div>
<div class="contntDiv-item-right"> {{ GET_SUPPORT_TYPE(item?.firstDeviceType) }} - {{ GET_SUPPORT_SECOND_TYPE_NAME(item?.secondDeviceType) }}</div>
</div>
<div>
<div class="contntDiv-item-left"> 图号 </div>
<div class="contntDiv-item-right"> {{item?.standardGroupNo }} </div>
</div>
<div>
<div class="contntDiv-item-left"> 单架重量 </div>
<div class="contntDiv-item-right"> {{ item?.singleWeight}}吨 </div>
</div>
<div>
<div class="contntDiv-item-left"> 支架特征代号 </div>
<div class="contntDiv-item-right"> {{ joinSupportFeatureModel }} </div>
</div>
<div class="contntDiv-item-right-bottom" v-if="item?.supportFeatureModel && item?.supportFeatureModel?.length > 0">
*支架产品型号{{ item?.supportProductModel}}
</div>
</div>
<div class="box-approve" v-if="item?.flowApproveDtoList?.length>0">
<el-steps direction="vertical" :active="1" align-center>
<el-step v-for="(v, i) in item?.flowApproveDtoList" class="my-text" :key="i">
<template #icon>
<div class="titleDiv">
<div class="time">{{ v.updateTime }}</div>
</div>
</template>
<template #title>
<div class="step-icon"></div>
</template>
<template #description>
<div class="descriptionDiv">
<div style="color: #707070; font-size: 14px">
<span class="" style="color: #3076fe">{{ v.approveUserName }}</span>
<!-- approveType 1 提交 2 审批 status 1 未审批 2 审批通过 3 驳回 -->
<span v-if="v.approveType == 1 && v.status == 2 && isLastElement(item?.flowApproveDtoList, i)" style="color: rgba(0, 0, 0, 0.56)"><span style="color: #262626">提交审批</span></span>
<span v-else>
<span v-if="v.approveType == 1 && v.status == 2" style="color: rgba(0, 0, 0, 0.56)"><span style="color: #262626">再次提交审批</span></span>
<span v-if="v.approveType == 1 && v.status == 3" style="color: rgba(0, 0, 0, 0.56)"><span style="color: #ffb236">审批驳回</span></span>
<span v-if="v.approveType == 2 && v.status == 2">
<span style="color: #63af17">审批通过</span>
</span>
<span v-if="v.approveType == 2 && v.status == 3">
将<span style="color: #ffb236">审批驳回</span>
</span>
</span>
</div>
<div v-if="(v.approveType == 1 || v.approveType == 2) && v.status == 3" class="reject-box">
<div class="reject-item-1">
<div>驳回原因</div>
<div>{{ v.rejectReason }}</div>
</div>
</div>
</div>
</template>
</el-step>
</el-steps>
</div>
</el-collapse-item>
</el-collapse>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="show = false">返回</el-button>
</div>
</template>
</zmjDialog>
</div>
</template>
<script setup lang="ts">
import { recordLog } from '@/api/project/device' // 接口替换为完成
import { GET_SUPPORT_TYPE, GET_SUPPORT_SECOND_TYPE_NAME } from './config'
const props = defineProps({
dialogFormVisible: Boolean,
value: Boolean,
projectDeviceId: { type: Number, default: null }, // 业务id
})
// const activeName = ref()
const activeName = ref([])
const emit = defineEmits(['update:value', 'exit'])
// 添加页面弹出标识
let show = computed({
get() {
return props.value
},
set(val: any) {
emit('update:value', val)
}
})
let PurchaseInfo:any = reactive([])
let joinSupportFeatureModel:any = ref('')
// 判断数组的最后一个
const isLastElement = (array:any, index:any) => {
return index === array.length - 1
}
const init = async () => {
try {
const res: any = await recordLog({ deviceId: props.projectDeviceId })
PurchaseInfo = res.data
let arr:any = []
activeName.value = []
PurchaseInfo.forEach((item:any, index:any)=>{
activeName.value.push(index.toString())
activeName.value = ['0']
if(index.toString() === activeName.value[0]){
item.height = myCollapseRef.value.$el.clientHeight + 20
item.flagActive = true
}else{
item.height = 38
item.flagActive = false
}
item?.supportFeatureModel?.map((v:any)=>{
if(v==='A1'){
arr.push('A类支架')
} else if(v ==='Q'){
arr.push('大倾角')
}else if(v ==='D'){
arr.push('电液控')
}else if(v ==='A'){
arr.push('大侧帮支架左架')
}else if(v ==='B'){
arr.push('大侧帮支架右架')
}else{
arr = []
}
})
})
// console.log(PurchaseInfo, 'PurchaseInfo-loading---',)
joinSupportFeatureModel.value = arr.join('、')
} catch (err) {
console.log(err.message)
}
}
let myCollapseRef = ref()
const itemHeight = ref(null)
// 监听折叠状态
const handleCollapseChange = (val: any) => {
// console.log(val, 'val');
PurchaseInfo.forEach((item:any, index:any)=>{
if(val){
if(val === index.toString()){
item.flagActive = true
item.height = myCollapseRef.value.$el.clientHeight + 20
} else{
item.flagActive = false
item.height = 38
}
}else{
item.flagActive = false
item.height = 38
}
})
// console.log(PurchaseInfo, 'PurchaseInfo')
}
</script>
<style lang="scss" scoped>
.el-dialog_divleft{
width: 10px;
// margin-left: 10px;
margin-top:28px;
display: flex;
flex-wrap: wrap;
height: 38px;
}
/* 选择最后一个div中的第二个p标签,并应用样式 */
.divleftlast:last-child p:last-child {
display: none;
}
.arrdata1{
width: 8px;
height: 8px;
border-radius: 50%;
border: 1px solid #3076fe;
// margin-top: 15px;
margin-left: 5px;
}
.arrdata1Active{
width: 8px;
height: 8px;
border-radius: 50%;
border: 1px solid #3076fe;
// margin-top: 15px;
margin-left: 5px;
background: #3076fe;
}
.el-dialog-div {
// width: 395px;
width: 100%;
margin-left: 20px; // 20px
height: 50vh;
overflow-x: hidden;
display: flex;
}
.page-content {
padding: 24px 44px;
.device-group {
&:not(:first-child) {
margin-top: 12px;
}
}
:deep(.el-descriptions.zmj-descriptions) {
.el-descriptions__header {
margin-top: 12px;
margin-bottom: 8px;
.el-descriptions__title {
font-weight: 400;
}
}
.el-descriptions__cell {
padding: 10px 12px;
color: #262626;
}
.el-descriptions__label {
padding: 10px 12px;
background-color: #fafafa;
color: #707070;
}
}
}
.page-empty {
height: 100%;
}
.color-centent {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
color: #3076fe;
}
/* 如果您想要在展开的el-collapse-item上添加特殊样式,可以使用深度选择器 */
.el-collapse {
:deep(.el-collapse-item__content) {
border: 1px solid #3076FE;
padding-bottom: 0px; /* 根据需要调整padding值 */
width: 384px;
}
}
.el-collapse-parent{
margin-top: 10px;
border: none;
width:395px;
margin-left: 10px;
:deep(.el-collapse-item__header){
background: #3076FE;
border-radius: 4px 4px 0px 0px;
width: 384px;
height: 39px
}
}
:deep(.el-collapse-item__arrow){
display:none;
}
.headerRightTrue{
width: 395px;
height: 38px;
background: #3076FE;
border-radius: 4px 4px 0px 0px;
display: flex;
justify-content: space-between;
padding: 10px;
color:#fff;
font-size: 14px;
line-height: 20px;
top: -20px;
.top-right{
width: 160px;
display: flex;
// justify-content: space-around;
justify-content: space-between;
font-size: 12px;
.headerRightspan1{
color:#fff;
}
}
}
.spanFalse{
width: 4px;
height: 12px;
background: #3076FE;
border-radius: 0px 0px 0px 0px;
margin-top: 4px;
}
.itemApproveTimeFalse{
margin-left: -55px;
}
.headerRightFlase{
background: #F3F8FF;
width: 395px;
height: 38px;
border-radius: 4px 4px 0px 0px;
display: flex;
justify-content: space-between;
padding: 10px;
color: #666666;
font-size: 14px;
line-height: 20px;
top: -20px;
border: 1px solid #3076FE;
.top-right{
width: 160px;
display: flex;
// justify-content: space-around;
justify-content: space-between;
font-size: 12px;
.headerRightspan2{
color: #3076FE
}
}
}
.contntDiv{
width: 355px;
height: 200px;
background: #F3F8FF;
border-radius: 4px 4px 4px 4px;
border: 1px solid #EEEEEE;
padding: 10px;
// margin: 14px;
margin: 8px 14px;
>div{
display: flex;
justify-content: space-between;
margin-top: 5px;
}
.contntDiv-1-span{
width: 116px;
height: 20px;
font-size: 14px;
color: #262626;
line-height: 0px;
text-align: left;
}
.contntDiv-2-span{
font-size: 10px;
color: #1890FF;
text-align: center;
height: 16px;
background: #E3F2FF;
border-radius: 2px 2px 2px 2px;
margin-left: 14px;
}
.contntDiv-1-d{
height: 17px;
font-size: 12px;
color: #A3A3A3;
}
.line{
background: #F3F8FF;
border: 1px dotted #A3A3A3;
}
.contntDiv-item-left{
// width: 100px;
height: 18px;
font-size: 13px;
color: #A3A3A3;
}
.contntDiv-item-right{
// width: 112px;
height: 18px;
font-size: 13px;
color: #262626;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.contntDiv-item-right-bottom{
height: 18px;
font-size: 13px;
color: #262626;
text-align: left;
display: flex;
justify-content: flex-end;
}
}
.box-approve {
min-height: 130px;
max-height: calc(100% - 82px);
overflow: auto;
margin-top: -5px;
}
.step-icon {
width: 8px;
height: 8px;
border-radius: 50%;
background: #A3A3A3;
border: 1px solid #A3A3A3;
margin-left: 50px;
// margin-top: 0px;
}
.titleDiv{
display: flex;
width: 155px;
.time {
color: #c2c2c2;
font-size: 12px;
margin-left: 90px;
width: 100px;
}
}
:deep(.el-steps) {
height: 100%;
}
:deep(.el-step__line){
background: #E8F0FF;
border: 1px dotted #A3A3A3;
margin-left: 87px;
margin-top: 20px;
height: calc(100% - 20px);
}
:deep(.el-step__main) {
padding: 8px 8px 9px;
// background-color: #f1f6ff;
min-height: 58px;
box-sizing: border-box;
margin-bottom: 12px;
.el-step__description {
font-size: 14px;
}
}
:deep(.el-step__title){
margin-left: 11px;
color: #e0e0e0;
}
// :deep(.el-step__head){
// // margin-left:110px;
// }
.reject-box {
font-size: 12px;
color: #a3a3a3;
.reject-item-1 {
display: flex;
& > div:nth-child(1) {
flex-shrink: 0;
}
& > div:nth-child(2) {
word-break: break-word;
width: 100%;
}
}
}
.descriptionDiv{
height: 100%;
width: 264px;
margin-left: 76px;
margin-top: -20px;
}
</style>
完成,请指教