Vue2.0 $set()的正確使用詳解
vue2.0 給data對象新增屬性,并觸發(fā)視圖更新
如下代碼,給 student對象新增 age 屬性
data () { return { student: { name: '', sex: '' } } }
眾所周知,直接給student賦值操作,雖然可以新增屬性,但是不會觸發(fā)視圖更新
mounted () { this.student.age = 24 }
原因是:受 ES5 的限制,Vue.js 不能檢測到對象屬性的添加或刪除。因?yàn)?Vue.js 在初始化實(shí)例時(shí)將屬性轉(zhuǎn)為 getter/setter,所以屬性必須在 data 對象上才能讓 Vue.js 轉(zhuǎn)換它,才能讓它是響應(yīng)的。
要處理這種情況,我們可以使用$set()方法,既可以新增屬性,又可以觸發(fā)視圖更新。
但是,值得注意的是,網(wǎng)上一些資料寫的$set()用法存在一些問題,導(dǎo)致在新接觸這個(gè)方法的時(shí)候會走一些彎路!
錯(cuò)誤寫法: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) }
補(bǔ)充知識:Vue 中 $set() 與 Vue.set() 原理及使用
1. 前言
問題: 在使用 vue 進(jìn)行開發(fā)的過程中,可能會遇到一種情況:當(dāng)生成vue實(shí)例后,再次給數(shù)據(jù)賦值時(shí),有時(shí)候并不會自動更新到視圖上去。也就是如果在實(shí)例創(chuàng)建之后添加新的屬性到實(shí)例上,它不會觸發(fā)視圖更新。
案例:
<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 不能檢測到對象屬性的添加或刪除。因?yàn)?Vue.js 在初始化實(shí)例時(shí)將屬性轉(zhuǎn)為 getter/setter,所以屬性必須在 data 對象上才能讓 Vue.js 轉(zhuǎn)換它,才能讓它是響應(yīng)的。
因此: Vue 不能檢測以下變動的數(shù)組:
當(dāng)你利用索引直接設(shè)置一個(gè)項(xiàng)時(shí),例如:vm.items[indexOfItem] = newValue
當(dāng)你修改數(shù)組的長度時(shí),例如:vm.items.length = newLength
例如:使用 this.arr[0] 去更新 array 的內(nèi)容,視圖沒有刷新
使用 Vue.set(this.arr, 0, !this.arr[0]) 去更新 array 的內(nèi)容,視圖被刷新
使用 this.arr[0] = !this.arr[0] 和 this.obj.a = !this.obj.a 同時(shí)更新,視圖被刷新
結(jié)論:
如果方法里面單純的更新數(shù)組 Array 的話,要使用 Vue.set();
如果方法里面同時(shí)有數(shù)組和對象的更新,直接操作 data 即可;
2. 原理
每個(gè)組件實(shí)例都有相應(yīng)的 watcher 實(shí)例對象,它會在組件渲染的過程中把屬性記錄為依賴,之后當(dāng)依賴項(xiàng)的 setter 被調(diào)用時(shí),會通知 watcher 重新計(jì)算,從而致使它關(guān)聯(lián)的組件得以更新。
受現(xiàn)代 JavaScript 的限制 (而且 Object.observe 也已經(jīng)被廢棄),Vue 不能檢測到對象屬性的添加或刪除。由于 Vue 會在初始化實(shí)例時(shí)對屬性執(zhí)行 getter/setter 轉(zhuǎn)化過程,所以屬性必須在 data 對象上存在才能讓 Vue 轉(zhuǎn)換它,這樣才能讓它是響應(yīng)的。
3. $set() 與 Vue.set() 的使用
3.1 通過 Vue.set() 改寫
語法:
Vue.set( target, propertyName/index, value )
參數(shù):
{Object | Array} target
{string | number} propertyName/index
{any} value
返回值:設(shè)置的值。
用法:
向響應(yīng)式對象中添加一個(gè) property,并確保這個(gè)新 property 同樣是響應(yīng)式的,且觸發(fā)視圖更新。
它必須用于向響應(yīng)式對象上添加新 property,因?yàn)?Vue 無法探測普通的新增 property (比如 this.myObject.newProperty = 'hi')
注意:
對象不能是 Vue 實(shí)例,或者 Vue 實(shí)例的根數(shù)據(jù)對象。
<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', data(){ return{ items:[1, 2, 3] } }, methods:{ btn(){ Vue.set(this.items, 1, 'two') console.log(this.items); } } } </script>
3.2 通過 $set() 改寫
語法:
vm.$set( target, propertyName/index, value )
參數(shù):
{Object | Array} target
{string | number} propertyName/index
{any} value
返回值:設(shè)置的值。
用法:
這是全局 Vue.set 的別名。
參考:Vue.set
<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.$set(this.items, 1, 'two') console.log(this.items); } } } </script>
頁面:
控制臺:
3.3 Vue.set() 和 this.$set() 的區(qū)別
Vue.set() 源碼:
import { set } from '../observer/index' ... Vue.set = set ...
this.$set() 源碼
import { set } from '../observer/index' ... Vue.prototype.$set = set ...
可以發(fā)現(xiàn) Vue.set() 和 this.$set() 這兩個(gè) api 的實(shí)現(xiàn)原理基本一模一樣,都是使用了set函數(shù)。
set 函數(shù)是從 …/observer/index 文件中導(dǎo)出的。
區(qū)別在于 Vue.set( ) 是將 set 函數(shù)綁定在 Vue 構(gòu)造函數(shù)上,this.$set() 是將 set 函數(shù)綁定在 Vue原型上。
以上這篇Vue2.0 $set()的正確使用詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue子傳父關(guān)于.sync與$emit的實(shí)現(xiàn)
這篇文章主要介紹了vue子傳父關(guān)于.sync與$emit的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11詳解vue-router 2.0 常用基礎(chǔ)知識點(diǎn)之導(dǎo)航鉤子
本篇文章主要介紹了vue-router 2.0 常用基礎(chǔ)知識點(diǎn)之導(dǎo)航鉤子,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05