Vue объект изменяется, но не перерисовывается - PullRequest
0 голосов
/ 04 мая 2019

Когда я нажимаю клавишу со стрелкой вправо, он меняет объект, но не перерисовывает его:

<div class="map">
   <div class="map-page" tabindex="0"  @keyup.arrow-keys="show"  ref="mapPage">
     <template  v-for="mapRow in mapMatrix">
       <div  v-for="cell in mapRow" @click="(cell.view === '1') ? showAlert() : false " v-bind:class="['map-cell',{'cell-active' : cell.active}]">
              {{cell.view}}
       </div>
     </template>
   </div>
<div>

При нажатии клавиши (@ keyup.arrow-keys = "show") хотите изменить активную ячейку.

show: function (event) {
        if(event.keyCode === 39){
          if (this.selectedCellId !== CELL_NUMBER){
            this.moveRight();
          }
        }
    },
moveRight: function(){
      this.$set(this.mapMatrix[this.selectedRowId][this.selectedCellId],'active',false);
      this.selectedCellId++;
      this.$set(this.mapMatrix[this.selectedRowId][this.selectedCellId],'active',true);
    },

это хорошо работает со статическим объектом:

 mapMatrix: {
        0 : {
            0 : {
                  "view" : "-1",
                  "available" : true,
                  "active": false
            },
            1 : {
                  "view" : "1",
                  "available" : true,
                  "active": false
            },
            2 : {
              "view" : "1",
              "available" : true,
              "active": false
            },

          },
...
}

Но не работает с:

fillMatrix: function(){
      var i;
      var g;
      for(i = 0; i <= CELL_NUMBER; i++){
          this.mapMatrix[i] = {};
          for(g = 0; g <= CELL_NUMBER; g++){
            var view = this.setVeiw(g);
            this.mapMatrix[i][g] =
              {
                    "view" : view,
                    "available" : true,
                    "active": false
              };
        }
      }
    }

Правильно меняет объект, но не реагирует на визуализацию html. В чем разница?

Ответы [ 2 ]

0 голосов
/ 04 мая 2019

Следует изменить функцию заполнения объекта более реактивным способом (как в комментарии @jcbdrn):

fillMatrix: function(){
      var i;
      var g;
      for(i = 0; i <= CELL_NUMBER; i++){
          this.$set(this.mapMatrix,i,{});
          for(g = 0; g <= CELL_NUMBER; g++){
            var view = this.setVeiw(g);
             this.$set(this.mapMatrix[i],g,
               {
                   "view" : view,
                   "available" : true,
                   "active": false
             }
           );

        }
      }
    },

Это решило проблему.

0 голосов
/ 04 мая 2019

То, как вы строите матричный объект, не будет правильно работать с Vue;скорее всего, он не станет реактивным (см. Предупреждение об обнаружении изменений ).

Либо используйте this.$set при построении матрицы, либо сначала создайте ее в локальной переменной , затем присвойте его this.mapMatrix последним, чтобы гарантировать, что весь объект будет реактивным.

Примерно так:

fillMatrix() {
  // This is a fresh new unobserved object
  const mapMatrix = {};

  for (let i = 0; i <= CELL_NUMBER; i++) {
    mapMatrix[i] = {};

    for(let g = 0; g <= CELL_NUMBER; g++) {
      mapMatrix[i][g] = {
        view: this.setView(g),
        available: true,
        active: false,
      };
    }
  }

  // Since the this.mapMatrix property is reactive, Vue will detect this
  // assignment and make the new mapMatrix object reactive
  this.mapMatrix = mapMatrix;
}
...