现象
项目需求是在微信小程序里面做一个数据看板tabbar页,所以这里会用到图表,我用到是 ucharts库,同时页面会有popup弹框展示查询条件,项目里还用到了自定义底部tabbar,根据角色权限是否展示数据看板栏。这就导致了,弹框展开时和图表滚动到底部时,会将tabbar和弹框覆盖,如图:

分析
canvas 在微信小程序、百度小程序、QQ小程序中为原生组件,层级高于前端组件。参考:uniapp.dcloud.net.cn/component/c...
解决方案
因为我这不想将popup和自定义tabbar替换,所以排除用cover-view的方案。我这使用的是在图表绘制完成时,将canvas替换为图片。
js
<div class="chart-box">
<div class="chart-title">
<div class="chart-name">反馈处理情况</div>
<u-icon
name="/static/images/data-statistics/icon-expand.png"
@click="toExpand('bar')"
></u-icon>
</div>
<canvas
canvas-id="bar"
id="bar"
class="charts-bar"
@touchend="tap"
v-show="barChartShow"
/>
<image
:src="barChartUrl"
alt=""
v-show="!barChartShow"
:style="{
width: cWidthBar + 'px',
height: cHeightBar + 'px',
}"
></image>
</div>
js
// 画图表
this.drawBar("bar", currentBarData);
setTimeout(() => {
uni.canvasToTempFilePath({
canvasId: "bar",
success: (res) => {
this.barChartUrl = res.tempFilePath;
this.barChartShow = false;
},
});
}, 1500);
就在我以为大功告成时,突然又出现一个新的坑,页面里有三种图表,通过tab切换显示,这里切换的时候需要重新调用图表数据接口,会重新渲染canvas,这就导致在切换的时候有一段时间底部tabbar栏还是会被遮盖。

然后就又换了另外一种方案,直接将canvas定位到页面外,过度期间使用loading来展示,渲染完图表后用图片替换loading。

代码:
js
<div
class="chart-content"
v-show="chartParams.data_type === 1"
@click="toDetail"
>
<div class="chrt-name">
反馈问题分布图
<!-- <span class="detail-link" @click.native="toDetail">查看详情</span> -->
</div>
<canvas
canvas-id="ring"
id="ring"
class="charts-ring"
@touchend.stop="tap"
/>
<div
:style="{
width: cWidthBar + 'px',
height: cHeightBar + 'px',
}"
class="chart-loading-box"
v-show="ringChartShow"
>
<u-loading-icon size="36" class="chart-loading-icon"></u-loading-icon>
</div>
<image
:src="ringChartUrl"
alt=""
v-show="!ringChartShow"
:style="{
width: cWidthRing + 'px',
height: cHeightRing + 'px',
}"
></image>
</div>
js
.charts-bar {
width: 650rpx;
height: 530rpx;
// margin: 0 auto;
position: absolute;
left: -999px;
top: -999px;
}
.chart-loading-box {
position: relative;
margin: 0 auto;
::v-deep .u-loading-icon {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
但是这样就会导致图表是没法交互的,这里就看具体需求的取舍了。