I want to assign some attributes and classes to the children VNode
through data
object? Everything works perfectly. But during my Vue.js investigation, I have not seen such pattern in use, that's why I don't think it's good idea to modify children VNode
's.
But that approach sometimes comes in handy – for example I want to assign to all the buttons in default slot the aria-label
attribute.
See example below, using default stateful components:
Vue.component('child', {
template: '<div>My role is </div>',
})
Vue.component('parent', {
render(h) {
const {
default: defaultSlot
} = this.$slots
if (defaultSlot.length) {
defaultSlot.forEach((child, index) => {
if (!child.data) child.data = {}
if (!child.data.attrs) child.data.attrs = {}
const {
data
} = child
data.attrs.role = 'button'
data.class = 'bar'
data.style = `color: #` + index + index + index
})
}
return h(
'div', {
class: 'parent',
},
defaultSlot,
)
},
})
new Vue({
el: '#app',
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<parent>
<child></child>
<child></child>
<child></child>
<child></child>
<child></child>
</parent>
</div>
And here is examples using stateless functional components:
Vue.component('child', {
functional: true,
render(h, {
children
}) {
return h('div', {
class: 'bar'
}, children)
},
})
Vue.component('parent', {
functional: true,
render(h, {
children,
scopedSlots
}) {
const defaultScopedSlot = scopedSlots.default({
foo: 'bar'
})
if (defaultScopedSlot.length) {
defaultScopedSlot.forEach((child, index) => {
child.data = {
style: `color: #` + index + index + index
}
child.data.attrs = {
role: 'wahtever'
}
})
}
return h(
'div', {
class: 'parent',
},
defaultScopedSlot,
)
},
})
new Vue({
el: '#app',
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<parent>
<template v-slot:default="{ foo }">
<child></child>
<child></child>
<child></child>
</template>
</parent>
</div>
I am waiting for the following answers:
-
Yes, you can use it, there are no potential problems with this approach.
-
Yes, but these problem(s) can happen.
-
No, there are a lot of problem(s).
UPDATE:
That another good approach I have found it's to wrap child VNode
into the another created VNode
with appropriate data object, like this:
const wrappedChildren = children.map(child => {
return h("div", { class: "foo" }, [child]);
});
Using this approach I have no fear modifying children VNode
's.
Thank you in advance.
from Can I modify Vue.js VNodes?
No comments:
Post a Comment