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:
<button><div>press me i'm button</div></button><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>
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)
])
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With