解决 Vue SPA 中使用路由守卫时页面闪动的问题

阅读时长 5 分钟读完

在使用 Vue 开发单页应用(SPA)时,我们经常会使用路由守卫来控制用户访问页面的权限。路由守卫的使用很方便,但在某些情况下,会出现页面闪动的问题,这个问题对用户体验有很大的影响。

问题分析

路由守卫的执行时机是在路由切换时,如下图所示:

图中可以看到,路由守卫的执行时机是在用户访问新页面时,但在路由守卫验证通过之前,页面已经显示出来了。这就导致了页面的闪动问题。

解决方案

解决页面闪动问题的方案是在路由切换之前,提前获取页面内容,并在验证通过后,再将内容渲染到页面中。这个方案可以使用 Vue 的异步组件和加载中组件来实现。

异步组件

异步组件是 Vue 中一个很方便的功能,它可以将组件的加载延迟到组件被访问时,可以避免在页面加载时同时加载大量组件的问题。异步组件的定义方式如下:

上述代码中,import('./views/User.vue') 返回一个 Promise 对象,当 Promise 对象被解析时,组件才会被加载。

加载中组件

加载中组件是一个用于提示用户正在加载内容的组件,可以在网络延迟或请求数据时展示。加载中组件的目的是让用户明确地知道,当前页面正在加载中,他们需要等待片刻才能看到内容。

可以为每个路由定义一个加载中组件,当路由守卫验证通过时,先显示加载中组件,然后异步加载组件,并将加载到的内容替换掉加载中组件。这样就可以避免页面闪动的问题。

示例

假设我们有一个需要登录才能访问的页面 /user,使用路由守卫来控制用户的访问权限。我们可以定义如下的路由:

-- -------------------- ---- -------
------ ------- ---- ---------------------------

----- ------ - --- -----------
  ------- -
    -
      ----- --------
      ---------- -------- -- ---------
      ----- - ------------- ---- --
      --------- -
        -
          ----- ---
          ---------- -- -- ---------------------------
          ----- - ------------- ---- --
        --
      --
    --
    -
      ----- ---------
      ---------- -- -- ----------------------------
    --
  --
---

---------------------- ----- ----- -- -
  -- ------------------------- -- -------------------------- -
    -- ------
    -- --------------- -
      ------
        ----- ---------
        ------ - --------- ----------- --
      ---
    - ---- -
      -------
    -
  - ---- -
    -------
  -
---

上述代码中,我们为需要登录的路由添加了 meta 属性,并在 beforeEach 中验证用户是否已经登录。如果用户已经登录,则允许访问路由,否则跳转到登录页面。

现在我们需要修改 /user 路由的组件渲染方式,让其先显示加载中组件,然后异步加载 User.vue 组件并渲染。这里我们可以定义一个高阶组件来实现:

-- -------------------- ---- -------
------ ------- ---- ----------------

-------- ----------------------------- -
  ------ -
    ---------- -- -- --
      ---------- ---------------------------------
      -------- --------
    ---
  --
-

-- ------
-
  ----- --------
  ---------- ----------------- -- ----------------------------
  ----- - ------------- ---- --
--

上述代码中,我们定义了一个 asyncComponent 函数,它接受一个组件的加载函数,返回一个异步组件的定义对象。异步组件的 component 选项是异步加载组件并解析 Promise(Promise.resolve(loadComponent())),加载过程中会显示 Loading 组件。

总结

在 Vue 的单页应用开发中,路由守卫是一个非常方便的功能,但在页面加载时会出现闪动问题,影响用户体验。通过使用异步组件和加载中组件,我们可以解决这个问题。在实际的开发中,可以将异步组件的定义、加载中组件的定义和路由守卫的使用封装到一个高阶组件中,方便复用和维护。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64aa0c7b48841e989463ad3a

纠错
反馈