Javascript 如何以编程方式间接创建Vue组件
我正在尝试以编程方式将组件添加到我的Vue单文件组件中的一个页面中,如果您提前知道要做什么,该组件的工作效果会非常好。在我的例子中,组件及其布局将通过JSON接收,我正在尝试动态创建它们。下面你可以看到,我想做一些类似eval的事情,但不幸的是,这不适用于未实例化的对象。下面的代码使用硬编码值进行简化,以获得点Javascript 如何以编程方式间接创建Vue组件,javascript,vue.js,Javascript,Vue.js,我正在尝试以编程方式将组件添加到我的Vue单文件组件中的一个页面中,如果您提前知道要做什么,该组件的工作效果会非常好。在我的例子中,组件及其布局将通过JSON接收,我正在尝试动态创建它们。下面你可以看到,我想做一些类似eval的事情,但不幸的是,这不适用于未实例化的对象。下面的代码使用硬编码值进行简化,以获得点 <template> <div id="app"> <h2>Static template:</h2> <Inp
<template>
<div id="app">
<h2>Static template:</h2>
<InputTemplate type="text"></InputTemplate>
<h2>Dynamically inserted:</h2>
<div ref="container">
<button @click="onClick">Click to insert</button>
<br/>
</div>
</div>
</template>
<script>
import Vue from 'vue'
//the component I'd like to create
import InputTemplate from './components/InputTemplate.vue'
export default {
name: 'app',
components: { InputTemplate },
methods: {
onClick() {
//I'd like to do something like this, but eval doesn't work like this
var ComponentClass = Vue.extend(eval('InputTemplate'))
var instance = new ComponentClass({
propsData: {type: 'text' }
})
instance.$mount()
this.$refs.container.appendChild(instance.$el)
}
}
}
</script>
您可以使用通过API检索组件
我已经通过Axios使用GraphQL进行了测试,但它应该可以与任何REST服务一起使用
主要组件如下所示:
<template>
<div>
<h1>Test page</h1>
<div><button @click="clicked = true">Load component</button></div>
<async-component v-if="clicked" />
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
clicked: false,
};
},
components: {
'async-component': () => axios.post('http://localhost:5000/graphql', { query: `
{
asyncComponentByRowId(rowId: 1) {
component
content
}
}
`,
}).then((response) => {
const comp = response.data.data.asyncComponentByRowId.content;
// eval can be harmful
return eval(`(${comp})`);
}),
},
};
</script>
当按下按钮时,从API异步下载后将显示组件
唯一的问题是我正在使用eval
解码对象
结果:
事实证明,Vue有
,如果您将它放入v-for
循环,它正是我希望实现的 你试过了吗?如果我理解正确,使用异步组件将允许我根据需要动态导入组件,方法是使用类似于myComponent:()=>import(myComponent)
?我自己没有试过,但这也是我的理解方式。我认为可以用另一个函数替换import
函数,该函数返回一个Promise中的组件对象。
<template>
<div>
<h1>Test page</h1>
<div><button @click="clicked = true">Load component</button></div>
<async-component v-if="clicked" />
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
clicked: false,
};
},
components: {
'async-component': () => axios.post('http://localhost:5000/graphql', { query: `
{
asyncComponentByRowId(rowId: 1) {
component
content
}
}
`,
}).then((response) => {
const comp = response.data.data.asyncComponentByRowId.content;
// eval can be harmful
return eval(`(${comp})`);
}),
},
};
</script>
{
"data": {
"asyncComponentByRowId": {
"component": "my-async-component",
"content": "{\r\n\ttemplate: '<div>{{ msg }}</div>',\r\n\tdata: function() {\r\n\t\treturn {\r\n\t\t\tmsg: 'Async component works!'\r\n\t\t};\r\n\t}\r\n}"
}
}
}
{
template: '<div>{{ msg }}</div>',
data: function() {
return {
msg: 'Async component works!'
};
}
}