2👍
Vue Components are supposed communicate one-way down to children via Props (where only parents mutate the props on the children, never the children themselves) and children communicate to parents by emitting events. The makes nesting components much easier to reason about, and decouples components properly. So what do you do when the parent wants to change a tab? Let me walk you through a process:
1) Imagine we add a prop called activeTab
to the tabs component (I’m not following your code in your question directly here, just basing loosely off it to demonstrate the process easier). The parent will change the value of this prop whenever it wants. The tabs component (aka child component in this case) should not alter the value of the activeTab
prop. Instead, inside the tabs component, add a watcher for this prop:
in child component (ie. tabs)
props: {
/**
* Prop parent can use to set active tab
*/
'activeTab': {
type: Number
}
},
watch: {
/**
* Watch for changes on the activeTab prop.
*
* @param {boolean} val The new tab value.
* @param {boolean} oldVal The old tab value.
* @return {void}
*/
activeTab: function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
// do something here to make the tabs change
// and never alter the prop itself.
this.switchTab(val)
}
},
2) Now on your parent, you should have a reactive data property that can be named the same as your prop if you want:
in parent component (ie. app)
data: {
activeTab: 0
}
3) Then we need to make it where when you alter the data property above, the prop gets altered too. Here’s what it would look like on the tabs component tag:
in parent component (ie. app)
<tabs :activeTab="activeTab" ...
4) What do you do if you want to allow the tabs component to also alter the active tab sometimes? Easy, just emit an event whenever an active tab is changed:
in the child component (ie. tabs)
methods: {
switchTab (newActiveTabValue) {
// store the new active tab in some data property in this component, but not the "activeTab" prop, as mentioned earlier.
this.whatever = newActiveTabValue
// ... now emit the event
this.$emit('switched', newActiveTabValue)
}
5) Your parent should now listen for this emitted event and update its own data property:
in parent component (ie. app)
<tabs :activeTab="activeTab" @switched="activeTab = arguments[0]" ...
Seems a little bit more effort, but it’s all worth it as your app grows in complexity and more things become nested. You can read more on Composing Components in the official docs here.