Vue3中组件向视图传递tmp_sell变量失败问题求助
问题分析与修复方案
核心问题点
- 事件名完全不匹配:子组件发射的事件名是
choosenOneProduct,但父组件监听的是choosen_products和tmp_sell,两者毫无对应,导致tmp_sell无法传递到父组件。 - 同名变量冲突:子组件同时在
props和data中声明choosen_products、tmp_sell,违反Vue单向数据流规则,造成变量逻辑混乱。 - 同一事件名重复发射不同数据:子组件两次调用
$root.$emit('choosenOneProduct', ...),分别传递数组和数值,即使父组件监听该事件,也无法区分两种数据。 - 父组件误用props接收子组件数据:
tmp_sell是子向父传递的数据,父组件应在data中定义变量存储,而非声明为props(props是父传子的通道)。 - 未利用Vue响应式绑定输入框:父组件打算用DOM操作赋值input,不符合Vue响应式思路,应使用
v-model实现自动更新。
修复后的代码
1. AllProductsChoose.vue(子组件)
<template> <tr class="choose_product" v-for="p, i in all_products" :key="i" @click.prevent="choosenOneProduct(p, i)"> <!-- 累计所选商品的p_sell值 --> <td>{{ p.p_sell }}</td> <td> <div> <button class="btn btn-info" @click.prevent="choosenOneProduct(p, i)"> [+] </button> </div> </td> </tr> </template> <script> export default { name: 'all-products-choose', // 移除props中与data同名的变量,内部状态由data维护 data() { return { choosen_products: [], tmp_sell: 0 } }, methods: { choosenOneProduct(p, i) { const choose_product_ref = firebase.firestore().collection("all_products").where("p_fullname", "==", p.p_fullname); choose_product_ref.onSnapshot((snapshot) => { snapshot.docs.forEach(d => { const product = d.data(); const tmp_one_sell = parseFloat(d.data().p_sell); this.tmp_sell += tmp_one_sell; this.choosen_products.push(product); // 发射不同名称的事件,分别传递两类数据 this.$emit('update:choosen-products', this.choosen_products); this.$emit('update:tmp-sell', this.tmp_sell); }) }) } } } </script>
2. 父视图组件
<template> <all-products-choose @update:choosen-products="getChoosenProducts" @update:tmp-sell="getTmpSell" ></all-products-choose> <!-- 用v-model.number绑定响应式变量,实现输入框自动更新 --> <input type="number" v-model.number="tmp_sell" placeholder="Subtotal" id="q_subtotal" /> </template> <script> import AllProductsChoose from './AllProductsChoose.vue'; export default { components: { AllProductsChoose }, data() { return { choosen_products: [], tmp_sell: 0 } }, methods: { getChoosenProducts(products) { this.choosen_products = products; }, getTmpSell(sell) { this.tmp_sell = sell; } } } </script>
额外优化建议
- 避免使用
$root.$emit,直接用组件自身的$emit,遵循组件间通信的标准方式。 - 给
v-for添加:key属性,提升渲染性能并消除Vue警告。 - 可考虑用Vue3组合式API(setup语法糖)重构代码,更贴合Vue3开发习惯。
内容的提问来源于stack exchange,提问作者ZION WONG
相关产品推荐
相关产品推荐

