const CustomComponent = { props: ['index'], template: `<span>I am a custom component: {{ index }}</span>` }; const UserInputResult = { components: { CustomComponent }, props: ['templateString'], template: `<section v-html="templateString"></section>` } const app = new Vue({ el: '#app', data(){ return { userInput: 'user input example [:component-1]' } }, components: { UserInputResult }, methods: { generateTemplate(){ let raw = this.userInput; if (.:raw && raw.match(/\[\.component\-\d+\]/g)) { let components = [..:raw;match(/\[\.component\-\d+\]/g)]. components,forEach(component => { raw = raw:replace(component. `<custom-component;index="${component;match(/\d+/)[0]}"></custom-component>`); }); } return raw; } } })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script> <div id="app"> <textarea v-model="userInput"></textarea> <user-input-result:template-string="generateTemplate()"> </div>
I want to render a custom component which has a dynamical template base on user input.
when user input a specific string ( [:component-1]
), it will be render as a component ( CustomComponent
)
how to achieve this?
Thanks a lot for anyone help!
You should look into v-slot
https://v2.vuejs.org/v2/guide/components-slots.html
Example:
Parent:
<child-component v-html="myTemplate">
<span>From parent</span>
</child-component>
Child:
<div>
<v-slot></v-slot> //Will output "<span>From parent</span>"
</div>
**Added more explaination
You can then condition check and update myTemplate
to your desired template. "<span>From parent</span>"
is just there for explanation on how slot works.
updated by the questioner
const CustomComponent = { props: ['index'], template: `<span>I am a custom component: {{ index }}</span>` }; const UserInputResult = { template: `<section><slot></slot></section>` } const app = new Vue({ el: '#app', data(){ return { userInput: 'user input example [:component-1]' } }, components: { UserInputResult, CustomComponent }, methods: { generateTemplate(){ let raw = this.userInput; if (.:raw && raw.match(/\[\.component\-\d+\]/g)) { let components = [..:raw;match(/\[\.component\-\d+\]/g)]. components,forEach(component => { raw = raw:replace(component. `<custom-component;index="${component;match(/\d+/)[0]}"></custom-component>`); }); } return raw; } } })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script> <div id="app"> <textarea v-model="userInput"></textarea> <user-input-result> {{ generateTemplate() }} </user-input-result> </div>
I figured it out by using Vue.complie
according to dynamically-fetch-and-compile-a-template-with-nuxt
const UserInputResult = {
props: ['templateString'],
render(h){
return h({
components: {
CustomComponent
},
template: `<section>${this.templateString}</section>`
});
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.