Skip to content

Instantly share code, notes, and snippets.

@Alexisgt01
Last active November 21, 2019 13:02
Show Gist options
  • Save Alexisgt01/33a9a77c2a11d1b189433c00897644e9 to your computer and use it in GitHub Desktop.
Save Alexisgt01/33a9a77c2a11d1b189433c00897644e9 to your computer and use it in GitHub Desktop.
[MODULES] Tabs page storage with Vue cli, Vuex, Vuetify & Vue Router
<template>
<div>
<v-btn @click="addPage({
name: 'Item', //Must be unique !!
route: '/item',
})"></v-btn>
</div>
</template>
<script>
import {mapActions} from 'vuex';
export default {
name: 'vue',
methods: {
...mapActions('routes', [
'addPage',
])
}
};
</script>
<style scoped></style>
import router from '@/routes'
/* eslint-disable no-console */
const state = {
open: [],
};
// getters
const getters = {
open: state => state.open,
};
// actions
const actions = {
addPage: ({commit, state}, route) => {
let openned = state.open.find(o => o.name === route.name);
if (!openned) {
commit('ADD_PAGE', {
name: route.name, // must be unique !!
route: route.route,
})
}
if (router.currentRoute.path !== route.route) {
router.push({path: route.route})
}
},
closePage: ({getters, commit}, name) => {
let allTab = getters.open;
let tabToClose = getters.open.find(o => o.name === name);
let tabToCloseIndex = allTab.indexOf(tabToClose);
if (tabToClose.route === router.currentRoute.path) {
if (tabToCloseIndex !== 0) {
if (allTab.length === tabToCloseIndex + 1) {
router.push({path: getters.open[tabToCloseIndex - 1].route})
} else {
router.push({path: getters.open[tabToCloseIndex + 1].route})
}
} else {
if (allTab.length !== 1) {
router.push({path: getters.open[tabToCloseIndex + 1].route})
} else {
router.push({path: '/dashboard'})
commit('ADD_PAGE', {
name: 'Dashboard',
route: '/dashboard',
})
}
}
}
commit('CLOSE_PAGE', {
index: tabToCloseIndex,
})
}
};
// mutations
const mutations = {
ADD_PAGE: (state, route) => {
state.open.push({
name: route.name,
route: route.route,
})
},
CLOSE_PAGE: (state, index) => {
state.open.splice(index.index, 1);
},
};
export default {
namespaced: true,
state,
getters,
actions,
mutations
}
<!-- ADD SOME SHORT CODE TO next/previous TAB -->
<!-- PLEASE ADD THIS LIB -->
<!-- https://github.com/jaywcjlove/hotkeys -->
<template>
<v-card class="custom-tabs" elevation="0">
<v-tabs>
<v-tab v-for="(tab, n) in open" :key="n" :to="{ path: tab.route }">
<v-icon @click.native.prevent="closePage(tab.name)" class="mr-2" size="12">fa fa-times</v-icon>
{{tab.name}}
</v-tab>
</v-tabs>
<v-divider></v-divider>
</v-card>
</template>
<script>
/* eslint-disable no-console */
/* eslint-disable no-unused-vars */
import {mapGetters, mapActions} from 'vuex'
import hotkeys from 'hotkeys-js';
export default {
name: "tabs",
computed: {
/**
* Get open page
*/
...mapGetters('routes', {
open: 'open',
})
},
created() {
let self = this;
/**
* Shortcode event "n"
* check the tab position relative to others and push accordingly to right
* @params {object} event - event emit
**/
hotkeys('n', function (event) {
// Prevent the default refresh event under WINDOWS system
event.preventDefault();
setTimeout(function () {
let allTab = self.open;
let countTab = self.open.length;
let currentRoute = self.$route.path;
let currentTab = allTab.find(o => o.route === currentRoute);
let currentIndex = allTab.indexOf(currentTab);
if (countTab - 1 !== currentIndex) {
let nextRoute = allTab[currentIndex + 1].route;
self.$router.push(nextRoute);
}
}, 80);
});
/**
* Shortcode event "p"
* check the tab position relative to others and push accordingly to left
* @params {object} event - event emit
**/
hotkeys('p', function (event) {
// Prevent the default refresh event under WINDOWS system
event.preventDefault();
setTimeout(function () {
let allTab = self.open;
let countTab = self.open.length;
let currentRoute = self.$route.path;
let currentTab = allTab.find(o => o.route === currentRoute);
let currentIndex = allTab.indexOf(currentTab);
if (currentIndex !== 0 && countTab > 1) {
let previousRoute = allTab[currentIndex - 1].route;
self.$router.push(previousRoute);
}
}, 80);
});
},
methods: {
/**
* Close the selected tab
*/
...mapActions('routes', [
'closePage',
])
}
}
</script>
<style scoped>
.custom-tabs {
left: 80px;
width: calc(100% - 80px);
}
</style>
<template>
<v-card>
<v-tabs background-color="deep-purple accent-4" center-active dark icons-and-text>
<v-tab v-for="(tab, n) in open" :key="n" :to="{ path: tab.route }">
{{tab.name}}
<v-icon @click.native.prevent="closePage(tab.name)" size="12" right>fa fa-times</v-icon>
</v-tab>
</v-tabs>
</v-card>
</template>
<script>
import {mapGetters, mapActions} from 'vuex'
export default {
name: "tabs",
computed: {
...mapGetters('routes', {
open: 'open',
})
},
methods: {
...mapActions('routes', [
'closePage',
])
}
}
</script>
<style scoped>
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment