[面試專題]習覺得常卻被忽略的vue小知識

習覺得常卻被忽略的vue小知識


root element

父模板中調用組件的元素將會被組件自己的模板取代。所以,若是組件的模板包含多個頂級元素: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 函數,每次建立一個新實例後,咱們可以調用 data 函數,從而返回初始數據的一個全新副本數據對象。web

若是須要,能夠經過將 vm.$data 傳入 JSON.parse(JSON.stringify(...)) 獲得深拷貝的原始數據對象。
複雜類型=>指針 簡單類型=>值瀏覽器

Vue.nextTick()

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
})

css scoped

data-v-079ce416屬性
app[data-v-079ce416]
跟隨做用域,webpack loader處理,加上'[hash:base64]'屬性異步

h => h(App)

h是createElement(),傳入{},返回vNode;函數

模板到DOM大體流程:oop

template模板通過parse處理後返回AST

得到一棵AST後再通過generate()生成渲染函數

執行渲染函數後會得到一個VNode,即虛擬DOM

patch函數,負責把虛擬DOM變爲真正DOM。

相關文章
相關標籤/搜索