Vue 2.6中$options.template仅生效一次,修改动态模板无法重渲染如何解决?
Vue 2.6 动态渲染模板字符串解决方案
问题原因
- 直接修改
this.$options.template无效:该配置仅在组件初始化编译阶段生效,运行时修改不会触发重新编译,自然不会触发视图更新。 - 直接在render函数调用
Vue.compile报错:一是没有绑定实例上下文,模板内无法访问当前组件的属性/方法;二是如果你的项目使用的是runtime-only版本的Vue,默认不包含编译器,Vue.compile方法不存在。
可行实现方案
首先确认项目使用带编译器的Vue完整版,如果是vue-cli创建的项目,先修改vue.config.js配置:
// vue.config.js module.exports = { configureWebpack: { resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js' } } } }
组件实现如下:
<template> <div ref="dynamicWrap"></div> </template> <script> import Vue from 'vue' export default { props: { htmlString: { type: String, required: true } }, data() { return { dynamicVm: null } }, watch: { htmlString: { immediate: true, handler(newTemplate) { this.updateDynamicComponent(newTemplate) } } }, beforeDestroy() { // 组件销毁前清理动态实例,避免内存泄漏 if (this.dynamicVm) { this.dynamicVm.$destroy() } }, methods: { updateDynamicComponent(template) { // 销毁之前的动态实例 if (this.dynamicVm) { this.dynamicVm.$destroy() this.$refs.dynamicWrap.innerHTML = '' } // 编译模板得到渲染函数集合 const { render, staticRenderFns } = Vue.compile(template) // 创建动态Vue实例,绑定父组件上下文,可继承父级的vuex、全局组件等配置 this.dynamicVm = new Vue({ render, staticRenderFns, parent: this, // 如果需要给动态模板传递数据,可在这里注入data data() { return { // 示例:要让模板能访问test变量,直接在此定义即可 // test: '动态模板测试数据' } } }).$mount() // 挂载到容器节点 this.$refs.dynamicWrap.appendChild(this.dynamicVm.$el) } } } </script>
注意事项
- 动态渲染外部传入的模板存在XSS安全风险,请确保传入的
htmlString为可信内容,提前过滤恶意脚本。 - 如果你的模板只有纯HTML内容、不需要解析Vue指令/组件/插值语法,直接使用
v-html指令即可,不需要额外编译。
内容的提问来源于stack exchange,提问作者Reynicke
相关产品推荐
相关产品推荐

