Вот несколько более простых способов сделать то, что вы обычно хотите.Если вы дадите больше подробностей, ваше правильное направление может быть шаблоном стратегии перед одним из этих решений, но, вероятно, вам нужно одно из этих решений:
1) Vue позволяет динамически определять компоненты прямо из коробки, так что эта единственная строка:
<component v-for="(component, index) in components" :key="'component'+index" :is="component.name" v-bind="component.props" />
... будет рисовать группу компонентов в массиве объектов, таких как этот (например): {name: 'myComponentName', props: {foo: 1,bar: 'baz'}}.
2) Vue позволяет внедрять HTML в компоненты, просто добавляя v-html = "variable"
Например, вот компонент, который создает динамический SVGзначки, где содержимое SVG динамически вводится из переменных JavaScript ...
<template>
<svg xmlns="http://www.w3.org/2000/svg"
:width="width"
:height="height"
viewBox="0 0 18 18"
:aria-labelledby="name"
role="presentation"
>
<title :id="name" lang="en">{{name}} icon</title>
<g :fill="color" v-html="path">
</g>
</svg>
</template>
<script>
import icons from '../common/icons'
export default {
props: {
name: {
type: String,
default: 'box'
},
width: {
type: [Number, String],
default: 18
},
height: {
type: [Number, String],
default: 18
},
color: {
type: String,
default: 'currentColor'
}
},
data () {
return {
path: icons[this.name]
}
},
created () {
console.log(icons)
}
}
</script>
<style scoped>
svg {
display: inline-block;
vertical-align: baseline;
margin-bottom: -2px;
}
</style>
3) Vue позволяет динамически определять шаблон компонента с помощью этого. $ options.template:
export default {
props: ['name', 'props'],
template: '',
created(){
this.$options.template = `<component :is="name" ${props.join(' ')} ></component>`
},
}
4) Vue позволяет вам определить функцию рендеринга, поэтому прокси-компоненты или другие продвинутые махинации тривиальны:
Vue.component('component-proxy', {
props: {
name: {
type: String,
required: true
},
props: {
type: Object,
default: () => {}
}
},
render(h) {
// Note the h function can render anything, like h('div') works too.
// the JS object that follows can contain anything like on, class, or more elements
return h(this.name, {
attrs: this.props
});
}
});
Умный гений написал для этого jsbin: http://jsbin.com/fifatod/5/edit?html,js,output
5) Vue позволяетчтобы создать компоненты с помощью Vue.extend или даже передать необработанные объекты JavaScript в раздел компонентов страницы или приложений, например, который создает компонент с именем «foo» из простой строки для шаблона и массива для реквизитов, вы также можетеРасширить данные, созданные, и т. д. таким же образом, используя только объект JS:
new Vue({
el: '#app',
data: {
foo: 'bar',
props: {a: 'a', b: 'b'}
},
components: {
foo: {
template: '<p>{{ a }} {{ b }}</p>',
props: ['a', 'b']
}
}
})