How can Vue.js leverage dynamic templates within a 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 need assistance with rendering a dynamic template based on user input to display a custom component.

If a specific string like [:component-1] is entered by the user, it should render as a CustomComponent.

Can someone provide guidance on how to achieve this functionality?

Your help is greatly appreciated!

Answer №1

Check out the v-slot feature in Vue.js
https://v2.vuejs.org/v2/guide/components-slots.html

Here's an example:
Parent:

<child-component v-html="myTemplate">
    <span>From parent</span>
</child-component>

Child:

<div>
    <v-slot></v-slot> //This will show "<span>From parent</span>"
</div>

**Additional explanation
You can customize myTemplate based on conditions. The example "

<span>From parent</span>
" is just for illustrative purposes.


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>

Answer №2

I successfully resolved this issue using the Vue.compile method

as described in this helpful post about dynamically fetching and compiling a template with Nuxt

const UserInputResult = {
  props: ['templateString'],
  render(h){
    return h({
      components: {
        CustomComponent
      },
      template: `<section>${this.templateString}</section>`
    });
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Discover the power of JQuery Mobile for implementing swipe functionality exclusively

Dealing with the jquery mobile pack has caused some major headaches for me. It completely disrupted my page by automatically turning links into ajax calls and displaying loading animations. After spending a significant amount of time trying to fix everythi ...

Manipulating visibility of an input tag using JQuery

Having a simple input tag: <input id="DAhour" type="number" style="width:50px; font-size: xx-small; visibility:hidden"> Initially, the input tag is set to be hidden. Upon changing a combobox to a specific index, it should become visible. Despite su ...

The render() method of the component is failing to execute even after the mobx store value has been updated

After successfully updating the store before fetching data from the server, everything seems to be working fine. However, once the data is fetched and the store is updated again, the render() method does not get called. Check out this code snippet @acti ...

React JS is not allowing me to enter any text into the input fields despite my attempts to remove the value props

Currently, I am working on creating a Contact Form using React Js. I have utilized react bootstrap to build the component, but unfortunately, when attempting to type in the input fields, the text does not change at all. import React, {useState} from ' ...

Completing a submission on a bootstrap form, using innerHTML and displaying an alert

I am currently having an issue with navigating to the home page after submitting a form in Bootstrap. Although I have successfully implemented an alert message upon submission, the page does not redirect to the home page as expected. Instead, it redirects ...

How can I make a variable available on the client side by exporting it from my Node JS server built with express framework?

How can I send a variable from my Node JS server, which is built using Express, to be accessed on the client side? I need this variable to hold a value stored locally on the server and then access it in my client side JavaScript code. I discovered that ...

Guide on how to retrieve Twitter Username and Profile Photo through the Twit NPM Package

Utilizing the twit npm package to retrieve the Authenticated Twitter Username and Profile Image, here is the code I am using: const Twit = require('twit'); let T = new Twit({ consumer_key: 'xxx', ...

Using AngularJS to handle click events and blur events

I am attempting to dynamically change the class based on user interaction in my code. The class should switch between "large" and "active" depending on whether the input field is filled or not. Please see the modified script below. <div class="snippe ...

Using a static value in the comparator is necessary for Array.find to function properly in Typescript

Looking to retrieve an item from an array: const device = this.selectedDevtype.devices.find(item => console.log(this.deviceID); return item.device_id === this.deviceID; }); console.log(device); When this.deviceID is logged, it shows "4", but t ...

analyzing whether the window.close spy is being invoked or not during testing operations

When it comes to unit testing my Vue component's methods using vitest and Vue test utils, there is a specific scenario I am working on. It involves a button triggering a call to a close() method, which in turn invokes the browser's window.close() ...

Utilizing JavaScript and its scope to include text within an HTML document

I am currently working on a program that receives input from the user twice, specifically a risk carrier and a sum (although it is just a placeholder for now), groups these two values together, and then repeats the contents in a loop. You can see the progr ...

Transferring JSON information from JavaScript to PHP using Jquery AJAX

Struggling to send JSON data from JavaScript to a PHP script using the code below. While debugging, "isRunning" initially shows true, indicating that AJAX is not running. However, when it moves to the next part of the AJAX code, "isRunning" changes to fal ...

Attempting to grasp the intricacies of HTML5/JS video playback quality

I've been diving deep into research on this topic, but I can't seem to find a straightforward answer to my specific query. My main focus is understanding the inner workings of how video players transition between different quality settings (480p, ...

Ways to calculate the total number of keys within a JSON object at a certain level

I need to process a JSON file by extracting values from keys located at a specific depth. The initial value I want to access is situated here: json.children[0].children[0].children[0] Is there a method to navigate through the JSON object at a particular ...

Exploring the Dynamic Display of Nested JSON Objects in Angular 6

Struggling with a complex issue and feeling lost on how to approach it. I'm currently working with Angular 6. The challenge at hand involves handling JSON data in my project. While accessing simple data like "id" or "certificate" is easy, I'm en ...

I aim to generate a JavaScript string that, when placed within a div tag, will display as a list

I need assistance with formatting a string that contains a list of items to display in a specific way within a div tag using JavaScript. The string has multiple items that I wish to show as a bulleted list. Here is an example of the string: const items = & ...

Can you explain the distinction between the GenerateSW and InjectManifest choices within the vue ui pwd configuration?

Currently utilizing @vue/cli for building a vue project. I have initiated vue ui to access the vue UI and am in the process of customizing various available options. https://i.sstatic.net/h77AE.png Within Configuration -> PWA, I have come across the a ...

Can you explain the functionality of this Angular JS code snippet?

How is it possible that the following code snippet works in Angular JS? var app = angular.module('store',[]); (function(){ app.controller('StoreController',function(){ this.blabla = student; }); })(); var student = ...

Is there a technique to block small increments in a Time Input field?

Currently in the process of developing a tool to automate task scheduling within an Angular app. I am looking for a way to restrict the user's input when selecting the hour for task execution without having to install a complex input management packag ...

What is the equivalent of {...props} in React for destructuring props in Vue?

When working in React, I can destructure props with ease: function MyComponent() { const myProp = { cx: '50%', cy: '50%', r: '45%', 'stroke-width': '10%' } return ( <svg> ...