父模板中調用組件的元素將會被組件自己的模板取代。所以,若是組件的模板包含多個頂級元素:css
Vue.component('example', { template: '<div>A</div>' + '<div>B</div>' }) 或者模板只包含文本: Vue.component('example', { template: 'Hello world' })
在這兩個狀況下,實例將變成一個片斷實例 (fragment instance),也即沒有根元素的實例。它的 $el 指向一個錨節點(普通模式下是空的文本節點,debug 模式下是註釋節點)。更重要的是,父模板組件元素上的指令、過渡效果和屬性綁定(props 除外)將無效,由於生成的實例並無根元素供它們綁定vue
<!-- 指令不生效,由於沒有根元素用來綁定 --> <example v-show="ok" v-transition="fade"></example> <!-- props 仍是可以正常生效 --> <example prop="{{someData}}"></example>
拓展:Web Components - 面向將來的組件標準webpack
當一個組件被定義, data 必須聲明爲返回一個初始數據對象的函數,由於組件可能被用來建立多個實例。若是 data 仍然是一個純粹的對象,則全部的實例將共享引用同一個數據對象!經過提供 data 函數,每次建立一個新實例後,咱們可以調用 data 函數,從而返回初始數據的一個全新副本數據對象。web
若是須要,能夠經過將 vm.$data 傳入 JSON.parse(JSON.stringify(...)) 獲得深拷貝的原始數據對象。
複雜類型=>指針 簡單類型=>值瀏覽器
Vue 的 DOM 更新是異步執行,當偵測到數據變化時,Vue 會打開一個隊列,而後把在同一個事件循環 (event loop) 當中觀察到數據變化的 watcher 推送進這個隊列。假如一個 watcher 在一個事件循環中被觸發了屢次,它只會被推送到隊列中一次。app
而後,在進入下一次的事件循環時, Vue 會清空隊列並進行必要的 DOM 更新。(microtasks和macrotasks)dom
if (typeof MutationObserver !== 'undefined' && !hasMutationObserverBug) { var counter = 1 // 建立一個MutationObserver,observer監聽到dom改動以後後執行回調nextTickHandler var observer = new MutationObserver(nextTickHandler) var textNode = document.createTextNode(counter) // 調用MutationObserver的接口,觀測文本節點的字符內容 observer.observe(textNode, { characterData: true }) // 每次執行timerFunc都會讓文本節點的內容在0/1之間切換, // 不用true/false多是有的瀏覽器對於文本節點設置內容爲true/false有bug? // 切換以後將新值賦值到那個咱們MutationObserver觀測的文本節點上去 timerFunc = function() { counter = (counter + 1) % 2 textNode.data = counter } } else { // webpack attempts to inject a shim for setImmediate // if it is used as a global, so we have to work around that to // avoid bundling unnecessary code. // webpack默認會在代碼中插入setImmediate的墊片 // 沒有MutationObserver就優先用setImmediate,不行再用setTimeout const context = inBrowser ? window : typeof global !== 'undefined' ? global : {} timerFunc = context.setImmediate || setTimeout } MO和Promise.resolve().then(nextTickHandler) // 文檔示例 var vm = new Vue({ el: '#example', data: { msg: '123' } }) vm.msg = 'new message' // change data vm.$el.textContent === 'new message' // false Vue.nextTick(function() { vm.$el.textContent === 'new message' // true })
data-v-079ce416屬性
app[data-v-079ce416]
跟隨做用域,webpack loader處理,加上'[hash:base64]'屬性異步
h是createElement(),傳入{},返回vNode;函數
模板到DOM大體流程:oop
template模板通過parse處理後返回AST
得到一棵AST後再通過generate()生成渲染函數
執行渲染函數後會得到一個VNode,即虛擬DOM
patch函數,負責把虛擬DOM變爲真正DOM。