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

Vue组件Prop无响应问题:解构props后JS值不更新求助

Vue3响应式Props解构后值不更新的问题解决

我怀疑自己对Vue.js存在基础误解,或是遇到了Bug,以下是最小复现示例:

父组件App.vue中,通过computed创建响应式变量message,并作为Prop传递给子组件Child.vue。点击按钮可切换message的值,模板显示正常,但在子组件中调用alert_message方法时,始终弹出初始值——仅模板更新,JS中的值未同步。

子组件中若不解构props,直接使用props.message可解决问题,但会导致代码冗余,不想一直携带props.前缀。

App.vue

<script setup>
import { ref, computed } from "vue";
import Child from "./components/Child.vue";

let index = ref(0);
let messages = ["hi", "there", "this", "is", "strange"];

let message = computed(() => messages[index.value]);

function change_message() {
    index.value++;
    if (index.value === messages.length) {
        index.value = 0;
    }
}
</script>

<template>
    <Child :message="message"></Child>
    <div>
        <button @click="change_message">Change message</button>
    </div>
</template>

Child.vue

<script setup>
const { message } = defineProps(["message"]);
function alert_message() {
    window.alert(message);
}
</script>

<template>
    <h1>
        {{ message }}
    </h1>
    <button @click="alert_message">Alert message</button>
</template>

演示:问题演示


这不是Bug,是Vue3响应式系统的特性导致的:defineProps返回的是响应式Proxy对象,直接解构会丢失响应性——你拿到的只是解构瞬间的原始值,后续props更新时这个变量不会自动同步。

给你两种解决方法:

  1. 用toRefs转换props后解构
    把Child.vue的脚本改成这样:
<script setup>
import { toRefs } from 'vue'
const props = defineProps(["message"]);
const { message } = toRefs(props);

function alert_message() {
    // 注意这里要加.value,因为message是ref对象
    window.alert(message.value);
}
</script>

toRefs会把响应式对象的每个属性转换成对应的ref,这样解构后的message依然保持响应性。如果嫌.value麻烦,也可以给别名:

<script setup>
import { toRefs } from 'vue'
const props = defineProps(["message"]);
const { message: msg } = toRefs(props);

function alert_message() {
    window.alert(msg.value);
}
</script>
  1. 用computed包装props属性
    如果不想用ref,也可以用computed来包裹:
<script setup>
import { computed } from 'vue'
const props = defineProps(["message"]);
const message = computed(() => props.message);

function alert_message() {
    window.alert(message.value);
}
</script>

这里的message是响应式的computed对象,模板里可以直接用{{ message }}(模板会自动解包),JS里需要加.value访问值。


内容的提问来源于stack exchange,提问作者Script Raccoon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 14:42:24