I understand from the caveats portion of the Vue docs that updating a value in an array in the following manner will not work:
this.arr[idx] = newVal
and that one should use splice()
. I am using a 2D array to store grid data, and I am having a difficult time updating the value when a cell in the grid is clicked.
Here is my template:
<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>
And here is the relevant code for the Vue component:
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)
}
}
So I am attempting to add a true
value to the cell that is click at the given row
col
locations provided in the my selectCell
method. However, the data in my grid is not updated to reflect the newly added value. How exactly do I update values in a multidimensional array in Vue?
One method that works:
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)
},
Here is an example.
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/[email protected]/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>
If I think of something better I'll update later.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With