Reputation: 1476
Assume I have a method in a Vue.js component that returns a string to be rendered onto the page:
display: (arg) => {
return arg.name
}
And in the relevant HTML:
<div html="component.display(arg)">
</div>
This has worked fine for me until now, but now I want to return HTML with some Vue-bound data on it:
display: (arg) => {
return '<button @click="myMethod(arg)">Click</button>'
}
Obviously, the above doesn't work. My research has led me to believe that the correct approach here would be to create a component and return it, but I just can't seem to get it working. How would I approach this problem?
Upvotes: 2
Views: 9503
Reputation: 139
If you want to write a function that will return a component and be able to use vue-bound data but do not want to make that into a separate file, then you can look into render functions in vue
Upvotes: 1
Reputation: 164812
I think what you're after is a dynamic component.
I would use a computed property to return the component definition to take advantage of Vue's reactivity (methods run all the time, computed properties only when required)
<component :is="display" :arg="arg" @click="myMethod"></component>
and...
computed: {
display () {
// you weren't clear on the conditions
// that should cause this to return something different
// but here is where you would put them
return {
props: ['arg'],
template: `<button @click="$emit('click', arg)">Click</button>`
}
}
}
I'm assuming here that myMethod
is defined in the parent, hence adding the @click
handler on <component>
and $emit
in the child.
I suppose you could use a method to return the component definition but that feels like it would be quite inefficient and there's probably a better way to do it.
Upvotes: 5
Reputation: 6981
Seems like you could make that button its own component.
// New component
Vue.component('arg-button', {
props: ['arg'],
data: function () {
return {
arg: null
}
},
myMethod: function(arg) {
console.log(arg)
},
template: `
<button
@click="myMethod(arg)">
Click
</button>`
})
// Old component
Vue.component('parent', {
data: function () {
return {
arg: null,
displayIfArg: true
}
},
template: `
<arg-button
v-show="displayIfArg"
:arg="arg">
</arg-button>`
})
Your overall approach is what Vue solves without returning functions-as-strings like that. There's a couple of ways to do it The Vue Way, but it roughly involves conditional instantiation/display of components—which should be readily reusable anyway, so thinking you need to base your return on arg
itself is likely more hassle than it's worth.
Components should above all be reusable and atomic. Read their docs, esp. on components, it'll shed a lot of light.
Upvotes: 2