【发布时间】:2020-09-30 11:16:29
【问题描述】:
在所有其他问题中,我发现数据被用于阻止反应。这里没有使用数据,prop 本身在渲染中更新失败。
我的 VueX 函数是:
addItemColumn() 在第一个 Box 中创建一个新列,本质上是不允许 box 自行增长;但是,父级可以请求添加一个新列(到第一个框)。
MoveBoxDown() 应该是不言自明的,但将当前框(调用此函数)与它下面的框切换。
这就是发生的事情......
当仅执行项目列时,会正确添加并重新呈现具有默认项目的附加列。但是,当首先执行 moveBoxDown 时,框会正确切换并重新渲染,但是当我去执行 addItemColumn 时,子 Box 没有看到对 Box 的任何更新。
奇怪的是
1) addItemColumn() 工作和渲染
2) moveBoxDown() 工作和渲染
因此,更新 moveBoxDown 的失败似乎不会导致 addItemColumn 出现问题。事实上,使用我的任何其他突变运行 moveBoxDown() 效果很好。
3) Vue Devtools 显示 Box 已更新,因此 box.items 已更新
4) 根据示例代码<p>{{ box.items.length }}<p> 更新父框而不是子框。
如果它在父母身上不起作用,我可能会认为这对孩子来说是一个关键问题;但是,它确实并结合 devtools 正确地在孩子身上显示更新的box,在我看来,出于某种未知原因,孩子没有检测到道具已更新?
我能想到解决这个问题的唯一方法是将 Box 变成一个开槽组件,因为父级知道,这似乎可以缓解这个问题。
我在 VueX 中有如下数据结构
Boxes = [
{
id: number
items: [
{
id: number
properties: {
...
}
},
...
]
},
...
]
在 VueX 中使用 .push() 添加项目,由 addBox 触发,因此检测到更改。同样,一般来说这是可行的,但在某些情况下,即使 Vue 开发工具显示正确的、现已更新的 prop 值,它也会拒绝更新。
父母
<template>
<b-button @click="addBox()">Add Box</b-button>
<div v-for="(box, index) in boxes" :key="`box_${index}`">
<!-- This updates so is not related to the parents loop -->
<p>{{ box.items.length }}</p>
<Box :box="box" />
</div>
</template>
<script>
// Import VueX
import { mapGetters, mapActions } from "vuex";
// Import Components
import Box from "~/components/Box";
export default {
name: "BoxesPage",
layout: "BoxesLayout",
components: { Box },
computed: {
...mapGetters({
boxes: "items/boxes"
})
},
methods: {
...mapActions({
addItemColumn: "items/addItemColumn"
})
},
async fetch({ store, params }) {
await store.dispatch("items/getInventory");
}
};
</script>
盒子
<template>
<div>
<!-- Neither of these update either, so this is not related to the child's loop -->
<p>{{ box }}<p>
<p>{{ box.items.length }}<p>
<b-button
@click="moveBoxDown()"
icon-right="chevron-down"
/>
<div
v-for="item in box.items"
:key="
`box_${box.index}_item_${item.index}_${item.name}`"
>
<!-- This does not add a new item -->
<Item :item="item" />
</div>
</div>
</template>
<script>
// Import VueX
import { mapGetters, mapActions } from "vuex";
// Import Components
import Item from "~/components/Item";
export default {
name: "Box",
components: { Item },
props: {
Box: {
type: Object,
required: true
}
},
methods: {
...mapActions({
moveBoxDown: "items/moveBoxDown",
})
}
};
</script>
我不会附加 VueX 行,因为 VueX 实现似乎完全没问题......无论它正确地重新渲染还是 Vue 开发工具没有显示 prop 已正确更新。
编辑: VueX“items.js”
export const state = () => ({
boxes: []
});
export const actions = {
moveFrameDown({ commit }, frameIndex) {
commit('switchBoxes', { fromIndex: frameIndex, toIndex: frameIndex + 1 });
},
addBoxColumn({ commit }, item) {
// Item is a default item type
commit('newItemColumn', item);
},
}
export const mutations = {
SwitchBoxes: (state, { fromIndex, toIndex }) => {
state.boxes[fromIndex] = {
index: fromIndex,
items: state.boxes.splice(toIndex, 1, {
index: toIndex,
items: state.frames[fromIndex].items
})[0].items
};
},
newItemColumn: (state, itemProps) => {
state.boxes[0].items.push({
id: state.idCounter
props: itemProps
});
state.idCounter += 1;
}
};
【问题讨论】:
-
什么具体不更新?当您添加一个盒子(数组的问题)时,附加的盒子不会显示在屏幕上,还是现有盒子的属性没有更新(盒子对象的问题)? 99% 的视图没有更新是由于没有预先正确声明反应数据,或者以 Vue 无法检测到的方式改变数组/对象,但是由于您省略了该代码,因此很难查明确切的问题。
-
是的,很抱歉,澄清一下当一个新的盒子被添加时它不会更新。我看看是否可以添加 VueX 代码或制作 JSFiddle。显示所有产生错误的代码有点复杂,因为它有点极端。
-
@DecadeMoon 我添加了 VueX 函数的示例,并阐明了特定的边缘情况以及应该发生的事情以及进一步发生的事情。我不确定看到 VueX 是否会特别有帮助,因为正如我一直提到的 DevTools 和 Parent 一样,
box在更新后的状态被正确表示和渲染。据我所知,这似乎是一个奇怪的问题,因为道具没有触发父母和孩子 Box 之间的更新。