You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Vue.js实例动态应用创建的模板?解决动态渲染失效问题

嘿,这个问题我之前也碰到过!核心原因其实很简单——Vue在初始化实例的时候,只会编译挂载时已经存在于DOM里的模板内容。你动态创建的dynamicTemplate是在Vue初始化完成后才塞到页面里的,Vue根本没察觉到这部分新内容,自然不会去编译它,所以secondPlaceholder就没被正确渲染出来。

接下来给你几个靠谱的解决方案,按需选就行:


方案一:手动编译+挂载动态模板(最直接)

直接用Vue的Vue.compile把动态模板编译成渲染函数,然后创建一个子Vue实例挂载到目标容器上,这样就能让Vue处理动态模板里的插值了:

<!doctype html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <div id="firstPlaceholder"></div>
    <div id="secondPlaceholder"></div>
  </div>

  <script type="text/x-template" id="staticTemplate">
    <div>{{ text }}</div>
  </script>

  <script>
    const app = new Vue({
      el: '#app',
      data: {
        text: 'Hello Vue!'
      },
      mounted() {
        // 静态模板正常渲染
        this.$mount('#firstPlaceholder');

        // 处理动态模板
        const dynamicTemplate = `<div>{{ text }}</div>`;
        // 编译动态模板得到渲染函数
        const compiledTemplate = Vue.compile(dynamicTemplate);
        // 创建子实例并挂载到secondPlaceholder
        new Vue({
          render: compiledTemplate.render,
          staticRenderFns: compiledTemplate.staticRenderFns,
          // 可以直接复用父组件的data,或者自己定义
          data: () => ({ text: this.text })
        }).$mount('#secondPlaceholder');
      }
    });
  </script>
</body>
</html>

方案二:用动态组件渲染(更符合Vue风格)

如果你的动态模板需要复用,或者想更贴合Vue的组件化思想,可以把动态模板封装成一个组件,然后通过<component>标签动态渲染:

<!doctype html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <div id="firstPlaceholder"></div>
    <!-- 用动态组件渲染 -->
    <component :is="dynamicComp"></component>
  </div>

  <script type="text/x-template" id="staticTemplate">
    <div>{{ text }}</div>
  </script>

  <script>
    const app = new Vue({
      el: '#app',
      data: {
        text: 'Hello Vue!',
        dynamicComp: null
      },
      mounted() {
        // 静态模板渲染
        this.$mount('#firstPlaceholder');

        // 动态注册组件
        this.dynamicComp = Vue.component('dynamic-template', {
          template: `<div>{{ text }}</div>`,
          data: () => ({ text: this.text })
        });
      }
    });
  </script>
</body>
</html>

补充:Vue 3的适配

如果是用Vue 3,API稍微有点变化,Vue.compile变成了直接导入compile方法,挂载方式也更简洁,核心思路还是一样的——手动让Vue编译动态模板内容,比如:

import { createApp, compile } from 'vue'

const app = createApp({
  data() {
    return { text: 'Hello Vue 3!' }
  },
  mounted() {
    const dynamicTemplate = `<div>{{ text }}</div>`
    const { render } = compile(dynamicTemplate)
    // 创建子应用挂载到目标元素
    createApp({ render, data: () => ({ text: this.text }) }).mount('#secondPlaceholder')
  }
}).mount('#app')

最后提醒一句:如果动态模板的内容是用户输入的,一定要做好XSS防护,别让恶意代码钻空子哦!

内容的提问来源于stack exchange,提问作者Stefan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:30:14