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

Vue3子组件计算父组件books数组总价功能异常求助

Vue3子组件计算父组件书籍总价的问题修复

问题根源

  1. forEach无法返回累加结果:你在totalPrice计算属性里使用forEach遍历数组,但这个方法没有返回值,只会执行遍历逻辑,导致计算属性最终返回undefined,无法得到有效总价。
  2. 多余的priceSummary状态:你试图用ref存储总价,但计算属性本身就是响应式的,额外维护这个状态只会增加数据不同步的风险,完全没必要。
  3. Vue版本冲突:App.vue和BookSummary.vue里都引入了Vue2的CDN,这和你使用的Vue3语法(setup、ref)冲突,必须移除。

修正后的代码

1. App.vue(移除Vue2 CDN,规范组件注册)

<script>
import BooksList from './components/BooksList.vue'
import BooksLengthMsg from './components/BooksLengthMsg.vue'
import BooksSummary from './components/BookSummary.vue' // 修正组件名大小写,与子组件name保持一致

export default {
  components: { BooksList, BooksLengthMsg, BooksSummary }, // 对应修正后的组件名
  name: 'App',
  data: () => ({
    books: [
      {
        title: 'Windows Powershell w miesiąc',
        price: 20
      },
      {
        title: 'Alicja w krainie czarów',
        price: 18
      }
    ],
    form: {
      title: '',
      price: null
    }
  }),
  methods: {
    removeBook (index) {
      this.books.splice(index, 1)
      console.log('delete', index)
    },
    handleSubmit () {
      const newBook = { ...this.form }
      this.books.push(newBook)
      this.resetForm()
    },
    resetForm () {
      this.form.price = null
      this.form.title = ''
    }
  }
}
</script>

<template>
  <div id="app">
    <header>
      <h1>Books<span>.app</span></h1>
    </header>
    <books-list @remove="removeBook" :books="books" />
    <books-length-msg :books="books"/>
    <form @submit.prevent="handleSubmit">
      <label>
        Title:
        <input v-model="form.title" type="text" name="title">
      </label>
      <label>
        Price:
        <input v-model="form.price" type="number" name="price">
      </label>
      <button type="submit">Add book</button>
    </form>
    <books-summary :books="books" /> <!-- 放在app容器内,避免DOM结构异常 -->
  </div>
</template>

2. BookSummary.vue(修复计算属性,移除冗余代码)

<script>
export default {
  name: 'BooksSummary',
  props: {
    books: {
      type: Array,
      required: true
    }
  },
  computed: {
    bookAmount () {
      return this.books.length
    },
    totalPrice () {
      // 使用reduce累加总价,初始值设为0,同时处理price为null的情况
      return this.books.reduce((total, book) => total + (book.price || 0), 0)
    }
  }
}
</script>

<template>
    <div>Books Amount : {{ bookAmount }}</div>
    <div>Total price : {{ totalPrice }}</div>
</template>

<style>
div {
    padding: 5px;
}
</style>

关键说明

  • reduce的作用:reduce会遍历数组,将每个书籍的price累加到累加器中,初始值设为0。同时通过book.price || 0处理新增书籍时price为null的情况,避免出现NaN。
  • 响应式自动更新:计算属性totalPrice会自动监听books数组的变化(新增、删除、修改价格),实时更新总价,无需手动维护状态。
  • 版本一致性:确保项目依赖的是Vue3,彻底移除Vue2的CDN引用,避免语法冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:25:18