这两天总结了关于vue-router优化的几点技法,做个笔记

在基于vue的移动端app中,通过vue-router可以便捷的进入某一路由或回退到上一路由,但是若不对vue-router做相关优化处理,则会造成以下几个问题:

1.切换路由时,频繁向后台发送请求

2.切换路由时,页面会卡顿,影响用户体验

基于这些困扰,我们从头开始探究vue-router

问题1:切换路由时,频繁向后台发送请求,以及解决办法

在常规的路由配置下,我们使用App.vue作为app根组件:

app.vue有一个router-view标签用于显示内部组件,

而在router/index.js中,path为'/'的根路由映射了home,这代表home组件作为App.vue的子组件

因而,App.vue下的router-view代表了身为子组件的home.vue,而home组件作为App.vue的子组件(路由),本身又是除app.vue以外所有后代路由的根路由。

它们一起构成了整个APP路由系统。这是vue-router的常规描述。

萌新们往往会将所有的路由一股脑的与根路由配置在同一级,但事实证明,这是不可取的。

假设我们F12键,打开netWork -> XHR 时就会发现,

在home路由下,进入某个路由,然后回退到上个路由时,我们请求了2次数据,即点击了要进入的路由时,请求了一次;回退到上个路由时,又请求了一次

而这与我们的期待是不一样的:每当我们点击一个新路由时,vue才向后台发送网络请求,而我们回退到某个路由时(比如本例,我们回退到home路由上),

则回退到的路由在没有刷新事件前不要请求数据。

所以原因就在于此:

与根路由同级时,每次进入或回退某个路由,上一个已请求到的路由资源都被销毁了,因而每当进入一个路由地址(无论是回退上一路由还是进入某一新路由),

app.vue都会重新加载一次router-view,vue都会向服务器发起一次网络请求,造成服务器实则没必要的花销。

并且随着用户不断进入或者回退某个路由,耗费的花销会越来越可观

那么,保持组件的状态,便是解决的方法:

  • 解决方法一:使用vue内置组件keep-alive保持组件状态

    使用keep-alive标签包裹app.vue里router-view标签,这样就相当于包裹了包括home在内的所有路由组件:

  1. <template>
  2. //App.vue
  3. <div id="app">
  4. <keep-alive>
  5. <router-view/>
  6. </keep-alive>
  7. </div>
  8. </template>

当我们打开f12再次尝试进入或者回退到某个标签时,发现只有在进入一个新路由地址时,才会发起请求, keep-alive可以缓存router-view的内容,

这样似乎已经达到了我们的期望,

但正是keep-alive的缓存特性有一个致命的缺陷———— keep-alive也会缓存动态路由的状态

尝试举个例子来解释这句话:

假设用户进入了一个商品界面,但用户对这个商品并不满意,当用户回退到上一级而进入了一个中意的商品界面却发现,

跟刚刚那个界面一样,且无论进入哪个商品界面都跟第一个商品界面一样时,

这便会是keep-alive的弊端----keep-alive标签会缓存动态路由的状态,因而不会再进行数据请求,

这对动态路由来说是致命的

所以,这个方法是不可取的

  • 解决办法二:更改router的配置

将home下所有子路由放置在home路由的children路由里,将子路由的子路由放置在子路由的children里,以此类推,即:

  1. //router/index.js
  2. {
  3. path: '/',
  4. name: 'Home',
  5. component: Home,
  6. // 根目录的子路由,优化路由,防止每次回退或进入都会加载
  7. //home路由的子路由放置在自身的children路由下
  8. children: [
  9. {
  10. path : '/playListView',
  11. name:'PlayListView',
  12. component:() => import(/* webpackChunkName: "about" */ '../views/playListView.vue'),
  13. children:[
  14. //子路由的子路由放置在自己的children下,以此类推
  15. {
  16. path : ':id',//传入id值,指明是哪一个playlist
  17. name:'PlayListViewInfo',
  18. component:() => import('../views/playListInfo.vue')
  19. }
  20. ]
  21. }
  22. ]
  23. }

如果某一后代路由是动态路由,直接给该后代路由加动态路由参数,不加父路由的path

如果使用了该方法,则还需要给home下每一个后代路由添加router-view标签,用以标识该路由是home根路由的后代路由

举个栗子:

  1. <template>
  2. <!-- 歌单视图 歌单详情页-->
  3. <div class="page">
  4. <div>
  5. <m-header>
  6. 全部歌单
  7. </m-header>
  8. <div class="play-wrapper">
  9. <play-list :data="playListData" @clickItem = 'gotoPlayListInfo '></play-list>
  10. </div>
  11. </div>
  12. <router-view/> <!-- 该路由组件上的router-view标签标识它的子路由-->
  13. </div>
  14. </template>

ps: 如果点击路由后有报错: Navigating to current location ("/router") is not allowed ,请点击这里

这样设置后,会出现点击无法进入路由的结果。

但是如果打开f12会看到DOM中存在有该后代路由的dom,且点击后,地址栏上已经显示了子组件的路由,但用户界面上依然只显示了home组件,

也就是说当点击了子路由以后,子路由显示了,但父路由依旧存在于当前界面,阻碍了用户的视图

这与我们期待的有所不同: 点击某个子路由,然后给用户展现该路由的内容,但其实已经接近明朗————仅仅是页面上有了父路由界面与子路由界面并存的现象

解决办法:(提高后代组件的层级,使后代组件可以覆盖父组件) 在home的所有后代路由的根div上添加一个叫page的class:

  1. /* app的公共样式common.js */
  2. .page{
  3. position: fixed;
  4. top: 0;
  5. left: 0;
  6. right: 0;
  7. bottom: 0;
  8. background:#f3f4f9 ; /*与html背景色保持一致*/
  9. z-index: 9999; /*使用最高层级,覆盖home组件的层级*/
  10. overflow: scroll;/*在移动端中使滚动可用*/
  11. }

