1. 程式人生 > 程式設計 >Vue2.0 $set()的正確使用詳解

Vue2.0 $set()的正確使用詳解

vue2.0 給data物件新增屬性,並觸發檢視更新

如下程式碼,給 student物件新增 age 屬性

data () {
  return {
    student: {
      name: '',sex: ''
    }
  }
}

眾所周知,直接給student賦值操作,雖然可以新增屬性,但是不會觸發檢視更新

mounted () {
  this.student.age = 24
}

原因是:受 ES5 的限制,Vue.js 不能檢測到物件屬性的新增或刪除。因為 Vue.js 在初始化例項時將屬性轉為 getter/setter,所以屬性必須在 data 物件上才能讓 Vue.js 轉換它,才能讓它是響應的。

要處理這種情況,我們可以使用$set()方法,既可以新增屬性,又可以觸發檢視更新。

但是,值得注意的是,網上一些資料寫的$set()用法存在一些問題,導致在新接觸這個方法的時候會走一些彎路!

錯誤寫法:this.$set(key,value)(ps: 可能是vue1.0的寫法)

mounted () {
  this.$set(this.student.age,24)
}

正確寫法:this.$set(this.data,”key”,value')

mounted () {
  this.$set(this.student,"age",24)
}

補充知識:Vue 中 $set() 與 Vue.set() 原理及使用

1. 前言

問題: 在使用 vue 進行開發的過程中,可能會遇到一種情況:當生成vue例項後,再次給資料賦值時,有時候並不會自動更新到檢視上去。也就是如果在例項建立之後新增新的屬性到例項上,它不會觸發檢視更新。

案例:

<template>
 <div class="home">
  <div v-for="(item,index) in items" :key="index">{{item}}</div>
 <button @click="btn()">修改</button>
 </div>
</template>

<script>
export default {
 name: 'Home',data(){
  return{
  items:[1,2,3]
   }
 },methods:{
 btn(){
     this.items[1] = 'two'
  console.log(this.items);
 }
  }
}
</script>

頁面:

Vue2.0 $set()的正確使用詳解

控制檯:

Vue2.0 $set()的正確使用詳解

原因: 受 ES5 的限制,Vue.js 不能檢測到物件屬性的新增或刪除。因為 Vue.js 在初始化例項時將屬性轉為 getter/setter,所以屬性必須在 data 物件上才能讓 Vue.js 轉換它,才能讓它是響應的。

因此: Vue 不能檢測以下變動的陣列:

當你利用索引直接設定一個項時,例如:vm.items[indexOfItem] = newValue

當你修改陣列的長度時,例如:vm.items.length = newLength

例如:使用 this.arr[0] 去更新 array 的內容,檢視沒有重新整理

使用 Vue.set(this.arr,!this.arr[0]) 去更新 array 的內容,檢視被重新整理

使用 this.arr[0] = !this.arr[0] 和 this.obj.a = !this.obj.a 同時更新,檢視被重新整理

結論:

如果方法裡面單純的更新陣列 Array 的話,要使用 Vue.set();

如果方法裡面同時有陣列和物件的更新,直接操作 data 即可;

2. 原理

每個元件例項都有相應的 watcher 例項物件,它會在元件渲染的過程中把屬性記錄為依賴,之後當依賴項的 setter 被呼叫時,會通知 watcher 重新計算,從而致使它關聯的元件得以更新。

Vue2.0 $set()的正確使用詳解

受現代 JavaScript 的限制 (而且 Object.observe 也已經被廢棄),Vue 不能檢測到物件屬性的新增或刪除。由於 Vue 會在初始化例項時對屬性執行 getter/setter 轉化過程,所以屬性必須在 data 物件上存在才能讓 Vue 轉換它,這樣才能讓它是響應的。

3. $set() 與 Vue.set() 的使用

3.1 通過 Vue.set() 改寫

語法:

Vue.set( target,propertyName/index,value )

引數:

{Object | Array} target

{string | number} propertyName/index

{any} value

返回值:設定的值。

用法:

向響應式物件中新增一個 property,並確保這個新 property 同樣是響應式的,且觸發檢視更新。

它必須用於向響應式物件上新增新 property,因為 Vue 無法探測普通的新增 property (比如 this.myObject.newProperty = 'hi')

注意:

物件不能是 Vue 例項,或者 Vue 例項的根資料物件。

<template>
 <div class="home">
  <div v-for="(item,index) in items" :key="index">{{item}}</div>
  <button @click="btn()">修改</button>
 </div>
</template>

<script>
import Vue from 'vue' // 別忘了引入
export default {
 name: 'Home',3]
  }
 },methods:{
 btn(){
      Vue.set(this.items,1,'two')
  console.log(this.items);
 }
 }
}
</script>

3.2 通過 $set() 改寫

語法:

vm.$set( target,value )

引數:

{Object | Array} target

{string | number} propertyName/index

{any} value

返回值:設定的值。

用法:

這是全域性 Vue.set 的別名。

參考:Vue.set

<template>
 <div class="home">
  <div v-for="(item,methods:{
 btn(){
    this.$set(this.items,'two')
  console.log(this.items);
 }
 }
}
</script>

頁面:

Vue2.0 $set()的正確使用詳解

控制檯:

Vue2.0 $set()的正確使用詳解

3.3 Vue.set() 和 this.$set() 的區別

Vue.set() 原始碼:

import { set } from '../observer/index'
...
Vue.set = set
...

this.$set() 原始碼

import { set } from '../observer/index'
...
Vue.prototype.$set = set
...

可以發現 Vue.set() 和 this.$set() 這兩個 api 的實現原理基本一模一樣,都是使用了set函式。

set 函式是從 …/observer/index 檔案中匯出的。

區別在於 Vue.set( ) 是將 set 函式繫結在 Vue 建構函式上,this.$set() 是將 set 函式繫結在 Vue原型上。

以上這篇Vue2.0 $set()的正確使用詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。