Handle url and history

This commit is contained in:
sheychen 2019-03-30 22:23:27 +01:00
parent 862dac5252
commit 68e43c4b15
4 changed files with 70 additions and 41 deletions

View File

@ -9,21 +9,23 @@
<script src="lib/lodash.js"></script>
<script src="lib/axios.js"></script>
<script src="lib/vue.full.js"></script>
<script src="lib/httpVueLoader.js"></script>
</head>
<body>
<div id="app">
<div id="pages-list">
<p v-if="pages.error" style="color: orangered">{{ pages.error }}</p>
<template v-else-if="pages.data">
<button v-for="page in pages.data" @click="showPage(page)">{{ page.name }}</button>
<template v-for="(page, id) in pages.data">
<button v-if="activePage != id" @click="showPage(id)">{{ page.name }}</button>
<p v-else>{{ page.name }}</p>
</template>
</template>
<p v-else>Loading...</p><!--TODO: Cool loader-->
</div>
<div id="active-page">
<div v-if="activePage">
<keep-alive>
<div :is="activePage"></div>
<div :is="activeComponent"></div>
</keep-alive>
</div>
</div>

92
main.js
View File

@ -6,6 +6,8 @@ const API = axios.create({
}*/
});
const PAGE_PREFIX = 'raith-'
const APP = new Vue({
el: '#app',
data: {
@ -18,49 +20,75 @@ const APP = new Vue({
created() {
API.get('pages.json').then(resp => {
this.pages.data = resp.data
const loading = () => {
this.showPage(window.location.hash.length > 0 ?
window.location.hash.substr(2) :
Object.keys(this.pages.data)[0])
}
this.$nextTick(loading)
window.onhashchange = loading
}).catch(err => {
this.pages.error = err.response.statusText
})
},
computed: {
activeComponent() {
return PAGE_PREFIX + this.activePage
}
},
methods: {
showPage(mod) {
var key = 'raith-' + mod.key
this.$options.components[key] = () => ({
// Dynamicly load component
component: new Promise((resolve, reject) => {
const loaded = () => key in Vue.options.components
showPage(id) {
const key = PAGE_PREFIX + id
if (!(id in this.pages.data)) {
const err = `Module not found: ${id}`
console.error(err)
this.$options.components[key] = {
template: `<p style="color: red">${err}</p>` //TODO: Sad error
}
return;
}
const mod = this.pages.data[id]
const load = () => loaded() ?
resolve(Vue.options.components[key]) : reject()
if (!(key in this.$options.components)) { // Must be load
this.$options.components[key] = () => ({
// Dynamicly load component
component: new Promise((resolve, reject) => {
const loaded = () => key in Vue.options.components
if (loaded() || document.querySelector('script[src="' + mod.src + '"]')) { //allready loaded
load()
return;
}
const load = () => loaded() ?
resolve(Vue.options.components[key]) : reject()
const el = document.createElement('script')
if (loaded() || document.querySelector('script[src="' + mod.src + '"]')) { //allready loaded
load()
return;
}
el.type = 'text/javascript'
el.async = true
el.src = mod.src
if (mod.integrity != null)
el.integrity = mod.integrity
const el = document.createElement('script')
el.addEventListener('load', load)
el.addEventListener('error', reject)
el.addEventListener('abort', reject)
el.type = 'text/javascript'
el.async = true
el.src = mod.src
if (mod.integrity != null)
el.integrity = mod.integrity
document.head.appendChild(el)
}),
loading: {
template: '<p>Loading...</p>' //TODO: Cool loader
},
error: {
template: `<p style="color: red">Can't load module</p>` //TODO: Sad error
},
timeout: 5000
})
this.activePage = key
el.addEventListener('load', load)
el.addEventListener('error', reject)
el.addEventListener('abort', reject)
document.head.appendChild(el)
}),
loading: {
template: '<p>Loading...</p>' //TODO: Cool loader
},
error: {
template: `<p style="color: red">Can't load module</p>` //TODO: Sad error
},
timeout: 5000
})
}
document.title = `Raith - ${mod.name}`
window.history.pushState({}, document.title, "/#/" + id);
this.activePage = id
}
}
})

View File

@ -1,12 +1,11 @@
[
{
{
"test1": {
"name": "Test1",
"key": "test1",
"src": "pages/test1/main.js"
},
{
"test2": {
"name": "Test2",
"key": "test2",
"src": "pages/test2/main.js"
}
]
}

View File

@ -8,7 +8,7 @@ Vue.component('raith-test1', {
},
created() {
API.get('pages.json').then(resp => {
this.yolol = resp.data[0]
this.yolol = Object.values(resp.data)[0]
}).catch(err => {
this.yolol = err.response.statusText
})