You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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遍历字符串时会把字符串拆成单个字符渲染,初始渲染逻辑本身就不符合预期。
修复方案

按以下三点调整即可解决问题:

  1. 不要在setup顶层直接触发emit,把传值逻辑移到onMounted生命周期钩子里执行,等组件挂载完成、父组件的事件监听器全部绑定完毕后再传值。
  2. emit传参时传递ref的实际值,也就是items.value,不要直接把ref实例当参数传。
  3. 统一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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 09:15:45