一个非常令人迷惑的错误蔓延到我的Vue组件中;如果我从下面的代码中添加第5行,它将按预期工作,如果将其删除,则每个board-slot
元素的click方法将停止更改boardSlots
对象。
使用{{currentPlayer}}
与这有什么关系?我没有在其他任何地方使用它。它不一定需要打印,仅需要在模板定义中的某个位置,因此具有currentPlayer
类绑定的随机元素也可以使其神奇地工作。我缺少Vuex架构的东西吗?
<template>
<div id="board-container">
//THIS LINE
{{currentPlayer}}
<div id="board">
<div class="board-row" v-for="i in boardSlots">
<div class="board-slot"
v-for="boardSlot in i"
:class="[{checked: (boardSlot.owner != 0)}, 'ownedBy-player-' + boardSlot.owner]"
@click="checkSlot(boardSlot.row, boardSlot.col)">
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default{
created(){
for(var i = 0; i < 6; i++){
this.boardSlots[i] = [];
}
var row = 0;
var col = 0;
for(var i = 1; i <= 42; i++){
this.boardSlots[row].push({
owner: 0,
hover: false,
row: row,
col: col,
});
col++;
if (col == 7) {
col = 0;
if (row < 5) {
row++;
}
}
}
},
data(){
return {
boardSlots: [],
}
},
computed: {
...mapState([
'currentPlayer',
]),
},
methods: {
...mapActions([
'swapToNextPlayer',
]),
checkSlot(row, col){
if (this.boardSlots[row][col].owner == 0) {
this.boardSlots[row][col].owner = 1;
this.swapToNextPlayer();
}
}
}
}
</script>
答案 0 :(得分:2)
我不确定{{currentPlayer}}
的具体用途,但是每当您修改组件的状态并且视图不更新时,(假设渲染期间没有错误)通常意味着要么:
这是一个危险信号:
this.boardSlots[i] = [];
Vue无法检测到对数组元素的分配(读取Array Change Detection)。您需要使用splice()
或push()
来让Vue知道。或者,您也可以在局部变量中构造boardSlots
数组,然后在最后将其分配给this.boardSlots
:
const boardSlots = [];
// Initialize boardSlots ...
this.boardSlots = boardSlots;
您还以一种奇怪的方式渲染了行和插槽;您不应在渲染过程中改变任何状态,无论是局部渲染还是其他方式(--i
)。只需这样做:
<div class="board-row" v-for="slots of boardSlots">
<div class="board-slot"
v-for="slot of slots"
:class="[{checked: (slot.owner != 0)}, 'ownedBy-player-' + slot.owner]"
@click="checkSlot(slot.row, slot.col)">
</div>
</div>
但这可能与您的反应性问题无关。
答案 1 :(得分:2)
添加{{ currentPlayer }}
将使其成为呈现依赖项。当任何渲染依赖项更改时,将导致整个模板重新运行。因此,在这种情况下,更改currentPlayer
将导致重新渲染该模板中的所有内容。
如果模板中包含一些非反应性数据,或者您试图以反应性系统无法跟踪的方式更改数据,则对该数据的更改将不会触发重新渲染。
需要理解的关键是,当模板或render
函数运行时,它始终会运行整个过程。尽管非反应性更改不会触发渲染,但是如果其他因素触发了渲染,它们仍然会被拉入。我的假设是swapToNextPlayer
对currentPlayer
进行了更改,从而触发了重新渲染。
有许多变更检测警告需要注意:
https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
https://vuejs.org/v2/guide/list.html#Caveats
在这种情况下,问题在于此行尝试通过索引更新数组:
this.boardSlots[i] = [];
结果是无法正确将阵列输入到反应性系统中。而是使用:
this.boardSlots.push([]);