Vue不能檢測數組或對象變動問題的解決


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>vue</title>
  <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script>
  <style>
    li:hover {
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div class="wrap">
    <ul>
      <li v-for="item,index in items" v-on:click="handle(index)">
        <span>{{item.name}}</span>
        <span>{{numbers[index]}}</span>
      </li>
    </ul>
  </div>
  <script>
    var vm = new Vue({
      el: ".wrap",
      data: {
        numbers: [],
        items: [
          {name: 'jjj'},
          {name: 'kkk'},
          {name: 'lll'},
        ]
      },
      methods: {
        handle: function (index) {
          // WHY: 更新數據,view層未渲染,但通過console這個數組可以發現數據確實更新了
           if (typeof(this.numbers[index]) === "undefined" ) {
          // 注:下面這么設置是可以的。例如 
          // var arr = [];
          // arr[3]=3;
          // console.log(arr)   //[empty × 3, 3]
              this.numbers[index] = 1;  
            //  this.numbers.splice(index,0,1)   //用splice方法能同步顯示,但得不到想要的效果
           } else {
              this.numbers[index]++;
            //  this.numbers.splice(index,1,this.numbers[index]++)
           }
        //    console.log(this.numbers)
        }
      }
    });
   
  </script>
</body>
</html>

想實現的效果是點擊 li 看 vm.nymbers[index] 是否存在,不存在設置為1,存在的話加1。

 

點擊之后數字並沒有在view層更新,而通過console打印發現數據更新了,只是view層沒有及時的檢測到。

再看一個栗子的:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>vue</title>
  <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script>
  <style>
    li:hover {
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div class="wrap">
    <ul>
      <li v-for="item,index in items" v-on:click="handle(index)">
        <span>{{item.name}}</span>
        <!--<span>{{numbers[index]}}</span>-->
      </li>
    </ul>
  </div>
  <script>
    var vm = new Vue({
      el: ".wrap",
      data: {
        // numbers: [],
        items: [
          {name: 'jjj'},
          {name: 'kkk'},
          {name: 'lll'},
        ]
      },
      methods: {
        handle: function (index) {
          // 不是數組,這里更新數據就可以直接在view層渲染
          this.items[index].name += " success";
        //   console.log(this.numbers)
        }
      }
    });
  </script>
</body>
</html>

可以看到這里的view層能及時得到更新,但是到了數組哪里為什么就不可以了呢?


來看Vue2.0官方的文檔說明:

由於 JavaScript 的限制,Vue 不能檢測以下變動的數組:

當你利用索引直接設置一個項時,例如:vm.items[indexOfItem] = newValue
當你修改數組的長度時,例如:vm.items.length = newLength
為了解決第一類問題,以下兩種方式都可以實現和 vm.items[indexOfItem] = newValue 相同的效果,同時也將觸發狀態更新:

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)


// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)

你還可以使用 vm.$set 實例方法,它只是全局 Vue.set 的別名。

 

還有由於 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除:

var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` 現在是響應式的
 
vm.b = 2
// `vm.b` 不是響應式的

對於已經創建的實例,Vue 不能動態添加根級別的響應式屬性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套對象添加響應式屬性。例如,對於:

var vm = new Vue({
  data: {
    userProfile: {
      name: 'Anika'
    }
  }
})


//如果你想添加新的響應式屬性應該這樣做:
this
.userProfile = Object.assign({}, this.userProfile, { age: 27, favoriteColor: 'Vue Green' })

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM