在Vue中更新多维数组中的值
Posted
技术标签:
【中文标题】在Vue中更新多维数组中的值【英文标题】:Update value in multidimensional array in Vue 【发布时间】:2018-01-20 12:53:11 【问题描述】:我从 Vue 文档的警告部分了解到,以下列方式更新数组中的值将不起作用:
this.arr[idx] = newVal
并且应该使用splice()
。我正在使用二维数组来存储网格数据,当单击网格中的单元格时,我很难更新值。
这是我的模板:
<tr
v-for="(row, rowKey, index) in grid"
:key="rowKey">
<th
class="row-col-label"
>rowKey+1</th>
<td
v-for="(col, colKey, index) in row"
:key="colKey"
@click="selectCell(rowKey, colKey)"
:class="'selected' : cellSelected(rowKey, colKey)"
>
col
</td>
</tr>
这里是Vue组件的相关代码:
created ()
this.initColHead()
this.createSpreadSheet()
,
data ()
return
selected: '',
grid: [],
colHead: [' '],
isSelected: false
,
methods:
initColHead ()
this.colHead.push(...'ABC'.split(''))
,
createSpreadSheet ()
for (let i = 0; i <= 2; i++)
this.grid[i] = []
for (let j = 0; j <= 2; j++)
this.grid[i][j] = false
,
selectCell (row, col)
this.isSelected = true
console.log(`row $row col $col`)
this.grid[row].splice(col, 1, true)
for (let i = 0; i <= 2; i++)
for (let j = 0; j <= 2; j++)
console.log(this.grid[i][j])
,
cellSelected (row, col)
return (this.grid[row][col] === true)
所以我试图将true
值添加到单击我的selectCell
方法中提供的给定row
col
位置的单元格。但是,我的网格中的数据没有更新以反映新增加的值。 Vue 中的多维数组究竟如何更新值?
【问题讨论】:
【参考方案1】:困难在于您构建数组的方式是 Vue 不会使其行反应。您可以构建数组,然后将其作为一个整体分配给数据项,以便 Vue 使其具有响应性,或者您可以使用 push
构建数组(最后是行),这将使它们具有响应性。然后您可以使用splice
修改单个元素。修改Bert的例子:
console.clear()
new Vue(
el: "#app",
created()
this.initColHead()
this.createSpreadSheet()
,
data()
return
selected: '',
grid: [],
colHead: [' '],
isSelected: false
,
methods:
initColHead()
this.colHead.push(...'ABC'.split(''))
,
createSpreadSheet()
for (var i = 0; i <= 2; i++)
this.grid.push([]);
for (var j = 0; j <= 2; j++)
this.grid[i].push(false);
,
selectCell(row, col)
this.grid[row].splice(col, 1, true);
,
cellSelected(row, col)
return (this.grid[row][col] === true)
)
.selected
background-color: green;
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
<table>
<tr v-for="(row, rowKey, index) in grid" :key="rowKey">
<th class="row-col-label">rowKey+1</th>
<td v-for="(col, colKey, index) in row" :key="colKey" @click="selectCell(rowKey, colKey)" :class="'selected' : cellSelected(rowKey, colKey)">
col
</td>
</tr>
</table>
</div>
【讨论】:
好收获!我没有注意到网格是如何构建的。 非常好。你能解释一下为什么使用push
会有不同的效果吗?
@MahmudAdam 与推荐 splice
的原因相同:它是 Vue 为反应式数组重新编写的 mutation methods 之一。【参考方案2】:
一种有效的方法:
selectCell (row, col)
//make a copy of the row
const newRow = this.grid[row].slice(0)
// update the value
newRow[col] = true
// update it in the grid
this.$set(this.grid, row, newRow)
,
这是一个例子。
console.clear()
new Vue(
el: "#app",
created()
this.initColHead()
this.createSpreadSheet()
,
data()
return
selected: '',
grid: [],
colHead: [' '],
isSelected: false
,
methods:
initColHead()
this.colHead.push(...'ABC'.split(''))
,
createSpreadSheet()
for (let i = 0; i <= 2; i++)
this.grid[i] = []
for (let j = 0; j <= 2; j++)
this.grid[i][j] = false
,
selectCell(row, col)
const newRow = this.grid[row].slice(0)
newRow[col] = true
this.$set(this.grid, row, newRow)
,
cellSelected(row, col)
return (this.grid[row][col] === true)
)
.selected
background-color: green;
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
<table>
<tr v-for="(row, rowKey, index) in grid" :key="rowKey">
<th class="row-col-label">rowKey+1</th>
<td v-for="(col, colKey, index) in row" :key="colKey" @click="selectCell(rowKey, colKey)" :class="'selected' : cellSelected(rowKey, colKey)">
col
</td>
</tr>
</table>
</div>
如果我想到更好的东西,我会稍后更新。
【讨论】:
谢谢!。我最终做的是 this.grid = this.grid.map(el => el.splice()) 以便在设置新值后更新整个网格并且它似乎正在工作;但是,您的解决方案看起来好多了。以上是关于在Vue中更新多维数组中的值的主要内容,如果未能解决你的问题,请参考以下文章