什么是<template>
元素?
<template>
是2013年定稿用于提供一种更统一、功能更强大的模板本存放方式。具体表现为
通过
<template>
元素属性content
获取已实例化的HTML元素(不是字符串而已)<template id="tpl"> <div>a</div> <div>b</div> </template> <script> const tpl = document.getElementById('tpl') tpl.content // document-fragment tpl.content.children[0].outerHTML // <div>a</div> </script>
<template>
以及其子节点均不可视<template>
下的img元素的src
属性即使有值也不会发出资源请求<template>
下的script和css规则均不会解析和执行
更多信息请查看:《HTML语义化:HTML5新标签——template》
v-if
搭配<template>
<div v-scope="App"></div>
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp({
App: {
$template: `
<template v-if="status === 'offline'">
<span> OFFLINE </span>
</template>
<template v-else>
<span> ONLINE </span>
</template>
`,
}
status: 'online'
}).mount('[v-scope]')
</script>
首次渲染过程如下:
将通过walk.ts中的
resolveTemplate
方法将App.$template
渲染到DOM树上<div v-scope="App"> <template v-if="status === 'offline'"> <span> OFFLINE </span> </template> <template v-else> <span> ONLINE </span> </template> </div>
解析子节点
<template v-if="status === 'offline'"></template>
- 进入directives/if.ts识别附着
v-if
、v-else
的元素,并将它们从DOM树中移除 - 根据条件表达式
status === 'offline'
对以离线节点(Dettached Node)<template v-else></template>
为基础创建块对象(Block)
<div v-scope="App"> </div>
- 进入directives/if.ts识别附着
在块对象的构造函数中会识别
<template>
元素,并通过content.cloneNode
方法复制<template>
的子节点作为模板,进行后续解析处理<div v-scope="App"> </div>
最后directives/if.ts里会将块对象插入父节点中且位于锚点元素前面
<div v-scope="App"> <span> ONLINE </span> </div>
小结
- 这里利用的是
<template>
元素本身的特性实现在线解析用户不可见(你看不到我,你看不到我:D),和避免如<img src="logo.png">
发送无效请求的问题; - 由于
<template>
是在block.ts中处理获取模板,因此v-for
搭配<template>
的原理和v-if
是一致的。
错误使用
虽然<template>
能帮助我们优化用户体验和性能,但有些时候也会让我们掉到坑里面,下面一起绕过这些坑吧!
<div v-scope="App"></div>
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp({
App: {
$template: `
<template>
<div>Hello</div>
</template>
`,
}
status: 'online'
}).mount('[v-scope]')
</script>
根块对象对应的是<div v-scope="App"></div>
,而<template>
由于没有附加v-if
或v-for
,因此不会为其创建新的块对象进行处理,最后得到的UI就是这样的:
<div v-scope="App">
<template>
<div>Hello</div>
</template>
</div>
用于无法看到文字Hello。
总结
通过本篇内容的介绍,我们记得<template>
必须搭配v-if
或v-for
使用哦!
后面我们将探索@vue/reactivity在petite-vue的使用,敬请期待。
尊重原创,转载请注明来自:https://www.cnblogs.com/fsjoh... 肥仔John
《Petite-Vue源码剖析》小册子
《Petite-Vue源码剖析》结合示例从在线渲染、响应式系统和沙箱模型分别对源码逐行解读,其中还对响应式系统中利用JS引擎的SMI优化依赖清理算法作详细分析。绝对是入门Vue3源码前绝佳的踏脚石喜欢的话记得转发、赞赏哦!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。