我已经使用webpack的代码拆分功能将我的应用分成多个块,以便在用户访问我的网页时不会下载整个应用程序包。
某些路由所需的块可能相当大,可能需要花费相当多的时间才能下载。这很好,除非用户在点击内部链接时不知道页面实际上正在加载,所以我需要以某种方式显示加载动画或其他东西。
我的路由器配置如下:
[
{
path: '/',
component: () => import(/* webpackChunkName: 'landing' */ './landing.vue'),
},
{
path: '/foo',
component: () => import(/* webpackChunkName: 'main' */ './foo.vue'),
},
{
path: '/bar',
component: () => import(/* webpackChunkName: 'main' */ './bar.vue'),
},
]
Vue.js指南中的Advanced Async Components显示了如何显示特定的" loading"组件正在被解析时 - 这正是我需要的,但它也说:
请注意,当在vue-router中用作路由组件时,将忽略这些属性,因为在路由导航发生之前会先解析异步组件。
如何在vue-router中实现这一目标?如果这是不可能的,延迟加载的组件对我来说几乎没用,因为它会给用户带来糟糕的体验。
答案 0 :(得分:25)
您可以使用导航防护来激活/停用显示/隐藏加载组件的加载状态:
如果您想使用" nprogress"你可以这样做:
http://jsfiddle.net/xgrjzsup/2669/
const router = new VueRouter({
routes
})
router.beforeEach((to, from, next) => {
NProgress.start()
next()
})
router.afterEach(() => {
NProgress.done()
})
或者,如果您想要在场显示某些内容:
http://jsfiddle.net/h4x8ebye/1/
Vue.component('loading',{ template: '<div>Loading!</div>'})
const router = new VueRouter({
routes
})
const app = new Vue({
data: { loading: false },
router
}).$mount('#app')
router.beforeEach((to, from, next) => {
app.loading = true
next()
})
router.afterEach((to, from, next) => {
setTimeout(() => app.loading = false, 1500) // timeout for demo purposes
next()
})
然后在模板中:
<loading v-if="$root.loading"></loading>
<router-view v-else></router-view>
这也可以很容易地在一个非常小的组件中包含,而不是使用$ root组件来加载状态。
答案 1 :(得分:0)
对于它的价值,我将分享我最终为自己的情况所做的事情。
我正在使用Vuex,因此很容易创建应用程序范围的“加载”状态,任何组件都可以访问该状态,但是您可以使用想要共享此状态的任何机制。
简化,它是这样的:
function componentLoader(store, fn) {
return () => {
// (Vuex) Loading begins now
store.commit('LOADING_BAR_TASK_BEGIN');
// (Vuex) Call when loading is done
const done = () => store.commit('LOADING_BAR_TASK_END');
const promise = fn();
promise.then(done, done);
return promise;
};
}
function createRoutes(store) {
const load = fn => componentLoader(store, fn);
return [
{
path: '/foo',
component: load(() => import('./components/foo.vue')),
},
{
path: '/bar',
component: load(() => import('./components/bar.vue')),
},
];
}
因此,我要做的就是通过() => import()
函数包装每个load()
,该函数负责设置加载状态。通过直接遵守承诺来确定负载,而不是依赖于特定于路由器的前/后挂钩。
答案 2 :(得分:0)
您可以在vuejs的一个项目中将此代码用于gobel路线
const router = new Router({
routes: [
{ path: '/', name: 'home', component: Home },
{ path: '/about', name: 'about', component: About }
]
})
router.beforeResolve((to, from, next) => {
// If this isn't an initial page load.
if (to.name) {
// Start the route progress bar.
NProgress.start()
}
next()
})
router.afterEach((to, from) => {
// Complete the animation of the route progress bar.
NProgress.done()
})