You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
5.3 KiB
160 lines
5.3 KiB
///https://html5boilerplate.com/
|
|
///config.js
|
|
//config
|
|
const config = {
|
|
debug: true,
|
|
path: document.location.pathname.substr(0, document.location.pathname.lastIndexOf('/')),
|
|
ext: '.html',
|
|
componentCounter: 'vue-component-counter',
|
|
file: function (file) {
|
|
return this.path + file;
|
|
}
|
|
};
|
|
//log
|
|
function log(message) {
|
|
if (config.debug) {
|
|
console.log(message);
|
|
}
|
|
}
|
|
//解析组件
|
|
function parseModel(response, name) {
|
|
var html = new DOMParser().parseFromString(response.data, 'text/html');
|
|
var template = html.getElementsByTagName('template')[0];
|
|
var script = html.getElementsByTagName('script')[0].innerHTML;
|
|
script = '(' + script.replace(/^\s*export\s*default\s*/, '').replace(/;?\s*$/, '') + ')\n//# sourceURL=' + response.config.url;
|
|
var model = eval(script) || {};
|
|
var style = html.getElementsByTagName('style')[0];
|
|
if (style) {
|
|
style.setAttribute('class', name);
|
|
style.setAttribute(config.componentCounter, 1);
|
|
model.style = style.outerHTML;
|
|
}
|
|
model.template = template;
|
|
return model;
|
|
}
|
|
//添加vue异步组件
|
|
function addVueComponentsByEval(app, cfg) {
|
|
for (var i in cfg.list) {
|
|
(function () {
|
|
var item = cfg.list[i];
|
|
var url = config.path + cfg.prefix + item + config.ext;
|
|
var path = url.substring(config.path.length);
|
|
var name = path.substring(cfg.prefix.length, path.length - config.ext.length).replaceAll('/', "-");
|
|
app.component(name, Vue.defineAsyncComponent(() => new Promise((resolve, reject) => {
|
|
axios.get(url, { headers: { 'Cache-Control': 'no-cache' } }).then(function (response) {
|
|
var component = parseModel(response, name);
|
|
component.created = function () {
|
|
var style = document.querySelector('head style.' + name);
|
|
if (style) {
|
|
var counter = parseInt(style.getAttribute(config.componentCounter));
|
|
style.setAttribute(config.componentCounter, counter + 1);
|
|
}
|
|
else {
|
|
if (component.style) {
|
|
$('head').append(component.style);
|
|
}
|
|
}
|
|
};
|
|
component.unmounted = function () {
|
|
var style = document.querySelector('head style.' + name);
|
|
if (style) {
|
|
var counter = parseInt(style.getAttribute(config.componentCounter));
|
|
if (counter - 1 > 0) {
|
|
style.setAttribute(config.componentCounter, counter - 1);
|
|
}
|
|
else {
|
|
document.head.removeChild(style);
|
|
}
|
|
}
|
|
};
|
|
resolve(component);
|
|
});
|
|
})));
|
|
})();
|
|
}
|
|
}
|
|
///router.js
|
|
var router = new VueRouter.createRouter({
|
|
history: VueRouter.createWebHashHistory(),
|
|
routes: []
|
|
});
|
|
router.beforeEach((to, from, next) => {
|
|
console.log('to------',to)
|
|
var url = to.path === '/' ? '/views/home' : to.path;
|
|
var name = url.substring(1).replaceAll('/', "-");
|
|
url = config.path + url + config.ext;
|
|
if (!router.hasRoute(name)) {
|
|
axios.get(url, { headers: { 'Cache-Control': 'no-cache' } }).then(function (response) {
|
|
var model = parseModel(response, name);
|
|
var route = {
|
|
name: name,
|
|
path: to.path,
|
|
component: model,
|
|
meta: model.meta
|
|
};
|
|
router.addRoute(route);
|
|
router.push({ path: to.path, query: to.query });
|
|
});
|
|
}
|
|
else {
|
|
next();
|
|
}
|
|
});
|
|
router.beforeResolve(async to => {
|
|
var route = Enumerable.from(router.getRoutes()).firstOrDefault(o => o.name === to.name);
|
|
if (route.components.default.style && !document.querySelector('head style.' + to.name)) {
|
|
$('head').append(route.components.default.style);
|
|
}
|
|
console.log(to);
|
|
});
|
|
router.afterEach((to, from) => {
|
|
if (from.name) {
|
|
if (to.path !== from.path) {
|
|
var style = document.querySelector('head style.' + from.name);
|
|
if (style) {
|
|
document.head.removeChild(style);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
///site.js
|
|
const store = {
|
|
state: Vue.reactive({
|
|
show: true,
|
|
query: '',
|
|
showOverlay: false
|
|
})
|
|
};
|
|
const app = Vue.createApp({
|
|
data() {
|
|
return store.state;
|
|
},
|
|
mounted() {
|
|
window.addEventListener('hashchange', () => {
|
|
let currentPath = window.location.hash.slice(1)
|
|
if (this.$route.path !== currentPath) {
|
|
this.$router.push(currentPath)
|
|
}
|
|
}, false);
|
|
},
|
|
methods: {
|
|
reload() {
|
|
this.show = false;
|
|
this.$nextTick(function () {
|
|
this.show = true;
|
|
});
|
|
}
|
|
}
|
|
});
|
|
//添加组件
|
|
var cfg = {
|
|
prefix: '/views/components/',
|
|
list: [
|
|
'layout',
|
|
'pagination'
|
|
]
|
|
};
|
|
addVueComponentsByEval(app, cfg);
|
|
app.component("v-chart", VueECharts);
|
|
app.use(router);
|
|
var vm = app.mount("#app"); |