Description
Version
3.0.0-beta.4
Reproduction link
https://codepen.io/lzhoucs/pen/rNOzpZa
Steps to reproduce
- Go to https://codepen.io/lzhoucs/pen/rNOzpZa
- Click on one of the two tabs
What is expected?
The tab clicked should render its active
prop as true
What is actually happening?
The tab renders its initial active
prop value false
and never re-renders after being clicked
I am using a functional component Tabs
to update its children Tab
before handing it over to _Tabs
because I don't know how to do the same directly in _Tabs
:
const _Tabs = {
template: '<div><slot></slot></div>'
}
const Tabs = (props, {emit, slots}) => {
const children = slots.default && slots.default()
children.forEach(vnode => {
vnode.props = Vue.mergeProps(vnode.props, {
onActivate(newHref) {
emit('update:modelValue', newHref)
},
active: vnode.props.href === props.modelValue
})
})
return Vue.h(_Tabs, () => children)
}
Using other approaches such as scoped slots might work however that's less ideal because the user who uses this component has to do extra work besides below:
<tabs v-model="selectedTab">
<tab href="#tab1">Tab 1</tab>
<tab href="#tab2">Tab 2</tab>
</tabs>
In my opinion, handling tab click and activate/deactivate tab should be the tab(s) component's job as a library, and the user only provides v-model
for initial state and gets notified when selected is updated.
According to vuejs/vue#4766 (comment), this should work in vue 2 but I didn't try.
I also tried the cloneVNode
approach as oppose to mutate the vnode directly, but it didn't work for me