Vue3 Composition API下子组件触发事件时如何重新渲染父组件
问题解决方案
核心问题原因
每次调用useMembers()都会创建全新的members ref实例,父组件和子组件的members是完全独立的引用。子组件提交成员后,只会修改自己的members,父组件的列表数据不会同步更新。
方法一:让Composable状态全局共享
将成员状态提升到useMembers函数外部,确保所有组件调用该Composable时共享同一套状态:
修改src/composables/members.js:
import { ref } from "vue"; import axiosClient from "../axios"; import { useRouter } from "vue-router"; // 状态定义在函数外部,实现全局共享 const members = ref([]); const member = ref([]); const errors = ref(""); export default function useMembers() { const router = useRouter(); const getMembers = async () => { let response = await axiosClient.get("/members"); members.value = response.data.data; }; const getMember = async (id) => { let response = await axiosClient.get("/members/" + id); member.value = response.data.data; }; const storeMember = async (data) => { errors.value = ""; try { const response = await axiosClient.post("/members", data); // 直接将新成员添加到共享数组 members.value.push(response.data.data); // 若接口不返回新成员数据,可替换为重新拉取列表:await getMembers(); } catch (e) { if (e.response?.status === 422) { errors.value = e.response.data; } } }; return { members, getMembers, router, member, getMember, storeMember, errors, }; }
修改后,父、子组件的members指向同一引用,子组件提交后父组件列表会自动更新。
方法二:子组件触发事件通知父组件刷新
通过自定义事件实现组件间通信,子组件提交成功后通知父组件重新拉取列表:
- 修改
memberStore.vue,添加事件触发逻辑:
<template> <!-- 模板部分不变 --> </template> <script> import { reactive, defineEmits } from "vue"; import useMembers from "../../composables/members"; export default { emits: ["member-added"], // 声明自定义事件 setup(props, { emit }) { // 解构获取emit方法 const form = reactive({ name: "", address: "", }); const { errors, storeMember } = useMembers(); const saveMember = async () => { await storeMember({ ...form }); emit("member-added"); // 触发通知事件 // 清空表单 form.name = ""; form.address = ""; }; return { form, errors, saveMember, }; }, }; </script>
- 修改
members.vue,监听事件并刷新列表:
<template> <div> <!-- 监听子组件的自定义事件 --> <memberStore @member-added="getMembers"></memberStore> <!-- 表格部分不变 --> </div> </template> <script> import useMembers from "../../composables/members"; import { onMounted } from "vue"; import memberStore from "../../components/members/memberStore.vue"; export default { components: { memberStore }, setup() { const { members, getMembers } = useMembers(); onMounted(getMembers); return { members, getMembers // 返回方法供模板调用 }; }, }; </script>
内容的提问来源于stack exchange,提问作者Daddi Al Amoudi
相关产品推荐
相关产品推荐

