|
|
@@ -0,0 +1,82 @@
|
|
|
+请问如何能实现在 app-ght/admin/home/components/OrderItem.vue 中改变了 item 中变量的值能传导到 app-ght/admin/home/order.vue 的 list.data 上
|
|
|
+
|
|
|
+## AI 给的解决方案
|
|
|
+
|
|
|
+### 核心结论
|
|
|
+- 不要在子组件 `OrderItem.vue` 里直接改 `props`(如 `item.sendStatus = 3`)。这会被父级重渲染覆盖,且在不同端(小程序/App)可能不触发视图更新。
|
|
|
+- 正确做法:子组件“上抛事件”,由父组件 `order.vue` 去改自己维护的源数据 `list.data`(并用 `this.$set` 确保响应式)。
|
|
|
+- 备选做法:使用 `.sync`,在父组件用 `:item.sync="list.data[index]"`,子组件发 `this.$emit('update:item', newItem)`。注意必须用 `list.data[index]`,不能用 `item`。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 推荐做法:事件上抛 + 父组件更新
|
|
|
+1) 子组件 `OrderItem.vue`:把直接改 `item` 的地方改成发事件
|
|
|
+```javascript
|
|
|
+// 例如:取消跑腿
|
|
|
+// 原:item.sendStatus = 3;
|
|
|
+this.$emit('update-field', { id: item.id, key: 'sendStatus', value: 3 });
|
|
|
+
|
|
|
+// 例如:创建跑腿订单成功
|
|
|
+// 原:item.sendStatus = 0;
|
|
|
+this.$emit('update-field', { id: item.id, key: 'sendStatus', value: 0 });
|
|
|
+```
|
|
|
+
|
|
|
+2) 父组件 `order.vue`:模板监听事件,并在 methods 里更新 `list.data`
|
|
|
+```vue
|
|
|
+<OrderItem
|
|
|
+ :ref="`orderRef${item.id}`"
|
|
|
+ :item="item"
|
|
|
+ :isScanEnv="isScanEnv"
|
|
|
+ @printOrder="printOrder"
|
|
|
+ @directFh="directFh"
|
|
|
+ @fillNoFh="fillNoFh"
|
|
|
+ @shareOrder="shareOrder"
|
|
|
+ @update-field="onUpdateItemField"
|
|
|
+/>
|
|
|
+```
|
|
|
+
|
|
|
+```javascript
|
|
|
+methods: {
|
|
|
+ onUpdateItemField({ id, key, value }) {
|
|
|
+ const index = this.list.data.findIndex(it => it.id === id);
|
|
|
+ if (index !== -1) {
|
|
|
+ // 确保响应式(数组/对象的嵌套字段)
|
|
|
+ this.$set(this.list.data[index], key, value);
|
|
|
+ // 若需要强制替换对象触发更深层渲染,可用:
|
|
|
+ // this.$set(this.list.data, index, { ...this.list.data[index], [key]: value });
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+这样,`OrderItem.vue` 中对 `item` 的“意图”通过事件通知给父组件,父组件去改 `list.data` 的源数据,UI 会稳定刷新,且没有直接改 `props` 的警告。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 备选做法:.sync 简化双向(谨慎用)
|
|
|
+父组件在 `v-for` 中绑定:
|
|
|
+```vue
|
|
|
+<view v-for="(item, index) in list.data" :key="item.id">
|
|
|
+ <OrderItem
|
|
|
+ :item.sync="list.data[index]"
|
|
|
+ :isScanEnv="isScanEnv"
|
|
|
+ ...
|
|
|
+ />
|
|
|
+</view>
|
|
|
+```
|
|
|
+
|
|
|
+子组件 `OrderItem.vue` 在需要改值时:
|
|
|
+```javascript
|
|
|
+this.$emit('update:item', { ...item, sendStatus: 3 });
|
|
|
+// 或 this.$emit('update:item', Object.assign({}, item, { sendStatus: 0 }));
|
|
|
+```
|
|
|
+
|
|
|
+要点:
|
|
|
+- 必须写成 `:item.sync="list.data[index]"`,不要写成 `:item.sync="item"`,否则赋值目标不是父级的响应式源数据。
|
|
|
+- `.sync` 会整体替换该条目对象,若对象很大或修改频繁,建议用“事件上抛 + 精准字段更新”的方式。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### 小提示
|
|
|
+- 在数组项或对象新增字段时,一定用 `this.$set` 保证响应式。
|
|
|
+- 子组件里直接改 `props` 虽然有时“能动”,但会有 Vue 警告且在部分端不刷新,建议统一改为上述两种正规方式。
|