摘要:先問大家一個簡單的問題還有人記得里面的方法是如何讓節點綁定對應的數據對象的嗎有時候我們做節點關聯設計的思路其實有一點類似,但是在里面多了很多概念,比如如何生成的,包含子父關系屬性內置的對象的如何注冊生命周期解析到根節點之后獲取再一步一步解析
先問大家一個簡單的問題:
還有人記得 jquery 里面的 data 方法是如何讓 DOM 節點綁定對應的數據對象的嗎
有時候我們做節點關聯設計的思路其實有一點類似,但是在 vue 里面多了很多概念,比如:
1、vnode: 如何生成的,包含子父關系、屬性 data
2、內置的 ref 對象的 create 如何注冊
3、生命周期:解析到根節點之后獲取 outerHTML 再一步一步解析子元素
用慣 vue 的人都會很熟悉地:
使用 ref 來注冊引用信息,再通過 $refs 對象就可以做關聯
但是我們看看它們是如何關聯上的呢?
代碼片段來自 2.5.16 版本:
1、需要初始化 $refs,默認是一個空對象
我們看到在函數 initLifecycle 上會往 vm 上設置一個 key 為 $refs 值為一個對象
function initLifecycle (vm) { vm.$refs = {}; }
2、獲取元素上的 ref 值:
在函數 registerRef 上,它接受 2 個參數:
vnode
isRemoval
function registerRef (vnode, isRemoval) {}
直接通過 vnode.data 獲取:
var key = vnode.data.ref;
然后獲取 $refs
在這之前需要獲取 vm:
從 vnode 上下文 context 獲取
var vm = vnode.context;
然后很簡單的就是 vm.$refs
var refs = vm.$refs;
ref 其實是什么呢?
DOM 節點或組件實例
這里的:
componentInstance -- 組件實例
elm -- DOM 節點
var ref = vnode.componentInstance || vnode.elm;
這里需要處理一下 v-for 一起用的情況,官網也提過:
對應的引用信息是包含 DOM 節點或組件實例的數組
if (vnode.data.refInFor) {}
情況一:如果不是數組格式,強制轉換一下,外層套一個數組
判斷方式:Array.isArray
if (!Array.isArray(refs[key])) { refs[key] = [ref]; }
情況二:看數組里面是否存在當前這個 ref,如果不存在,push 進去
if (refs[key].indexOf(ref) < 0) { refs[key].push(ref); }
如果不是和 v-for 一起用:直接設置對象的 key 和 value:
refs[key] = ref;
最后一個問題,官網提到了:
ref 注冊時間 -- 因為 ref 本身是作為渲染結果被創建的,在初始渲染的時候你不能訪問它們 - 它們還不存在
那我們看看:
1、它到底是在什么時機綁定的
2、vnode 是如何產生的
最開始我們從 _init 開始
Vue.prototype._init = function (options) { // vm.$mount if (vm.$options.el) { vm.$mount(vm.$options.el); } }
生成 vnode 最核心的部分:
實例化 VNode
function _createElement ( var vnode; if (typeof tag === "string") { // ... vnode = new VNode( config.parsePlatformTagName(tag), data, children, undefined, undefined, context ); } }
我們以如下代碼為例:
我們的 VNode 如下:
最外層 app 轉換的 vnode:
children:[VNode] data: { attrs: { id: "app" } } tag: "div"
子 vnode 如下:
data: { ref: "imgbox", attrs: { src:"https://vuejs.org/images/logo.png", alt:"Vue logo" } } tag: "img"
內置了一個 ref 對象,里面有 create 函數,調用了 registerRef
var ref = { create: function create (_, vnode) { registerRef(vnode); } }
在函數 invokeCreateHooks 調用 create
注意兩點:
1、cbs 是什么?
2、create又是什么,和 ref 對象的 create 有什么關系
function invokeCreateHooks (vnode, insertedVnodeQueue) { for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) { cbs.create[i$1](emptyNode, vnode); } }
后面會提到:hooks
var hooks = ["create", "activate", "update", "remove", "destroy"];
核心部分:createPatchFunction,往 cbs 里面放置對應的函數
function createPatchFunction (backend) { var cbs = {}; var modules = backend.modules; for (i = 0; i < hooks.length; ++i) { cbs[hooks[i]] = []; for (j = 0; j < modules.length; ++j) { // ... cbs[hooks[i]].push(modules[j][hooks[i]]); } } }
那誰調用了 createPatchFunction 函數呢:
var modules = platformModules.concat(baseModules); var patch = createPatchFunction({ nodeOps: nodeOps, modules: modules });
我們發現 baseModules 關聯了 ref
var baseModules = [ ref, directives ]
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97559.html
摘要:大家中秋假期快樂,假期分享一些原理設計文章給大家原創不易,歡迎轉發,一起學習凌晨寫的,不容易哈,收藏或者點個贊吧在常見的單頁應用中,我們都會有一個根文件,里面放置一個然后配置路由來切換很多人在子父組件嵌套關系下的生命周期鉤子函數如何應用, 大家中秋假期快樂,假期分享一些原理設計文章給大家 原創不易,歡迎轉發,一起學習(凌晨寫的,不容易哈,收藏或者點個贊吧) 在常見的單頁應用中,我們都...
摘要:的組件化功能可謂是它的一大亮點,通過將頁面上某一組件的代碼放入一個的文件中進行管理可以大大提高代碼的維護性。項目中未做移動端適配,在不同屏幕手機上打開,可能用戶體驗會差些 一、項目展示: showImg(https://user-gold-cdn.xitu.io/2018/5/18/1637183ad14a696a?w=372&h=791&f=gif&s=2408442); 注意:如果...
摘要:主要是通過為我們屬性添加一些自定義的行為。方法用來初始化一些生命周期相關的屬性,以及為等屬性賦值,來看源碼。名稱說明指定已創建的實例之父實例,在兩者之間建立父子關系。一個對象,持有已注冊過的所有子組件。 上篇文章,我們講了vm._renderProxy相關的內容。主要是通過Proxy為我們vm屬性添加一些自定義的行為。今天我們回到init方法中,為大家講解initLifecycle。i...
摘要:我們先來看下這個函數的一些神奇用法對于上述代碼,也就是函數來說返回值是。不管你第二個參數的函數返回值是幾維嵌套數組,函數都能幫你攤平到一維數組,并且每次遍歷后返回的數組中的元素個數代表了同一個節點需要復制幾次。這是我的 React 源碼解讀課的第一篇文章,首先來說說為啥要寫這個系列文章: 現在工作中基本都用 React 了,由此想了解下內部原理 市面上 Vue 的源碼解讀數不勝數,但是反觀...
閱讀 2217·2019-08-30 15:54
閱讀 1955·2019-08-30 13:49
閱讀 675·2019-08-29 18:44
閱讀 830·2019-08-29 18:39
閱讀 1111·2019-08-29 15:40
閱讀 1533·2019-08-29 12:56
閱讀 3146·2019-08-26 11:39
閱讀 3101·2019-08-26 11:37