点击卡片渲染小细节
2026/7/9 7:30:40 网站建设 项目流程

项目场景:

点击展开卡片,卡片内容为echart的图表。

默认不展开卡片。


问题描述

点击展开后,内容 空白,不显示图表。


原因分析:

因为默认不展开,因此图表无法直接渲染,需要添加对应的方法去渲染图表。

虽然页面在一开始就获取了图表所需的数据,甚至可能已经做了初始化。但是要注意,此时卡片并没有展开,因此dom没有,所以初始化是失败的!!!就导致了点击展开以后内容空白,图表无法渲染。


解决方案:

需要根据卡片展开去渲染数据!

有两个方法可以去做

一:watch监听卡片的展开,监听到展开以后进行图表渲染

二:添加卡片的点击事件,在点击事件里面添加渲染逻辑

方法一:watch

处理逻辑

用户点击 collapse 标题

van-collapse 内部修改 activeNames(展开)

watch 监听到 activeNames 变化

$nextTick:等待 DOM 更新完成

面板已展开,容器有宽高

初始化图表

渲染成功

特点: van-collapse 自主改变数据,watch 被动响应,逻辑自然。

这里是监听到卡片展开的消息就出发了watch代码块,使用$nextTick是为了确保dom更新完成使得图表渲染所需的高宽存在,否则图表可能会渲染失败!!!

ctiveNames (newValue) { // 监听 '1'(卡片) 是否被展开 if (newValue && newValue.includes('1')) { this.$nextTick(() => { if (this.completionChart) { // 图表已存在,调整尺寸 this.completionChart.resize() } else if (this.completionChartReady) { // 数据已加载,立即初始化图表 this.initCompletionChart() } }) } }

方法二:点击事件

处理逻辑

用户点击

click handler 执行(同步):
1. this.activeNames = ['1'] → 主动改变数据
2. this.$nextTick(() => { → 等待 DOM 更新完成
initCompletionChart() → 面板已展开,容器有宽高
})

渲染成功

1、用 van-collapse 的 @change 事件
<van-collapse v-model="activeNames" @change="onCollapseChange"> <van-collapse-item name="1"> <template #title> <div class="firstContentTitle0"> <span class="firstContentTitle1"> <van-image :src="require('@/assets/icon/ico_two_done.svg')" /> </span> <span class="firstContentTitle2">各分公司完成情况</span> </div> </template> <div class="firstContentFrame"> <div class="chart-container" ref="completionChart"></div> </div> </van-collapse-item> </van-collapse>
2、对应的method
methods: { onCollapseChange() { if (this.activeNames && !this.activeNames.includes('1')) { this.activeNames.push('1') this.$nextTick(() => { if (this.completionChart) { this.completionChart.resize() } else if (this.completionChartReady) { this.initCompletionChart() } }) } } }

错误示例

点击事件逻辑和watch处理代码一致,图表在第一次展开的时候会是空白,第二次展开才能正常渲染!!!

methods: { onCollapseChange() { if (this.activeNames && this.activeNames.includes('1')) { this.$nextTick(() => { if (this.completionChart) { this.completionChart.resize() } else if (this.completionChartReady) { this.initCompletionChart() } }) } } }

错误原因:

因为点击事件发生时,卡片的展开标识还没有更新,而是优先执行点击事件的逻辑

顺序如下:

用户点击->执行代码块->更新卡片展开标识


由此可知,此时activename并没有‘1’,所以其实无法执行代码块,就算不加if (this.activeNames && this.activeNames.includes('1'))的判断,他也无法成功渲染,因为卡片并没有成功展开呢,dom没有更新,没有高宽给到echart渲染图表!


解决方案(点击事件代码块):

手动修改卡片展开标识->dom更新完毕->渲染图表

总结

watch直接监听到卡片展开标识更新以后,才执行watch代码块,要注意使用$nextTick等待dom更新完成以后再执行echart渲染,(是因为echart渲染强关联dom的高宽!!!否则直接执行是可以的!!!!)


点击事件则是先触发点击事件代码块,才到更新展开标识。按照这个逻辑,首次展开是无法获取图表渲染所必须的高宽,因此无法成功!

所以需要将展开标识的更新前置到点击事件代码块,然后后面逻辑与watch一致(dom更新,图表渲染)


两者逻辑上略有不同,因此操作也略不同!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询