Learn the process of dynamically wrapping component content with HTML tags in Vue.js

Hey there! I'm looking to enclose the content of a component with a specific HTML tag, let's say button for this scenario.

I have a function that dynamically returns a value which I use as a prop. Based on that, I want to wrap the component's content.

I am aware that I could achieve this by doing something like

<button><compA/></button>
, but that doesn't work for me because it would require changing it in multiple places.

This is what I expect:

  1. <button><div>press me i'm button</div></button>
  2. <div>don't wrap me with button leave me as it is</div>

Note: Setting :wrappwithbutton="" to true for the first case and false for the second case.

const localComponent = {
     name:'first-comp',
     template:`<div> {{text}}</div>`,
     props:['wrappwithbutton','text'],
}



const app = new Vue({
   el:'#app',
   name:'app',
  components:{'first-comp':localComponent},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>


  <div id="app">

    <first-comp :wrappwithbutton="true" text="press me i'm button"></first-comp>
    
    <br/>
    <hr/>
    <br/>
    
       <first-comp :wrappwithbutton="false" text="don't wrap me with button leave me as it is"></first-comp>

 </div>

Answer №1

Here is a great illustration of how render functions can be used effectively. Rather than relying on a pre-defined template, you have the option to utilize a render function to generate the template dynamically for you. Explore more about render functions

const customComponent = {
 name:'custom-comp',
 props:['wrappwithbutton', 'text'],
 methods: {
   btnClick() {
     if (this.wrappwithbutton) console.log('button')
   }
 },
 render(h) {
   return h(this.wrappwithbutton ? 'button' : 'div', [
     h('div', this.text)
   ])
 }
}

const app = new Vue({
  el:'#app',
  name:'app',
  components:{'custom-comp':customComponent},
});

Vue.config.productionTip = false
Vue.config.devtools = false

You can take it a step further by enhancing your customComponent to be more versatile with the parent passing a prop specifying the element to be rendered:

const localComponent = {
 name:'first-comp',
 props:['tag', 'text'],
 methods: {
   btnClick() {
     if (this.wrappwithbutton) console.log('button')
   }
 },
 render(h) {
   return h(this.tag, [
     h('div', this.text)
   ])
 }
}

If you prefer to have just a single div instead of two divs, you can achieve that like so:

render(h) {
   if (this.tag === 'div') {
     return ('div', this.text);
   }

   return h(this.tag ? 'button' : 'div', [
     h('div', this.text)
   ])
}

Answer №2

My suggestion is to streamline the template for better readability

const myComponent = {
  name: "my-comp",
  template: `
    <template v-if="displayButton">
      <button>
        <div> {{content}}</div>
      </button>
    </template>
    <template v-else>
      <div> {{content}}</div>
    </template>
  `,
  props: ["displayButton", "content"]
};

const vueApp = new Vue({
  el: "#app",
  name: "myApp",
  components: { "my-comp": myComponent }
});

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

Displaying Image Previews in Rails View Using JavaScript

I am working on a functionality where I have a text_field that contains the URL of an image. The goal is to load this URL into an img tag and update the preview image when the user changes the URL in the text field. Below is the relevant erb code for the ...

There was an issue with the Google Maps embed API that resulted in an error with interpolation

My goal is to utilize the Google Maps API in order to showcase a map using data from a JSON file. However, whenever I attempt to incorporate the JSON data, an error message 'Error: [$interpolate:noconcat] Error while interpolating' pops up. < ...

What is the method to make a CSS selector avoid selecting a specific element?

Let's say I have a CSS style that looks like this: input.validation-passed {border: 1px solid #00CC00; color : #000;} The JavaScript validation framework I am using injects every input tag with a class="validation-passed". While this works fine ...

Tips for successfully sending an API request using tRPC and NextJS without encountering an error related to invalid hook calls

I am encountering an issue while attempting to send user input data to my tRPC API. Every time I try to send my query, I receive an error stating that React Hooks can only be used inside a function component. It seems that I cannot call tRPC's useQuer ...

Error encountered while submitting ajax request to server

When I click a button, a function is triggered with the argument insertSongPlay(newSong.songID);. After logging the value of newSong.songID, which is 90 as desired, an ajax call is made: function insertSongPlay(songID) { $.ajax ({ type: " ...

How to dynamically add events to a JQuery FullCalendar using a loop

When utilizing the jQuery full calendar, I need to dynamically set events based on data obtained from a database. To achieve this, I am using data attributes to assign values and then display them on the calendar. Below is an example of my html twig code: ...

Encountering an unexpected token error while building an Angular4 --prod project that involves Three

Encountering an error while trying to build an Angular4 project in production with the following command: node --max_old_space_size=8192 'node_modules/@angular/cli/bin/ng' build --prod --output-hashing=al Error: ERROR in vendor.422622daea37e ...

I am looking to transfer information in CodeIgniter from a view utilizing AJAX post, handle that information in the controller, and then return the resultant array back to the view

I have been searching the entire internet, but unfortunately, I couldn't find a helpful solution. Any assistance would be greatly appreciated. Thank you in advance. MY HTML <div class="row"> I am unsure whether the form tag is required in my ...

Sharing JSON data with public/javascripts/X.js in Node/Express: A beginner's guide

Currently facing a challenge with my Express project. Take a look at https://github.com/MoreeZ/help1 and examine ./public/javascripts/budget.js. My goal is to swap the incomeData object to read data from ./incomedata.json I attempted passing it through th ...

Deploying Vue.js applications

I am working on a Vue application that was created using vue-cli. It is semi-developed and I would like to show the progress to a customer. Therefore, I am looking to deploy what we have so far. If I execute the script npm run build, will I still be able ...

How to add and append values to an array in a Realtime Database

My React.js app allows users to upload songs to Firebase and view the queue of uploaded songs in order. The queue can be sorted using a drag-and-drop system that updates the database in Firebase. Is there a way to insert these songs into an array when uplo ...

Tips for converting an Array object to JSON format

After much effort, I have finally managed to format my data as valid JSON with the following Javascript code: var roles = getSelectedRoles(); // returns an Array object /* TODO: Explore better methods for incorporating roles into JSON data */ var rolesSt ...

Is it possible to transform an array into a JSON file and securely store/upload it in an AWS S3 bucket?

Recently, I started exploring aws and its capabilities. Currently, my focus is on developing a web application that allows users to input text in two separate fields. Subsequently, this text will be converted into a Json file and stored in the S3 bucket. ...

Ways to maintain a pointer to a RequireJS module?

Understanding the inner workings of RequireJS has been a bit challenging for me, as the official website doesn't provide clear explanations on fundamental concepts like how to utilize the 'require' and 'define' methods. Currently, ...

Uninstall all packages that are no longer listed in the package.json file using Npm

Seeking guidance on how to uninstall packages from the node_modules directory that are no longer listed in package.json. These packages were removed by another developer and the package.json file has been updated on git. Any tips on how to accomplish this ...

Guide to passing the parent state as a prop to a child component and enabling the child to modify the state

I have a situation where my parent component holds 4 buttons to set a payment state, and I need to pass this state to a text field child component. Additionally, I want the text field to be editable so that the state can also be modified through it. My att ...

What is the best way to confirm checkbox selection based on MySQL data?

Writing this question feels challenging, but I have a collection of checkboxes with their data stored as JSON in my PHP database. What I'm trying to achieve now is to dynamically load the JSON data on the page without refreshing it, checking specific ...

What is the best way to showcase a local image in the console using nwjs?

I am currently developing a desktop application using NW.js (node-webkit). In relation to this topic google chrome console, print image, I am attempting to display an image in the console. Following the suggestion from the aforementioned topic, the follo ...

Error Alert: Vue is not recognized in Browserify environment

My venture into front-end development has just begun and I am experimenting with Vue.js along with Browserify. The main 'app.js' file includes: window.$ = window.jQuery = require('jquery'); require('bootstrap'); var moment = ...

React dynamic table

I've been experimenting with creating a dynamic table in React that allows users to add and delete rows. I need the data entered by the user to be saved, possibly using in-state management so that I can work with it later. Essentially, I'm looki ...