3 / 31 vm.$set()實現原理是什麼?

前面的話

前端日問,鞏固基礎,不打烊!!!

解答

搞懂set原理要先搞懂響應式原理,如果不動響應式原理,可以先看小柒前面的文章。

  • 受現代 JavaScript 的限制 (而且 Object.observe 也已經被廢棄),Vue 無法檢測到對象屬性的添加或刪除。
  • 由於 Vue 會在初始化實例時對屬性執行 getter/setter 轉化,所以屬性必須在 data 對象上存在才能讓 Vue 將它轉換爲響應式的。
  • 對於已經創建的實例,Vue 不允許動態添加根級別的響應式屬性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套對象添加響應式屬性。
  • 那麼 Vue 內部是如何解決對象新增屬性不能響應的問題的呢?
export function set(target: Array<any> | Object, key: any, val: any): any { 
 // target 爲數組 
 if (Array.isArray(target) && isValidArrayIndex(key)) {   
  // 修改數組的長度, 避免索引>數組長度導致splice()執行有誤   
   target.length = Math.max(target.length, key);   
  // 利用數組的splice變異方法觸發響應式   
  target.splice(key, 1, val);  
   return val; 
  } 
  // target爲對象, key在target或者target.prototype上 且必須不能在 Object.prototype 上,直接賦值 
 	if (key in target && !(key in Object.prototype)) {    
 	target[key] = val;   
  	return val; 
 }  
 // 以上都不成立, 即開始給target創建一個全新的屬性 
  // 獲取Observer實例 
  const ob = (target: any).__ob__;  
  // target 本身就不是響應式數據, 直接賦值 
   if (!ob) {  
     target[key] = val;  
     return val;
   }  
   // 進行響應式處理
     defineReactive(ob.value, key, val);
     ob.dep.notify(); 
      return val;
  } 
  • 如果目標是數組,使用 vue 實現的變異方法 splice 實現響應式
  • 如果目標是對象,判斷屬性存在,即爲響應式,直接賦值
  • 如果 target 本身就不是響應式,直接賦值
  • 如果屬性不是響應式,則調用 defineReactive 方法進行響應式處理
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章