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();
      });
    },

这样就不会报错了。

当然,父组件触发子组件中的方法不止一种,也可以使用别的方法。

分类: 前端