Vue.js响应式值更新延迟、子组件emit传参不生效问题求助
问题根因
出现更新滞后一个周期、传items不生效、传test看似正常的现象,是三个写法错误共同导致的:
- 子组件
ItemList.vue在<script setup>顶层直接执行emit触发事件,这个执行时机过早:子组件初始化跑setup逻辑的时候,父组件还没完成对子组件自定义事件的绑定,第一次触发的事件父组件根本接收不到,只有后续组件重渲染时才会同步值,外在表现就是永远慢一个更新周期。 - emit传参时直接传了
items这个ref响应式对象本身,没有通过.value取到内部存储的真实数组;父组件收到参数后直接执行testArray = msg,相当于把一个ref对象赋值给了原本存基础类型的testArray,响应式追踪逻辑直接混乱。传test时看似正常完全是巧合——test数组里只有一个元素,没有触发更明显的渲染报错,本质写法同样不符合规范。 - 父组件里
testArray初始值设为字符串'This is a test',和后续要存储数组的类型完全不一致,v-for遍历字符串时会把字符串拆成单个字符渲染,初始渲染逻辑本身就不符合预期。
修复方案
按以下三点调整即可解决问题:
- 不要在setup顶层直接触发emit,把传值逻辑移到
onMounted生命周期钩子里执行,等组件挂载完成、父组件的事件监听器全部绑定完毕后再传值。 - emit传参时传递ref的实际值,也就是
items.value,不要直接把ref实例当参数传。 - 统一
testArray的类型,初始值设为空数组即可,不要混用字符串和数组类型。
修正后App.vue代码
<script setup> import ItemList from "./components/ItemList.vue"; import {ref} from "vue"; // 初始值和后续类型保持一致,使用空数组 const testArray = ref([]) </script> <template> <ItemList @response="(msg) => testArray = msg" /> <ul> <li v-for="item in testArray" :key="item.id"> {{item.name}} </li> </ul> </template>
修正后ItemList.vue代码
<script setup> import {ref, onMounted} from "vue"; const items = ref([ {id: 1, name: 'SomeRandomName'}, {id: 2, name: 'SomeRandomName'}, {id: 3, name: 'SomeRandomName'}, ]) const emit = defineEmits(['response']) // 挂载完成后再传值 onMounted(() => { // 传递ref内部的真实数组 emit('response', items.value) }) </script> <template> </template>
内容的提问来源于stack exchange,提问作者Floooorson
相关产品推荐
相关产品推荐

