在使用 Vue 开发单页应用(SPA)时,我们经常会使用路由守卫来控制用户访问页面的权限。路由守卫的使用很方便,但在某些情况下,会出现页面闪动的问题,这个问题对用户体验有很大的影响。
问题分析
路由守卫的执行时机是在路由切换时,如下图所示:
图中可以看到,路由守卫的执行时机是在用户访问新页面时,但在路由守卫验证通过之前,页面已经显示出来了。这就导致了页面的闪动问题。
解决方案
解决页面闪动问题的方案是在路由切换之前,提前获取页面内容,并在验证通过后,再将内容渲染到页面中。这个方案可以使用 Vue 的异步组件和加载中组件来实现。
异步组件
异步组件是 Vue 中一个很方便的功能,它可以将组件的加载延迟到组件被访问时,可以避免在页面加载时同时加载大量组件的问题。异步组件的定义方式如下:
{ path: '/user', component: () => import('./views/User.vue') }
上述代码中,import('./views/User.vue')
返回一个 Promise 对象,当 Promise 对象被解析时,组件才会被加载。
加载中组件
加载中组件是一个用于提示用户正在加载内容的组件,可以在网络延迟或请求数据时展示。加载中组件的目的是让用户明确地知道,当前页面正在加载中,他们需要等待片刻才能看到内容。
<template> <div class="loading"> <img src="./loading.gif" alt="Loading"> <p>正在加载,请稍后...</p> </div> </template>
可以为每个路由定义一个加载中组件,当路由守卫验证通过时,先显示加载中组件,然后异步加载组件,并将加载到的内容替换掉加载中组件。这样就可以避免页面闪动的问题。
示例
假设我们有一个需要登录才能访问的页面 /user
,使用路由守卫来控制用户的访问权限。我们可以定义如下的路由:
-- -------------------- ---- ------- ------ ------- ---- --------------------------- ----- ------ - --- ----------- ------- - - ----- -------- ---------- -------- -- --------- ----- - ------------- ---- -- --------- - - ----- --- ---------- -- -- --------------------------- ----- - ------------- ---- -- -- -- -- - ----- --------- ---------- -- -- ---------------------------- -- -- --- ---------------------- ----- ----- -- - -- ------------------------- -- -------------------------- - -- ------ -- --------------- - ------ ----- --------- ------ - --------- ----------- -- --- - ---- - ------- - - ---- - ------- - ---
上述代码中,我们为需要登录的路由添加了 meta
属性,并在 beforeEach
中验证用户是否已经登录。如果用户已经登录,则允许访问路由,否则跳转到登录页面。
现在我们需要修改 /user
路由的组件渲染方式,让其先显示加载中组件,然后异步加载 User.vue
组件并渲染。这里我们可以定义一个高阶组件来实现:
-- -------------------- ---- ------- ------ ------- ---- ---------------- -------- ----------------------------- - ------ - ---------- -- -- -- ---------- --------------------------------- -------- -------- --- -- - -- ------ - ----- -------- ---------- ----------------- -- ---------------------------- ----- - ------------- ---- -- --
上述代码中,我们定义了一个 asyncComponent
函数,它接受一个组件的加载函数,返回一个异步组件的定义对象。异步组件的 component
选项是异步加载组件并解析 Promise(Promise.resolve(loadComponent())
),加载过程中会显示 Loading
组件。
总结
在 Vue 的单页应用开发中,路由守卫是一个非常方便的功能,但在页面加载时会出现闪动问题,影响用户体验。通过使用异步组件和加载中组件,我们可以解决这个问题。在实际的开发中,可以将异步组件的定义、加载中组件的定义和路由守卫的使用封装到一个高阶组件中,方便复用和维护。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64aa0c7b48841e989463ad3a