【发布时间】:2022-01-14 15:40:59
【问题描述】:
我有一个组件可以呈现一个库存计算机设备表。以下是初始渲染的相关代码:
let oEquiptByType = reactive({
Laptop: [],
iPad: [],
"Document Camera": [],
"Overhead Projector": [],
Chromebook: [],
Desktop: [],
MacBook: [],
Scanner: [],
});
// ======== Props =========== //
const props = defineProps({
propFormData: {},
});
// Now let's use Stein to retrieve the SS data
// eslint-disable-next-line no-unused-vars
const fetchSheetsData = function () {
const store = new SteinStore(
"https://api.steinhq.com/v1/storages/618e81028d29ba2379044caa"
);
store
.read("HS - Classrooms")
.then((data) => {
scrapDataHSClassrooms.value = data;
emptyRowsRemoved.value.forEach((item) => {
// Let's construct an object that separates equipment by type
// Check if property exists on oEquiptByType object
const exists = Object.prototype.hasOwnProperty.call(
oEquiptByType,
item["Equipment"]
);
// If item(row) is good lets push the row onto the corresponding Object Array
// in oEquiptByType. This will construct an object where each object property corresponds
// to an equipment category. And each oEquiptByType entry is an array where each array
// element is a row from the SS. e.g., oEquiptByType["Laptop"][3] is a row from
// SS and is a laptop.
if (exists) {
oEquiptByType[item["Equipment"]].push(item);
}
});
})
.catch((e) => {
console.error(e);
failure.value = true;
});
};
// =============== Called on component mount =============================== //
onMounted(fetchSheetsData);
初始渲染很好。现在我在道具上有一个观察者,所以当有人为库存提交新项目时,我将该数据推送到相应的对象数组(即,笔记本电脑将被推送到 oEquiptByType[props.propFormData.Equipment] em> 通过 oEquiptByType[props.propFormData.Equipment].push(props.propFormData);
// ================================================================ //
// ======================= Watch effects ========================== //
// ================================================================ //
watch(props.propFormData, () => {
// Push the submitted form item onto the reactive
// oEquiptByType object array. This update of Vue state
// will then be injected into DOM and automagically update browser display.
oEquiptByType[props.propFormData.Equipment].push(props.propFormData);
});
这适用于我添加到后端的第一个项目,您可以在此处看到原始项目,然后添加第一个项目:
在添加第一项后(笔记本电脑)
请注意 oEquiptByType[props.propFormData.Equipment] 添加了新项目。伟大的。 但是现在当我添加第二个项目(MacBook)时,这是结果状态:
请注意 Macbook 阵列已更新,但笔记本电脑阵列的最后一项已被 Mac book 条目覆盖???对于从用户添加的任何其他项目,此行为将继续。我已经阅读了文档,没有看到任何可以解释这种行为的东西。我希望也许有超过我对 Vue 有限经验的人可以帮助我。需要任何其他信息,请告诉我。谢谢...
更新: 将 JSON.Stringify 放入 watch 函数中
更新二: 这是prop.FormData的血统-
我们从表单模式开始并发出如下表单数据:
emit("emiterUIUpdate", formAsPlainObject);
然后在父App.vue中捕获数据:
<FormModal
v-show="isModalVisible"
@close="closeModal"
@emiterUIUpdate="updateUI"
>
<DisplayScrap :propFormData="formData" />
const formData = reactive({});
// Method to be called when there is an emiterUIUpdate event emiited
// from form-modal.vue @param(data) is the form data sent from the
// form submission via the event bus. We will then send this data back
// down to child display-scrap component via a prop.
const updateUI = (data) => {
Object.assign(formData, data);
};
然后正如之前在 display-scrap.vue 中发布的那样,prop propFormData 在 watch 函数中被定义和监视。希望有帮助..
【问题讨论】:
-
如果没有更多关于
props.propFormData的确切来源(当然,它来自父组件)以及对象是如何创建的信息,就无法回答。您很可能只是在重用单个对象实例。通过简单比较即可轻松测试Laptop[17] === Macbook[0] -
查看更新 2 以获得更多解释。
标签: vuejs3 vue-composition-api vue-reactivity