今天在调试代码时发现控制台经常输出一个error日志,出于好奇,于是探个究竟。若在你的Vue文件中有如下类似的示例代码:
<template> <div> <p>Welcome to home</p>
<el-button @click="testButton">Test</el-button> <el-button @click="handleButton">Show Dialog</el-button> <el-dialog :visible.sync="visible" @close="handleClose"> <customer-component ref="customerComponent"/> </el-dialog </div> </template> <script> components: {
'customer-component': ()=>import('HelloWorld') // 假设同目录下有HelloWorld.vue文件,并且提供了reset()方法
},
data() {
return {
visible: false
}
},
mounted() {
console.log('====this refs are', this.$refs)
},
methods: {
testButton() {
this.$refs.customerComponent.reset()
},
handleButton(){
this.visible = true
},
handleClose() {
this.visible = false
}
} <script> <style> </style>
(1)问题现象
当进入该组件后,先不要弹出对话框,而是直接触击estButton()方法,此时会在控制台中看到一条error消息,如下截图所示:
也就是说this.$refs.cusomerComponent是undefined,未定义的,不能直接引用reset()方法。
(2)问题分析
由于该组件中是通过this.visible属性值来控制对话框的,当首次进入该组件时,由于this.visible为false,所以对话框中插槽内容是不会被渲染的,我们也可以在mounted方法看到console.log()对this.$refs的打印,发现是空的。所以可以肯定的一点是当el-dialog组件通过visible属性来控制显示时,若初始值时false的话,那么首次进入父组件时该el-dialog组件内的内容是不会被加载渲染的,此时不能直接使用ref来访问插槽中组件的方法或者属性。
(3)问题解决
通过分析,已明确问题的原因了,那么我们可以这样来处理:首先判断this.$refs.customerComponent是否有效,若无效的话,就不执行reset()方法;所以,在testButton()方法中适当判断一下就可以了:
testButton() { if (this.$refs.customerComponent) { this.$refs.customerComponent.reset() } }