【前端】VUE动态引入组件 通过字符串动态渲染模板

应用场景:

js增强 动态代码 扩展一类的  可以配合低代码平台等  灵活配置在线表单  在线列表等 适合灵活性 扩展性比较强的组件

【前端】VUE动态引入组件 通过字符串动态渲染模板 动态生成组件_Vue

VUE2

<template>
  <div>
    <textarea v-model="templateString"></textarea>
    <div>
      <component :is="component"></component>
    </div>
  </div>
</template>

<script>
import Vue from 'vue';

//这里如果之前全局引用过 则不用再引用
import Antd from 'ant-design-vue';
//这里如果之前全局引用过 则不用再引用
import 'ant-design-vue/dist/antd.css';

Vue.use(Antd);

export default {
  data() {
    return {
      templateString: `
        <div>
          <h1> message </h1>
          <button>Change Message</button>
            <a-progress :percent="30" />
            <a-progress :percent="50" status="active" />
            <a-progress :percent="70" status="exception" />
            <a-progress :percent="100" />
            <a-progress :percent="50" :show-info="false" />
          </div>
      `,
      component: null
    };
  },
  watch: {
    templateString(newTemplate) {
      if (newTemplate) {
        console.log('渲染', newTemplate)
        this.createDynamicComponent(newTemplate);
      }
    }
  },
  methods: {
    createDynamicComponent(templateString) {

      // 使用 Vue.component 创建动态组件
      this.component = Vue.component('dynamic-component', {
        template: templateString
      });


    },
  }
};
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
使用带编译器的 Vue 版本

你可以使用包含模板编译器的 Vue 版本,它支持直接编译模板字符串。你需要在 vue.config.js 中指定这一点:

module.exports = { runtimeCompiler: true };
  • 1.

这样你就可以使用包含编译器的 Vue 版本,并且可以动态编译模板字符串。

VUE3

<template>
  <div>
    <textarea v-model="templateString"></textarea>
    <div>
      <dynamic-component :is="dynamicComponentId"></dynamic-component>
    </div>
  </div>
</template>

<script>
import { defineAsyncComponent } from "vue";

export default {
  data() {
    return {
      templateString: `
        <template>
          <div>
            <h1>{{ message }}</h1>
            <button @click="changeMessage">Change Message</button>
          </div>
        </template>
        
        <script>
        export default {
          data() {
            return {
              message: "Hello from dynamic component!"
            };
          },
          methods: {
            changeMessage() {
              this.message = "Message changed!";
            }
          }
        };
        </script>
      `,
      dynamicComponentId: null
    };
  },
  watch: {
    templateString(newTemplate) {
      if (newTemplate) {
        this.createDynamicComponent(newTemplate);
      }
    }
  },
  methods: {
    createDynamicComponent(templateString) {
      const DynamicComponent = defineAsyncComponent(() => {
        return new Promise((resolve, reject) => {
          try {
            // 解析模板字符串为组件定义
            const componentDefinition = JSON.parse(
              JSON.stringify({
                template: templateString,
                data: () => ({
                  message: "Initial message"
                })
              })
            );
            
            resolve(componentDefinition);
          } catch (error) {
            console.error("Error parsing template string:", error);
            reject(error);
          }
        });
      });

      // 设置动态组件 ID
      this.dynamicComponentId = DynamicComponent;
    }
  }
};
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.

错误提示

"export 'defineAsyncComponent' was not found in 'vue'
需要使用VUE3