Vue中子组件触发事件后父组件Ref对象值未更新问题求助
问题分析与解决方案
你的问题核心在于父子组件的状态完全脱节:子组件没有使用父组件传递的filter props,而是自己初始化了独立的状态;同时父组件也没有接收子组件emit的更新值来同步自身状态。以下是具体修正步骤:
1. 修正子组件:接收父组件props并同步状态
子组件目前自己创建了filter ref,完全忽略了父组件传递的:filter="f",导致两者状态无关。修改子组件脚本和模板:
子组件脚本修改
import { defineProps, defineEmits } from 'vue'; // 接收父组件传递的filter props const props = defineProps<{ filter: IFilter; }>(); // 定义emit事件 const emit = defineEmits(['filterChange']); const updateFilter = () => { console.log("value in filter " + props.filter.go); // 将更新后的filter对象传递给父组件 emit('filterChange', { ...props.filter }); // 展开对象确保传递新引用(可选) };
子组件模板修改
将v-model绑定到父组件传递的props属性:
<template> <div class="flex items-start"> <div class="flex items-center h-5"> <input id="gcp" name="gcp" type="checkbox" v-model="props.filter.gcp" @change="updateFilter" class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" > </div> <div class="ml-3 text-sm"> <label for="gcp" class="font-medium text-gray-200">GCP</label> </div> </div> </template>
若开启Vue严格模式,直接修改props会触发警告,可改用
computed做双向绑定优化(可选):import { computed } from 'vue'; const localFilter = computed({ get() { return props.filter; }, set(newVal) { emit('filterChange', newVal); } });模板中绑定
v-model="localFilter.gcp"即可。
2. 修正父组件:接收emit值并更新自身状态
父组件的checkit函数需要接收子组件传递的更新值,同步到自身的f ref:
父组件脚本修改
function checkit(updatedFilter: IFilter) { // 更新父组件的filter状态 f.value = updatedFilter; console.log("fired " + f.value.go); api.getAll(1,6, f.value).then(c => courses.value = c); }
更简洁的优化方案:使用Vue3自定义v-model
利用Vue3的自定义组件v-model语法糖,简化双向绑定逻辑:
子组件修改
import { defineProps, defineEmits } from 'vue'; // 使用modelValue作为props名,update:modelValue作为emit事件 const props = defineProps<{ modelValue: IFilter; }>(); const emit = defineEmits(['update:modelValue']); const updateFilter = () => { emit('update:modelValue', { ...props.modelValue }); };
模板绑定props.modelValue.gcp即可。
父组件修改
直接用v-model绑定f,无需手动处理@filter-change,同时监听f的变化自动调用API:
<template> <div v-if="!courses">Loading courses...</div> <div v-else> <div class="flex grid-cols-2 justify-start"> <div> <Filter v-model="f" /> </div> </div> </div> </template>
import { watch } from 'vue'; // 监听filter变化,自动触发API请求 watch(f, (newFilter) => { console.log("fired " + newFilter.go); api.getAll(1,6, newFilter).then(c => courses.value = c); }, { deep: true }); // 对象类型需开启深度监听
内容的提问来源于stack exchange,提问作者Mike3355
相关产品推荐
相关产品推荐

