1. 程式人生 > 程式設計 >Vue之vue.$set()方法原始碼案例詳解

Vue之vue.$set()方法原始碼案例詳解

在使用開發專案的過程中,經常會遇到這樣的問題:當vue的data裡邊宣告或者已經賦值過的物件或者陣列(數組裡邊的值是物件)時,向物件中新增新的屬性,如果更新此屬性的值,是不會更新檢視的。

這是因為新加入的屬性不是響應式的,因此不會觸發檢視的更新,通常使用靜態方法Vue.set()或者例項方法this.$set()解決 ,使用方式:

物件:this.$set(target,key,  value)

陣列:this.$set(target,index,  value)

但不管是靜態方法Vue.set()還是例項方法this.$set(),他們底層的實現邏輯是一樣的,實現邏輯如下:

/**
 * Set a property on an object. Adds the new property and
 * triggers change notification if the property doesn't
 * alrewww.cppcns.comady exist.
 */
export function set (target: Array<any> | Object,key: any,val: any): any {
  // 首先判斷如果傳入的目標物件是undefined,null,primitive(原始值),或丟擲警告
  if (process.env.NODE_ENV !== 'production' &&
    (www.cppcns.com
isUndef(target) || isPrimitive(target)) ) { warn(`Cannot set reactive property on undefined,or primitive value: ${(target: any)}`) } // 判斷目標物件target是陣列,並且key是合法的索引 if (Array.isArray(target) && isValidArrayIndex(key)) { // 取目標陣列的length值和key中較大的值作為target的length屬性 target.length = Math.max(target.length,key)
// 通過splice對key位置的元素進行替換 target.splice(key,1,val) return val } // 如果key在目標物件中已經存在,則直接賦值 if (key in target && !(key in Object.prototype)) { target[key] = val return val } // 獲取target中的observer物件 const ob = (target: any).__ob__ // 如果target是vue例項或者$data直接返回 if (target._isVue || (ob && ob.vmCount)) { process.env.NODE_ENV !== 'production' && warn( 'Avoid adding reactive properties to a Vue instance or its root $data ' + 'at runtime - declare it upfront in the data option.' ) return val } // 如果ob不存在,說明target不是響應式物件,直接賦值,不觸發檢視更新 if (!ob) { target[key] = val return val } // 如果ob存在http://www.cppcns.com,把key設定為響應式屬性 defineReactive(ob.value,key,val) // 傳送通知,觸發檢視更新 ob.dep.notify() return val }

以上是vue 中set方法的原始碼,在這裡需要特別注意的是,在對陣列進行處理時,所用的splice方法並不是陣列本身的方法,而是在vue中封裝的具有響應式的陣列方法。

到此這篇關於Vue之vue.$set()方法原始碼案例詳解的文章就介紹到這了,更多相關Vue之vue.$set()方法原始碼內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!