• wordpress CMS主题:ssmay主题 wordpress CMS主题:ssmay主题
  • 首页 > 前端开发 > Vue异步组件处理路由组件加载状态

    Vue异步组件处理路由组件加载状态

    作者: 分类:前端开发 点击: 1,046 次
    wordpress CMS主题:ssmay主题

      扫描下面的二维码,“关注”我的百家号。

      问题场景

      在大型单页面应用中,处于对性能的考虑和首屏加载速度的要求,我们一般都会使用webpack的代码分割和vue-router的路由懒加载功能将我们的代码分成一个个模块,并且只在需要的时候才从服务器加载一个模块。

      但是这种解决方案也有其问题,当网络环境较差时,我们去首次访问某个路由模块,由于加载该模块的资源需要一定的时间,那么该段时间内,我们的应用就会处于无响应的状态,用户体验极差。

      解决方案

      这种情况,我们一方面可以缩小路由模块代码的体积,静态资源使用cdn存储等方式缩短加载时间,另一方面则可以路由组件上使用异步组件,显示loading和error等状态,使用户能够得到清晰明了的操作反馈。
      Vue官方文档-动态组件&异步组件

      具体实现

      1. 声明方法,基于Vue动态组件工厂函数来返回一个Promise对象
      /**
       * 处理路由页面切换时,异步组件加载过渡的处理函数
       * @param  {Object} AsyncView 需要加载的组件,如 import('@/components/home/Home.vue')
       * @return {Object} 返回一个promise对象
       */
      function lazyLoadView (AsyncView) {
        const AsyncHandler = () => ({
          // 需要加载的组件 (应该是一个 `Promise` 对象)
          component: AsyncView,
          // 异步组件加载时使用的组件
          loading: require('@/components/public/RouteLoading.vue').default,
          // 加载失败时使用的组件
          error: require('@/components/public/RouteError.vue').default,
          // 展示加载时组件的延时时间。默认值是 200 (毫秒)
          delay: 200,
          // 如果提供了超时时间且组件加载也超时了,
          // 则使用加载失败时使用的组件。默认值是:`Infinity`
          timeout: 10000
        });
        return Promise.resolve({
          functional: true,
          render (h, { data, children }) {
            return h(AsyncHandler, data, children);
          }
        });
      }
      
      1. 引入路由
      const helloWorld = () => lazyLoadView(import('@/components/helloWorld'))
      
      1. vue-router中使用
      routes: [
          {
              path: '/helloWorld',
              name: 'helloWorld',
              component: helloWorld
          }
      ]
      

      至此,改造已经完成,当你首次加载某一个组件的资源时(可以将网速调为 slow 3g,效果更明显),就会显示你在loading组件的内容,而当超出超时时间仍未加载完成该组件时,那么将显示error组件的内容(建议error组件尽量简单,因为当处于低速网络或者断网情况下时,error组件内的图片资源等有可能出现无法加载的问题)

      关于使用异步组件后路由钩子失效的问题

      在使用本文的配置对路由引入方式进行重构后,会出现路由钩子无法使用的问题,这个问题也是刚刚发现,在查阅资料后发现,vue-router目前对于这种使用方法是不支持的...
      官方解释为:

      > WARNING: Components loaded with this strategy will **not** have access to
      in-component guards, such as `beforeRouteEnter`, `beforeRouteUpdate`, and
      `beforeRouteLeave`. If you need to use these, you must either use route-level
      guards instead or lazy-load the component directly, without handling loading
      state.
      

      链接:https://github.com/vuejs/vue-router/pull/2140/commits/8975db3659401ef5831ebf2eae5558f2bf3075e1?tdsourcetag=s_pctim_aiomsg

      关于使用异步组件后路由钩子失效的解决方法

      1. 需要使用路由钩子的页面放弃异步加载,使用普通的懒加载
      2. 使用created, mounted等钩子替代路由钩子
        其他办法进一步查找中,欢迎各位在评论中提出问题和解决方案。

      本文转载于:Vue异步组件处理路由组件加载状态



      欢迎“关注”我的百家号。

      头条二维码
      加入我的QQ群
      头条二维码
      关注我的百家号

    文章作者:sunny
    本文地址:http://wanlimm.com/77202006218356.html
    版权所有 © 转载时必须以链接形式注明作者和原始出处!

    上一篇:
    下一篇:
    wordpress CMS主题:ssmay主题

    或许你会感兴趣的文章:

    发表评论

    您的电子邮箱地址不会被公开。 必填项已用*标注

    此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据