资讯专栏INFORMATION COLUMN

[面试专题]习以为常却被忽略的vue小知识

ThreeWords / 473人阅读

摘要:习以为常却被忽略的小知识父模板中调用组件的元素将会被组件本身的模板取代。如果需要,可以通过将传入得到深拷贝的原始数据对象。然后,在进入下一次的事件循环时,会清空队列并进行必要的更新。

习以为常却被忽略的vue小知识 root element

父模板中调用组件的元素将会被组件本身的模板取代。因此,如果组件的模板包含多个顶级元素:

Vue.component("example", {
  template:
    "
A
" + "
B
" }) 或者模板只包含文本: Vue.component("example", { template: "Hello world" })

在这两个情况下,实例将变成一个片段实例 (fragment instance),也即没有根元素的实例。它的 $el 指向一个锚节点(普通模式下是空的文本节点,debug 模式下是注释节点)。更重要的是,父模板组件元素上的指令、过渡效果和属性绑定(props 除外)将无效,因为生成的实例并没有根元素供它们绑定





拓展:Web Components - 面向未来的组件标准

组件中的data必须是函数

当一个组件被定义, data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。

如果需要,可以通过将 vm.$data 传入 JSON.parse(JSON.stringify(...)) 得到深拷贝的原始数据对象。
复杂类型=>指针 简单类型=>值

Vue.nextTick()

Vue 的 DOM 更新是异步执行,当侦测到数据变化时,Vue 会打开一个队列,然后把在同一个事件循环 (event loop) 当中观察到数据变化的 watcher 推送进这个队列。假如一个 watcher 在一个事件循环中被触发了多次,它只会被推送到队列中一次。

然后,在进入下一次的事件循环时, Vue 会清空队列并进行必要的 DOM 更新。(microtasks和macrotasks)

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大致流程:

template模板经过parse处理后返回AST

获得一棵AST后再经过generate()生成渲染函数

执行渲染函数后会获得一个VNode,即虚拟DOM

patch函数,负责把虚拟DOM变为真正DOM。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/112491.html

相关文章

  • [面试专题]习以为常却被忽略vue知识

    摘要:习以为常却被忽略的小知识父模板中调用组件的元素将会被组件本身的模板取代。如果需要,可以通过将传入得到深拷贝的原始数据对象。然后,在进入下一次的事件循环时,会清空队列并进行必要的更新。 习以为常却被忽略的vue小知识 root element 父模板中调用组件的元素将会被组件本身的模板取代。因此,如果组件的模板包含多个顶级元素: Vue.component(example, { t...

    Loong_T 评论0 收藏0
  • [面试专题]习以为常却被忽略vue知识

    摘要:习以为常却被忽略的小知识父模板中调用组件的元素将会被组件本身的模板取代。如果需要,可以通过将传入得到深拷贝的原始数据对象。然后,在进入下一次的事件循环时,会清空队列并进行必要的更新。 习以为常却被忽略的vue小知识 root element 父模板中调用组件的元素将会被组件本身的模板取代。因此,如果组件的模板包含多个顶级元素: Vue.component(example, { t...

    fobnn 评论0 收藏0
  • 前端空间 - 收藏集 - 掘金

    摘要:封装手写的方笔记使用检测文件前端掘金副标题可以做什么以及使用中会遇到的坑。目的是帮助人们用纯中文指南实现复选框中多选功能前端掘金作者缉熙简介是推出的一个天挑战。 深入理解 JavaScript Errors 和 Stack Traces - 前端 - 掘金译者注:本文作者是著名 JavaScript BDD 测试框架 Chai.js 源码贡献者之一,Chai.js 中会遇到很多异常处理...

    you_De 评论0 收藏0
  • 前端空间 - 收藏集 - 掘金

    摘要:封装手写的方笔记使用检测文件前端掘金副标题可以做什么以及使用中会遇到的坑。目的是帮助人们用纯中文指南实现复选框中多选功能前端掘金作者缉熙简介是推出的一个天挑战。 深入理解 JavaScript Errors 和 Stack Traces - 前端 - 掘金译者注:本文作者是著名 JavaScript BDD 测试框架 Chai.js 源码贡献者之一,Chai.js 中会遇到很多异常处理...

    lwx12525 评论0 收藏0

发表评论

0条评论

ThreeWords

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<