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

Vue+TypeScript中父组件更新子组件Props值的问题排查

Vue 3 + TypeScript 动态Props不更新问题解决

问题原因

你定义的friends是普通JavaScript数组,不属于Vue的响应式数据。Vue无法追踪普通对象/数组的属性修改,所以即使你通过toggleFavorite修改了isFavorite的值,组件也不会触发重新渲染,子组件的isFavorite props自然不会更新。

解决步骤

  1. 将数组转为响应式数据
    使用Vue的ref函数包裹friends数组,让它成为响应式数据。
  2. 优化TypeScript类型约束
    给数组和props定义明确的类型,提升代码健壮性。

修改后的完整代码

父组件

<script setup lang="ts">
import { ref } from 'vue';

interface Friend {
  id: string;
  name: string;
  phone: string;
  email: string;
  isFavorite: boolean;
}

const friends = ref<Friend[]>([
  {
    id: "emanuel",
    name: "Emanuella e",
    phone: "08788",
    email: "emanuella@gmail.com",
    isFavorite: true,
  },
  {
    id: "denta",
    name: "Denta W",
    phone: "08789",
    email: "denta@gmail.com",
    isFavorite: false,
  },
]);

function toggleFavorite(friendId: string){
  const identifiedFriend = friends.value.find(friend => friend.id === friendId);
  if(identifiedFriend){
    identifiedFriend.isFavorite = !identifiedFriend.isFavorite;
  }
}
</script>

<template>
  <section>
    <header><h1>Test Friends</h1></header>
    <ul>
      <friend-container
        v-for="friend in friends"
        :id="friend.id"
        :key="friend.id"
        :name="friend.name"
        :phone="friend.phone"
        :email="friend.email"
        :isFavorite="friend.isFavorite"
        @toggle-favorite="toggleFavorite"
      >
      </friend-container>
    </ul>
  </section>
</template>

子组件

<template>
  <li>
    <h2>{{ name }} {{ isFavorite ? "(Favorite)" : "" }}</h2>
    <button @click="toggleFavorite">Toggle Favorite</button>
    <button @click="toggleDetails">Show details</button>
  
    <ul v-if="detailAreVisible">
      <li><strong>Phone: </strong>{{ phone }}</li>
      <li><strong>email: </strong>{{ email }}</li>
    </ul>
  </li>
</template>

<script setup lang="ts">
import { ref} from 'vue';

const detailAreVisible = ref(false);

const props = defineProps<{
  id: string;
  name: string;
  phone: string;
  email: string;
  isFavorite: boolean;
}>();

const emit = defineEmits<{
    (e: 'toggle-favorite', value: string): void
}>()

function toggleDetails(){
    detailAreVisible.value = !detailAreVisible.value;
}

function toggleFavorite(){
    emit("toggle-favorite", props.id);
}
</script>

额外说明

  • Vue模板中会自动解包ref类型的变量,所以模板里直接写v-for="friend in friends"即可,无需访问.value。
  • 子组件props中isFavorite改用小写boolean类型(大写Boolean是构造函数,不是TypeScript的基本类型),同时简化了props的写法——TypeScript类型已经能约束必填项,无需额外写{ type: String; required: true }这种选项式API风格的配置。

内容的提问来源于stack exchange,提问作者marcellus denta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:52:41