简体   繁体   中英

Vuejs how to use dynamical template in component?

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM