Vue3中如何渲染动态模板?原Vue2组件迁移后失效求助
解决Vue3动态模板渲染组件迁移问题
问题根源
Vue3移除了Vue2中直接通过{ template: '...' }对象在h()函数中创建动态组件的隐式编译支持,必须显式使用compile函数编译模板字符串为渲染函数,才能正确生成可渲染的组件。
修复步骤及完整代码
- 导入
compile函数:从vue中引入compile,用于编译动态模板字符串。 - 修正模板编译逻辑:将原有的动态组件对象替换为编译后的渲染函数,并正确传递props和注册组件。
- 修复模板转义问题:原代码中使用
</>转义HTML标签会导致模板被解析为文本而非元素,需直接使用</>。
<script> import { defineComponent, h, compile } from 'vue' import { /* 导入你需要的Vuetify组件,比如VButton、VCard等 */ } from 'vuetify/components' import Formatter from '@/framework/util/format' export default defineComponent({ name: 'Template', props: { template: { type: String, required: true // 建议添加必填校验 }, value: { type: null, default: null }, context: { type: Object, default: () => ({}) }, timeZone: { type: String }, allowedAttributes: { type: Object, default: () => ({}) }, allowedTags: { type: Array, default: () => [] }, allowedSchemes: { type: Array, default: () => [] }, format: { type: Object, default: () => ({}) } }, computed: { tmpl() { return this.template }, computedContext() { return { ...this.context, ...(this.timeZone && { timeZone: this.timeZone }) } } }, render() { const formattedTemplate = Formatter.applyFormat( this.tmpl, this.format, this.context ) // 编译模板为渲染函数 const render = compile(`<div>${formattedTemplate}</div>`) // 定义动态组件选项 const dynamicComponent = { render, props: ['value', 'context'], components: { // 注册你需要用到的组件,比如Vuetify组件 /* VButton, VCard, ... */ } } return h(dynamicComponent, { value: this.value, context: this.computedContext }) } }) </script>
额外注意事项
- 模板安全性:动态渲染用户提供的模板存在XSS风险,建议结合你的
allowedTags/allowedAttributes参数,使用HTML净化库对formattedTemplate进行预处理,过滤危险标签和属性。 - 组件注册:确保所有在动态模板中使用的组件都已在
components选项中正确注册,或全局注册,否则会出现组件无法渲染的问题。 - 编译环境:如果是在生产环境中使用,确保你的Vue构建配置支持模板编译(Vue3的运行时版本默认不包含编译器,需使用完整版本或配置构建工具支持编译)。
内容的提问来源于stack exchange,提问作者Abdul Kadir Khan
相关产品推荐
相关产品推荐

