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>
頁面:
控制檯:
原因: 受 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 重新計算,從而致使它關聯的元件得以更新。
受現代 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>
頁面:
控制檯:
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()的正確使用詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。