Update value in multidimensional array in Vue

后端 未结 2 864
鱼传尺愫
鱼传尺愫 2021-01-12 18:50

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


        
相关标签:
2条回答
  • 2021-01-12 19:02

    The difficulty is that you're building the array in a way that Vue does not make its rows reactive. You could build the array and then assign it to the data item as a whole so that Vue would make it reactive, or you can build the array (at last the rows) using push, which will make them reactive. Then you can modify individual elements using splice. Modifying Bert's 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 (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>

    0 讨论(0)
  • 2021-01-12 19:10

    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/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>

    If I think of something better I'll update later.

    0 讨论(0)
提交回复
热议问题