需求描述: 项目中,使用el-dialog组件展示内容,内容是自己封装的一个组件,组件中通过ref获取dom元素然后进行echarts图形的绘制渲染。
出现问题:
会报以下错误
没有弹出el-dialog组件,也echarts图形没有渲染出来,刚开始还以为是自己监听数据出现了问题,通过把组件放在el-dialog弹窗组件外使用,发现图形能正常显示,所以把问题出现的原因锁定在了el-dialog组件上。通过百度,了解到在刚开始弹窗没有弹出来的时候,el-dialog中的组件是没有被渲染出来的,因此在使用ref获取dom元素的时候,在el-dialog没有被渲染出来之前去获取是获取不到的。
想办法解决:
知道原因即可,但我没有使用tip的这个方法,既然是获取不到dom,那么应该是可以借助nextTick函数解决问题的,于是,我将渲染逻辑放到nextTick函数中顺利解决问题看到了想要的结果
结果如下:
展示一下我封装的el-dialog组件的全部代码:
<template>
<div>
<el-dialog
v-model="props.modelValue"
:title="props.title"
@close="handleCancel"
>
<div ref="mainHx" style="width: 100%; height: 400px"></div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSubmit"> 确定 </el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref,nextTick } from "vue";
// 按需引入 echarts
import * as echarts from "echarts";
const props = defineProps({
modelValue: {
type: Boolean,
required: true,
default: false,
},
title: {
type: String,
required: true,
default: "",
},
Data: {
type: Object,
default: () => {
return {};
},
},
});
const emit = defineEmits(["update:modelValue", "handleSubmitFn", "isEditFn"]);
const handleSubmit = async () => {
handleCancel();
};
const handleCancel = async () => {
emit("update:modelValue");
emit("isEditFn");
};
onMounted(() => {
nextTick(()=>{
renderChart();
})
});
const pieData = [
{ value: 335, name: "数据1" },
{ value: 310, name: "数据2" },
{ value: 234, name: "数据3" },
{ value: 135, name: "数据4" },
{ value: 1548, name: "数据5" },
];
const mainHx = ref();
function renderChart() {
console.log("mainHx.value", mainHx.value);
const chartHx = echarts.init(mainHx.value);
const option = {
title: {
text: "环形图",
left: "center",
},
tooltip: {
trigger: "item",
},
legend: {
orient: "vertical",
left: "left",
data: pieData?.map((item) => item.name),
},
series: [
{
name: "数据",
type: "pie",
radius: ["60%", "70%"], // 设置内外半径
data: pieData,
},
],
};
chartHx.setOption(option);
function eventHandler4() {
// 自适应大小
chartHx.resize();
}
window.addEventListener("resize", eventHandler4);
}
</script>
<style scoped lang="scss"></style>