【问题标题】:Vue object changes, but doesn't re-renderVue 对象更改,但不会重新渲染
【发布时间】:2019-09-22 17:05:09
【问题描述】:

当我按右箭头键时,它会更改对象,但不会重新渲染它:

<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 渲染没有反应。有什么区别?

【问题讨论】:

标签: javascript vue.js components render


【解决方案1】:

您构建矩阵对象的方式无法在 Vue 中正常工作;它可能最终不会是被动的(请参阅Change Detection Caveats)。

要么在构建矩阵时使用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;
}

【讨论】:

    【解决方案2】:

    应该将对象填充功能更改为更具反应性的方式(如@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
                 }
               );
    
            }
          }
        },
    

    这解决了问题。

    【讨论】:

      猜你喜欢
      • 2023-01-10
      • 1970-01-01
      • 2018-10-14
      • 1970-01-01
      • 2019-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      相关资源
      最近更新 更多