父模板中调用组件的元素将会被组件自己的模板取代。所以,若是组件的模板包含多个顶级元素: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。