I have a VueJS/Vuetify application that has tab bars using v-tabs
/v-tab
components to navigate between pages. I have implemented code using the click
event in the v-tab
element that checks to make sure there is no unsaved content when the user clicks on another tab, and if there is, displays a modal using v-dialog
to alert the user. If the user chooses to continue, it continues on to the desired tab/component. However, if the user selects Cancel
in the modal, the page is left where it was.
Here is the tabs component:
<template>
<div>
<!-- Tabs -->
<v-tabs
color="secondary"
:value="currentTab"
>
<v-tab
v-for="(tab, i) in userTabs"
:key="i"
:href="tab.href"
@click="tabClick(tab.component, tab.link)"
:disabled="isDisabled(tab)"
>
{{ tab.title }}
</v-tab>
</v-tabs>
<BaseConfirmModal
:value="showUnsaved"
:title="unsavedContentTitle"
:text="unsavedContentText"
declineText="Cancel"
@clicked="unsavedModalConfirm"
/>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex';
import baseTabMixin from '@/components/mixins/workspace/baseTabMixin';
export default {
name: 'UserTabs',
data: () => ({
userTabs: [
{
title: 'General Info',
href: '#tab-general',
link: 'tab-general',
component: 'UserEdit',
},
{
title: 'Enrollments',
href: '#tab-enrollments',
link: 'tab-enrollments',
component: 'UserEnrollmentEdit',
},
{
title: 'Alerts',
href: '#tab-alerts',
link: 'tab-alerts',
component: 'UserAlertEdit',
},
{
title: 'Devices',
href: '#tab-devices',
link: 'tab-devices',
component: 'UserDeviceEdit',
},
],
}),
computed: {
...mapGetters('app', ['getStickyTenant', 'roleAtLeastTa', 'getUnsaved']),
...mapGetters('users', ['getCurrent']),
...mapGetters('tabs', {
currentTab: 'getSelected',
}),
},
methods: {
...mapActions('tabs', {
setCurrentTab: 'setSelected',
}),
isDisabled(item) {
if (item.component === 'UserEdit') {
return false;
}
if (item.component === 'UserDeviceEdit' && !this.roleAtLeastTa) {
return true;
}
return !this.getCurrent.userId;
},
},
mixins: [baseTabMixin],
};
</script>
and the referenced baseTabMixin
:
import { mapGetters, mapActions } from 'vuex';
const baseTabMixin = {
data: () => ({
showUnsaved: false,
unsavedContentTitle: 'Unsaved Changes',
unsavedContentText: 'You have made changes to this page that are not saved. Do you wish to continue?',
destTabComponent: '',
destTabLink: '',
}),
components: {
BaseConfirmModal: () => import('@/components/base/BaseConfirmModal'),
},
computed: {
...mapGetters('app', ['getUnsaved']),
},
methods: {
...mapActions('app', ['setUnsaved']),
tabClick(component, tab) {
// Check to see if getUnsaved === true; if it is,
// set variable to display warning modal.
if (this.getUnsaved) {
this.showUnsaved = true;
} else {
// There is no unsaved content, so continue to the desired tab.
this.destTabComponent = component;
this.destTabLink = tab;
this.setCurrentTab(tab);
this.$router.push({ name: component });
}
},
unsavedModalConfirm(confirm) {
if (confirm) {
this.setCurrentTab(this.destTabLink);
this.$router.push({ name: this.destTabComponent });
}
this.showUnsaved = false;
},
},
};
export default baseTabMixin;
The problem has to do with the tab item highlighting. When the new tab is clicked, the slider moves to the new tab and the new tab title is bolded before the click event (tabClick()
in this case) is called. When I select Cancel
in my modal, it leaves the page where it is (as expected), but the clicked tab is still highlighted, both with the slider underneath and the bolder text. Since that all happens before my click handler is even called, is there way to either a) stop the highlighting from happening before the click event is called, or b) reverse the highlighting back to the current tab?