「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」
问题:
当对话框 (Dialog)中包含子组件时,我们使用 this.$refs 试图获取该组件的 dom 并操作时,发现获取的 dom 为 undefined 导致后续的方法报错;
<template>
<div>
<el-dialog :visible.sync="propertyDialog" width="60%" center>
<lineChart
ref="chart"
:xAxisArr="xAxisArr"
:yAxisArr="yAxisArr"
></lineChart>
</el-dialog>
</div>
</template>
<script>
import lineChart from "@/components/lineChart.vue";
export default {
data() {
return {
xAxisArr: [],
yAxisArr: [],
propertyDialog: false,
};
},
components: {
lineChart,
},
methods: {
showCharts() {
this.propertyDialog = true;
console.log(this.$refs.chart);
this.$refs.chart.drawLineChart();
},
},
};
</script>
解决:
因为自己之前用过 refs 来调用子组件方法,但是没有遇到过这种问题,很是无奈加之彷徨。 后来在度娘怀里遨游一番,发现和 element-ui 框架有关系,总之什么关系呢,我也说不清啦。
提示1:
Dialog 的内容是懒渲染的,即在第一次被打开之前,传入的默认 slot 不会被渲染到 DOM 上。
因此,如果需要执行 DOM 操作,或通过 ref 获取相应组件,请在 open 事件回调中进行。
提示2:
如果 visible 属性绑定的变量位于 Vuex 的 store 内,那么 .sync 不会正常工作。
此时需要去除 .sync 修饰符,同时监听 Dialog 的 open 和 close 事件,
在事件回调中执行 Vuex 中对应的 mutation 更新 visible 属性绑定的变量的值。
加上一个 this.$nextTick 就可以啦,这个回调函数的意思呢?
官方的用法说明:将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。 它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
其实简单理解就是:等所有的DOM元素节点都渲染完成以后才执行其里面的方法。
具体什么意思呢, 请参考 Vue中 $nextTick() 与 Vue.nextTick() 原理及使用
showCharts(params) {
this.propertyDialog = true;
this.$nextTick(()=>{
console.log(this.$refs.chart);
this.$refs.chart.drawLineChart();
})
},