<template>
<div>
<!-- 这里是动态组件-->
<component :is="component"></component>
<!-- 这里是动态组件-->
<br />
<br />
<br />
可以理解为是一个vue模拟器 虚拟机
以上是渲染的内容, 修改以下内容会实时动态渲染上边的组件 vue代码中怎么写 这里就怎么写 当成编辑器
这里用的是https://1x.antdv.com/components/input-cn/ UI库 VUE2
<p>模板内容: template 中的内容</p>
<a-textarea v-model="virtualTemplateStr" :rows="15" />
<p>data内容:</p>
<a-textarea v-model="virtualDataStr" :rows="15" />
<p>methods内容:</p>
<a-textarea v-model="virtualMethodsStr" :rows="15" />
<p>other 其他内容:</p>
<a-textarea v-model="virtualOtherStr" :rows="15" />
</div>
</template>
<script>
//动态模板中 使用到的组件 需要提前引入
/**
* 然后使用 components
* components: {
* 'a-progress': AProgress, // 在动态组件中注册组件
* },
*/
import Vue from 'vue';
//这里如果之前全局引用过 则不用再引用
import Antd from 'ant-design-vue';
//这里如果之前全局引用过 则不用再引用
import 'ant-design-vue/dist/antd.css';
Vue.use(Antd);
export default {
data() {
return {
/**
* 模板内容 str形式的
*/
virtualTemplateStr: `
<div>
<h1>{{消息内容}}</h1>
<a-button @click="changeMessage">点击改变消息内容 并打印组件相关日志F12查看控制台</a-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>
`,
/**
* 虚拟组件data数据
*/
virtualDataStr: `
{
//这里this指向是当前页面的this 而不是虚拟组件的this 所以用这个可以访问当前页面的属性方法等
//也可以使用 this.$parent 获取
父组件this: this,
消息内容: 'Hello from templateString!',
//这里可以添加更多变量
}
`,
virtualMethodsStr: `
{
/**
* 改变消息内容
*/
changeMessage() {
//this.speak()
// this.父组件this.speak()
//调用真实页面的方法 同 this.父组件this.speak()
this.$parent.speak()
console.info('真实页面的this:', this.$parent)
console.info('当前虚拟组件页面的this:', this)
// 动态导入 AProgress 组件 这里是不行的, 必须在上层VUE中引入组件 然后通过 components的方式引入
// const AProgress = await import('ant-design-vue/lib/progress');
this.消息内容 = '我是改变之后的消息' + new Date();
},
// 可以在这里添加更多的方法
test(){
alert('我是虚拟组件test方法')
}
}
`,
/**
* 其他内容 例如
*
* created () {
* this.createDynamicComponent()
* },
* watch: {
*
* }
*
*/
virtualOtherStr: `
{
}
`,
component: null
};
},
created() {
this.createDynamicComponent()
},
/**
* 监听
*/
watch: {
virtualTemplateStr(newStr) {
this.createDynamicComponent();
},
virtualDataStr(newStr) {
this.createDynamicComponent();
},
virtualMethodsStr(newStr) {
this.createDynamicComponent();
},
},
methods: {
speak(){
console.log('我是真实页面的方法')
},
/**
* 创建动态组件
* @returns {any}
*/
async createDynamicComponent() {
// 动态导入 AProgress 组件
const AProgress = await import('ant-design-vue/lib/progress');
//动态解析data字符串
let tdata = eval('(' + this.virtualDataStr + ')');
let tMethods = eval('(' + this.virtualMethodsStr + ')');
let tOther = eval('(' + this.virtualOtherStr + ')');
// 使用 Vue.component 创建动态组件
this.component = Vue.component('dynamic-component', {
//动态解析模板内容
template: this.virtualTemplateStr,
data() {
//注入data数据
return tdata
},
/**
* 引入组件
*/
components: {
'a-progress': AProgress.default, // 在动态组件中注册组件
},
methods: tMethods,
...tOther
});
},
}
};
</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.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.