Vue 2.6.12如何像KnockoutJS一样通过模板Id快速渲染内容?
Vue 2.6.12 按模板ID渲染内容的实现方案
Vue 2.6.12 没有提供和KnockoutJS完全一致的、直接绑定模板ID选择器即时渲染的开箱语法,但可以通过官方内置能力组合实现完全相同的效果。你之前自定义quick-template组件渲染失败,核心原因不是props赋值时序问题,是Vue组件选项的初始化规则限制:组件的template选项会在实例初始化阶段完成编译,早于props的赋值流程,所以直接在组件根选项里读取props传入的模板ID取不到有效值。
基础静态渲染实现
如果不需要动态切换模板,可以直接在Vue实例初始化时读取对应ID的script模板内容,写法和Knockout的模板定义逻辑完全兼容:
<!-- 模板定义,和Knockout写法一致 --> <script type="text/html" id="template-example"> <span>Hello world!</span> </script> <!-- 挂载节点 --> <div id="app"></div> <script> new Vue({ el: '#app', // 直接读取指定ID的模板内容 template: document.querySelector('#template-example').innerHTML }) </script>
通用动态模板组件(对齐Knockout template绑定能力)
要实现类似Knockout那种传入模板ID即可动态渲染的能力,可以通过render函数+运行时编译实现通用组件,避开template选项提前编译的问题:
// 注册全局通用模板组件 Vue.component('quick-template', { props: { tplId: { type: String, required: true } }, render(h) { const tplNode = document.querySelector(this.tplId) // 模板不存在时返回空节点 if (!tplNode) return h() // 动态构造组件实例渲染模板内容,支持传入模板数据 return h({ template: tplNode.innerHTML, props: ['tplData'] }, { props: { tplData: this.$attrs.tplData } }) } })
组件使用方式和Knockout的绑定逻辑几乎一致:
<script type="text/html" id="template-example"> <span>Hello {{ tplData?.name || 'world' }}!</span> </script> <!-- 传入模板ID、模板数据即可渲染 --> <quick-template tpl-id="#template-example" :tpl-data="{ name: 'Vue' }"></quick-template>
注意事项
- 上述动态编译方案需要引入带运行时编译器的Vue 2.6.12版本,如果你使用的是runtime-only版本(比如Vue CLI默认配置引入的
vue.runtime.esm.js),不支持前端动态编译template字符串,需要替换为带compiler的版本,或在构建阶段提前把script标签内的模板预编译为渲染函数。 - 可以在组件内增加模板缓存逻辑,同一个ID的模板仅读取解析一次,减少重复编译的性能开销。
内容的提问来源于stack exchange,提问作者Pochen
相关产品推荐
相关产品推荐

