Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

257
Vistas
how to wrap a component content with html tag dynamically in vue

Hi i want to wrap the content of a component with some specific html tag let say button for this example.

i have a function which dynamically returns a value which i use as a prop, based on that i want to wrap the content of a component.

i know i could have achieved this way too <button><compA/></button> it does not solve my problem beacuse i need to change it in 100 places.

My expected result:

  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: :wrappwithbutton="" having true for 1st usage and false for 2nd usage

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>

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

This is a perfect example for render functions. Instead of using a template you can use a render function to render the template for you. Read more about render functions

const localComponent = {
 name:'first-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:{'first-comp':localComponent},
});

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

You can even go a step further and make your localComponent to be more dynamic with the parent passing a prop with the tag that should 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 would like to have a single div and not two divs you can do:

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

   return h(this.tag ? 'button' : 'div', [
     h('div', this.text)
   ])
}
over 4 years ago · Santiago Trujillo Denunciar

0

This is my idea, but I think the template should have a more concise way of writing

const localComponent = {
  name: "first-comp",
  template: `
    <template v-if="wrappwithbutton">
      <button>
        <div> {{text}}</div>
      </button>
    </template>
    <template v-else>
      <div> {{text}}</div>
    </template>
  `,
  props: ["wrappwithbutton", "text"]
};

const app = new Vue({
  el: "#app",
  name: "app",
  components: { "first-comp": localComponent }
});
over 4 years ago · Santiago Trujillo Denunciar

0

You can try to focus on functionality rather then tags:

const localComponent = {
 name:'first-comp',
 template:`<div 
             :class="wrappwithbutton && 'btn'"
             @click="btnClick"
           > 
             {{text}}
           </div>`,
 props:['wrappwithbutton','text'],
 methods: {
   btnClick() {
     if (this.wrappwithbutton) console.log('button')
   }
 }
}

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

Vue.config.productionTip = false
Vue.config.devtools = false
.btn {
  border: 1px solid violet;
  cursor: pointer;
}
<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>

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda