Vue3 的模板编译也可以发生在运行时
#vue3
目录
R1
Vue3 的模板编译通常是在构建时完成的,而不是运行时,但不是绝对的,我们可以打包==两个版本Vue==
- runtime-only:
- 仅包含运行时,体积更小,当然性能也更好
- runtime + compiler:
- 包含编译器代码,体积更大,当然性能也更好
之前做个 markdown 嵌入 vue组件时,就使用过构建时,将 markdown → html → 特定 vdom → 特定的vue组件 → 渲染
2. 构建时编译(推荐)
// 单文件组件 (.vue)
<template>
<div>{{ message }}</div>
</template>
// 会在构建时被编译成
import { createVNode, toDisplayString } from 'vue'
export function render(_ctx, _cache) {
return createVNode("div", null, toDisplayString(_ctx.message))
}
3. 运行时编译(不推荐)
// main.js
import { createApp } from 'vue/dist/vue.esm-bundler.js' // 包含运行时编译器的版本
createApp({
template: `<div>{{ message }}</div>` // 这种情况会在运行时编译
}).mount('#app')
4. 两种版本的区别
// 1. 仅运行时版本(推荐,体积更小)
import { createApp } from 'vue' // 约 14kb gzipped
// 2. 完整版本(包含编译器,体积更大)
import { createApp } from 'vue/dist/vue.esm-bundler.js' // 约 23kb gzipped
5. 开发环境配置
// vite.config.js
export default {
resolve: {
alias: {
'vue': 'vue/dist/vue.runtime.esm-bundler.js' // 使用仅运行时版本
}
}
}
6. 性能对比
// 1. 构建时编译(更好的性能)
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>
// 2. 运行时编译(需要额外的编译开销)
const app = createApp({
template: `
<button @click="count++">{{ count }}</button>
`,
setup() {
const count = ref(0)
return { count }
}
})
7. 特殊场景:动态模板 和 动态渲染
// 1. 动态模板(需要运行时编译)
const DynamicComponent = {
props: ['template'],
render() {
const { h } = Vue
if (this.template) {
// 不推荐:这种情况需要运行时编译
return h({
template: this.template,
data() {
return this.$props
}
})
}
return h('div', 'No template provided')
}
}
// 2. 推荐的动态渲染方式
const DynamicComponent = {
props: ['content'],
render() {
// 使用渲染函数或 JSX
return h('div', this.content)
}
}
8. 编译优化
// 构建时编译可以进行的优化
<template>
<div>Static Content</div>
<div>{{ dynamic }}</div>
</template>
// 编译后
export function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock(_Fragment, null, [
_createElementVNode("div", null, "Static Content", -1 /* HOISTED */),
_createElementVNode("div", null, _toDisplayString(_ctx.dynamic), 1 /* TEXT */)
], 64 /* STABLE_FRAGMENT */))
}
9. 总结
- 默认情况:
- Vue3 默认在构建时完成模板编译
- 使用 Vite 或 webpack 等构建工具时自动处理
- 性能考虑:
- 构建时编译可以减少运行时开销
- 减少最终包的体积
- 允许更多的编译时优化
- 不同版本:
- runtime-only:仅包含运行时,体积更小
- runtime + compiler:包含编译器,体积更大
- 最佳实践:
- 尽可能使用单文件组件(.vue)
- 避免运行时编译
- 特殊场景下才考虑使用完整版本
- 例外情况:
- 需要动态编译模板的场景
- 不使用构建工具的简单项目
- 特殊的开发需求