0x00
近来想写个简朴blog来演习下vue百口桶,个中特别想完成相似github的页面加载行动。
0x01
翻了下api,vue-router供应导航钩子给开发者完成导航阻拦
router.beforeEach((to, from, next) => { })
但试验后发明,当钩子实行的时刻url/hash的状况已转变而且难以完成进度条。
0x02
翻查源代码后发明变动url主如果在history实例中举行,个中history暴露一个listen的方法来监听路由的转变从而更新vue的root元素的路由值。
history.listen(route => {
this.app._route = route
})
在这里只需耽误_route的赋值就能够耽误UI和url的更新,甚至能替代路由
0x03
终究代码,这里没有用作进度条,合营store能够完成相似github的进度条指示器,以及超时处置惩罚
// 定义一个正在加载的Route的接见器
Object.defineProperty(Vue.prototype, '$routePending', {
get () {
return this.$root._routePending;
}
});
//hook vm建立
Vue.mixin({
/**
* hook route updated
*/
beforeCreate () {
if (this.$options.router) {
//定义一个相应式属性
Vue.util.defineReactive(this, '_routePending', null);
//耽误赋值并做预加载
this._router.history.listen(route => {
this._routePending = route;
Promise.resolve()
.then(() => {
//过滤非实行中的route
if (route != this._routePending) {
return;
}
if (route.matched) { //路由有婚配的组件
let reduce = route.matched.reduce((list, item) => {
Object.keys(item.components).forEach(k => {
let component = item.components[k];
if (component.preFetch) {
list.push(component.preFetch); //一切组件的preFetch入列
}
});
return list;
}, []);
if (reduce.length > 0) {
return Promise.all(reduce.map(fn => fn(route)));
}
return route;
}
})
.then(() => {
//过滤非实行中的route
if (route != this._routePending) {
return;
}
//
this._route = route;
this._routePending = null;
})
.catch(e => {
console.warn(e);
this._router.replace('/500');
});
});
}
}
});
已知题目:
本来的导航钩子能够涌现题目
PS:文中极能够涌现毛病,这里给出一个思绪