This commit is contained in:
+100
@@ -0,0 +1,100 @@
|
||||
<script>
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import Project from '@components/project';
|
||||
|
||||
const aoRoutes = {
|
||||
'project': Project, //Merge app.js and project.js calls to avoid extra http request on inital page
|
||||
'admin': defineAsyncComponent(() => import(/* webpackChunkName: "admin" */ '@components/admin')),
|
||||
'upload': defineAsyncComponent(() => import(/* webpackChunkName: "upload" */ '@components/upload'))
|
||||
};
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
hash: {page: '', items: []},
|
||||
consts: this.appConfig.consts,
|
||||
mobile: false
|
||||
};
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
hash: this.hash,
|
||||
consts: this.consts,
|
||||
isMobile: () => this.isMobile()
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
route() {
|
||||
return aoRoutes[this.hash.page];
|
||||
},
|
||||
hashSnapshot() {
|
||||
return JSON.stringify(this.hash);
|
||||
}
|
||||
},
|
||||
inject: ['appConfig'],
|
||||
created() {
|
||||
this.mobileMediaQuery = window.matchMedia('only screen and (max-width: 800px)');
|
||||
this.mobileMediaQuery.addEventListener('change', this.updateMobile);
|
||||
this.updateMobile();
|
||||
|
||||
//Set initial page
|
||||
let asInitHash = this.getBrowserHash();
|
||||
if(!asInitHash.page) asInitHash.page = this.consts.default_page;
|
||||
this.setVarHash(asInitHash);
|
||||
},
|
||||
mounted() {
|
||||
//Catch browser hash change
|
||||
window.addEventListener('hashchange', this.onBrowserHashChange);
|
||||
},
|
||||
watch: {
|
||||
hashSnapshot(jNewHash, jOldHash) {
|
||||
const asNewHash = JSON.parse(jNewHash);
|
||||
//Sync variable -> #hash
|
||||
if(asNewHash != this.getBrowserHash()) {
|
||||
this.setBrowserHash(asNewHash.page, asNewHash.items);
|
||||
}
|
||||
|
||||
this.setPageTitle(asNewHash.page);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isMobile() {
|
||||
return this.mobile;
|
||||
},
|
||||
updateMobile() {
|
||||
this.mobile = this.mobileMediaQuery.matches;
|
||||
},
|
||||
setPageTitle(sTitle) {
|
||||
document.title = this.consts.title + ' - ' + sTitle.trim();
|
||||
},
|
||||
setVarHash(asHash) {
|
||||
this.hash.page = asHash.page || '';
|
||||
this.hash.items = Array.isArray(asHash.items) ? [...asHash.items.filter(n => n)] : [];
|
||||
},
|
||||
onBrowserHashChange() { //Sync #hash -> variable
|
||||
let asHash = this.getBrowserHash();
|
||||
if(asHash != this.hash) this.setVarHash(asHash);
|
||||
},
|
||||
getBrowserHash() {
|
||||
let sHash = window.location.hash.slice(1);
|
||||
let asHash = sHash.split(this.consts.hash_sep).filter(n => n);
|
||||
let sPage = asHash.shift() || '';
|
||||
return {page: sPage, items: asHash};
|
||||
},
|
||||
setBrowserHash(sPage = '', asItems = []) {
|
||||
if(typeof asItems == 'string' && asItems != '') asItems = [asItems];
|
||||
const sItems = (asItems.length > 0)?(this.consts.hash_sep + asItems.join(this.consts.hash_sep)):'';
|
||||
window.location.hash = '#' + sPage + sItems;
|
||||
}
|
||||
},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('hashchange', this.onBrowserHashChange);
|
||||
this.mobileMediaQuery.removeEventListener('change', this.updateMobile);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div id="main">
|
||||
<component :is="route" />
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user