而以上操作完成后,就可以发现,点击进入路由时,会发送一个网络请求,而回退到上一路由时,则不会发起请求,且页面正常显示;且就算进入了一个动态路由也可以正常显示

这样,就解决了切换路由时,频繁向后台发送请求的问题。

问题2: 进入某一路由或回退到上一路由时,页面会有生硬的进入显示现象,影响用户体验

原因: 路由间的切换没有添加过渡效果

基于问题一,我们可以使用vue的transition标签包裹组件的router-view标签,使用transition的name属性来定制过渡样式

举个栗子:

  1. <template>
  2. <div class="page">
  3. <div>
  4. <m-header >全部歌手</m-header>
  5. <artist-list :data="artistsData"
  6. @clickItem="gotoArtistsInfo"
  7. class="artist"></artist-list>
  8. </div>
  9. <transition name="slide"><!--
  10. 关于对vue-router的优化(详尽版)的更多相关文章

      1. Vue项目SEO优化的另一种姿态
      1. 背景:当前项目首页和登陆后的平台在一个项目里,路由采用hash模式,现在要做SEO优化,这时候同构SSR(Server Side Rendering)服务端渲染代价显然太大,影响范围比较广,同样更改当 ...

      1. Vue项目性能优化整理
      1. 以下方式基于 @vue/cli 快速搭建的交互式项目脚手架 1. 路由懒加载 当打包构建应用时,JavaScript 包会变得非常大,影响页面加载.如果我们能把不同路由对应的组件分割成不同的代码块,然 ...

      1. 【Vuejs】335-(超全) Vue 项目性能优化实践指南
      1. 点击上方"前端自习课"关注,学习起来~ 前言 Vue 框架通过数据双向绑定和虚拟 DOM 技术,帮我们处理了前端开发中最脏最累的 DOM 操作部分, 我们不再需要去考虑如何操作 D ...

      1. Vue Router 使用方法
      1. 安装 直接下载 / CDN https://unpkg.com/vue-router/dist/vue-router.js Unpkg.com 提供了基于 NPM 的 CDN 链接.上面的链接会一直指 ...

      1. Vue Router详细教程
      1. 1.什么是路由 1.1路由简介 说起路由你想起了什么?路由是一个网络工程里面的术语. 路由(routing)就是通过互联的网络把信息从源地址传输到目的地址的活动. --- 维基百科 额,啥玩意? 没听 ...

      1. VUE项目性能优化实践——通过懒加载提升页面响应速度
      1. 本文由葡萄城技术团队原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 最近我司因业务需求,需要在一个内部数据分析平台集成在线Excel功能,既然我 ...

      1. Vue 2.0 + Vue Router + Vuex
      1. 用 Vue.js 2.x 与相配套的 Vue Router.Vuex 搭建了一个最基本的后台管理系统的骨架. 当然先要安装 node.js(包括了 npm).vue-cli 项目结构如图所示: ass ...

      1. 电脑公司最新GHOST WIN7系统32,64位优化精简版下载
      1. 系统来自系统妈:http://www.xitongma.com 电脑公司最新GHOST win7系统32位优化精简版V2016年3月 系统概述 电脑公司ghost win7 x86(32位)万能装机版 ...

      1. vue router 只需要这么几步
      1. <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

    1. 随机推荐

        1. Hive学习笔记六
        1. 目录 查询 一.基本查询 1.全表和特定列查询 2.列别名 3.算术运算符 4.常用函数 5.Limit语句 二.Where语句 1.比较运算符(Between/In/ Is Null) 2.Like ...

        1. Consul+Nginx部署高可用
        1. 1. Consul Server 创建consul server虚拟主机 docker-machine create consul 出现如下内容即创建成功 Running pre-create che ...

        1. Spring Boot 邮件发送
        1. pom文件依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

        1. adb的连接设备故障分析(三)
        1. 一,如果使用adb devices进行检测,发现没有任何设备信息,我们就需要检查是否有手机/模拟器连接上 二,如果是手机进行连接,windows右下角有出来如下提示的话,需要检查你的手机驱动是否有安装 ...

        1. Java序列化机制剖析
        1. 本文转载自longdick的博文<Java序列化算法透析>,原文地址:http://longdick.iteye.com Java序列化算法透析 Serialization(序列化)是一种 ...

        1. JS面向对象介绍
        1. JS面向对象介绍 首先面向对象是什么?为什么要使用面向对象. 因为JavaScript对每个创建的对象都会自动设置一个原型(谷歌火狐中是proto),指向它的原型对象prototype,举个例子: f ...

        1. springboot项目下的Caused by: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):
        1. 今天遇到mybatis-puls的报错Caused by: org.apache.ibatis.binding.BindingException: Invalid bound statement (n ...

        1. Shell:Day04.笔记
        1. grep与正则表达式: 1.grep程序 Linux下有文本处理三剑客 - - grep sed awk grep:文本 行 过滤工具 sed:文本 行 编辑器(流编辑器) awk:报告生成器(做文本 ...

        1. 关于TD信息树自己的体验和建议
        1. 自己选择的是17级学长13组的TD消息树,通过对这个软件的使用,感觉整体上还是很好的,他的主要功能就相当于把微信的朋友圈还有qq的好友动态等功能集合到了一起.这个软件整体就相当于一个空间,可以加好友互 ...

        1. MTK Android 设置-选择日期格式 [管理和组织首选项,ListPreference,CheckBoxPreference,EditTextPreference,RingtonePreference]
        1. ###android.preference.ListPreference的一些特性 android:key  选项的名称或键 android:title  选项的标题 android:summary  ...