0.背景
改个小功能,定义了一个子组件:
<template> <div> </div> </template> <script> export default { name: "SyncGroupList", props: { // 班级/团队id gid: { type: Number, default: null, }, }, data() { return { }; }, methods: { // 获取所有题单列表 getTrainingList() { console.log("getTrainingList"); }, }, }; </script>
想通过父组件引入子组件,然后触发子组件的方法。
父组件定义参考如下:
<template> <div> <el-button @click="handleTrainingToGroup"></el-button> <el-dialog :title="弹窗" width="850px" :visible.sync="groupListPage" :close-on-click-modal="false" > <SyncGroupList ref="SyncGroupListChild"> </SyncGroupList> </el-dialog> </div> </template> <script> export default { name: "GroupTrainingList", data() { return { }; }, methods: { handleTrainingToGroup() { console.log("公共训练同步至班级"); this.groupListPage = true; this.$refs.SyncGroupListChild.getTrainingList(); }, }, }; </script>
如果像上面那样定义,首次加载就会报错:
vue.min.js:6 TypeError: Cannot read properties of undefined (reading ‘getTrainingList’)
第二次打开就正常了。
去查了一下原因:
“关于ref注册时间的重要说明:因为ref本身作为渲染结果被创建的,在初始渲染的时候你不能访问它们,它们还不存在!$refs也不是响应式的,因此你不应该试图用它在模板中做数据绑定”。
意思是:你用上面的方法创建子组件后,不能立即访问里面的方法。
解决办法,我们可以加个定时。比如下面这样:
handleTrainingToGroup() { console.log("公共训练同步至班级"); this.groupListPage = true; setTimeout(() => { this.$refs.SyncGroupListChild.getTrainingList(); }); },
这样就不会报错了。
当然,父组件触发子组件中的方法不止一种,也可以使用别的方法。