generator-wxnode-boilerplate
Version:
Yeoman generator for wxnode boilerplate
127 lines (116 loc) • 4.45 kB
text/typescript
import Vue from 'vue';
import 'es6-promise/auto';
import BJ_REPORT from 'badjs-report';
import jsCookie from 'js-cookie';
import Config from './config';
import {createApp} from './main';
import ProgressBar from './components/ProgressBar.vue';
import {Promise} from 'es6-promise';
BJ_REPORT.init({
id: Config.BADJS_ID, // 申请的项目上报ID,不指定id将不上报
uin: jsCookie.get(Config.BADJS_COOKIE) || '', // 用户唯一标识
combo: 1, // combo 是否合并上报, 0 关闭, 1 启动(默认)
delay: Config.BADJS_DELAY, // 当 combo= 1 可用,延迟多少毫秒,合并缓冲区中的上报
url: Config.BADJS_REPORT_URL, // 指定上报地址
ignore: [/Script Error:/], // 忽略某个错误
level: 4, // 设置默认的级别 // 上报等级 // 1-debug 2-info 4-error 8-fail
});
// 包裹异步回调
const badjs: any = BJ_REPORT;
badjs.tryJs().spyModules();
badjs.tryJs().spySystem();
// global progress bar
const bar: any = Vue.prototype.$bar = new Vue(ProgressBar).$mount();
document.body.appendChild(bar.$el);
// a global mixin that calls `asyncData` when a route component's params change
Vue.mixin({
beforeRouteUpdate(to, from, next) {
const resolve = () => Promise.resolve();
const asyncData = this.$options.asyncData || resolve;
const clientData = this.$options.clientData || resolve;
bar.start();
Promise.all([
asyncData({
store: this.$store,
route: to,
routeFrom: from,
}),
clientData({
store: this.$store,
route: to,
routeFrom: from,
}),
]).then(() => {
bar.finish();
next();
try {
const event = new Event('routeUpdate');
document.dispatchEvent(event);
} catch (err) {
}
}).catch(() => {
bar.finish();
next();
});
},
});
const {app, router, store} = createApp();
// store.token = jsCookie.get('server_token'); // 用于防止csrf攻击的token校验
// prime the store with server-initialized state.
// the state is determined during SSR and inlined in the page markup.
if (window.__INITIAL_STATE__) {
store.replaceState(window.__INITIAL_STATE__);
}
// wait until router has resolved all async before hooks
// and async components...
router.onReady(() => {
// Add router hook for handling asyncData.
// Doing it after initial route is resolved so that we don't double-fetch
// the data that we already have. Using router.beforeResolve() so that all
// async components are resolved.
router.beforeResolve((to, from, next) => {
const matched = router.getMatchedComponents(to);
const prevMatched = router.getMatchedComponents(from);
let diffed = false;
const activated = matched.filter((c, i) => {
return diffed || (diffed = (prevMatched[i] !== c));
});
const clientDataHooks = activated.map((c: any) => c.options.clientData).filter(_ => _);
const asyncDataHooks = activated.map((c: any) => c.options.asyncData).filter(_ => _);
if (!asyncDataHooks.length && !clientDataHooks.length) {
return next();
}
const dataHooks = asyncDataHooks.concat(clientDataHooks);
bar.start();
Promise.all(dataHooks.map(hook => hook({store, route: to, routeFrom: from})))
.then(() => {
bar.finish();
next();
})
.catch(() => {
bar.finish();
next();
});
});
const matchedComponents: any = router.getMatchedComponents();
if (!window.__INITIAL_STATE__) {
// 首屏非服务端渲染,需要自行触发数据加载逻辑
// no matched routes
if (!matchedComponents.length) {
return;
}
Promise.all(matchedComponents.map(({options}) => options && options.asyncData && options.asyncData({
store,
route: router.currentRoute,
})));
}
// 客户端数据触发
matchedComponents.map(({options}) => options && options.clientData && options.clientData({
store,
route: router.currentRoute,
routeFrom: null,
}));
// actually mount to DOM
app.$mount('#app');
window.app = app;
});