这两天总结了关于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在内的所有路由组件:

<template>
//App.vue
<div id="app">
<keep-alive>
<router-view/>
</keep-alive>
</div>
</template>

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

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

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

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

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

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

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

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

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

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

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

//router/index.js
{
path: '/',
name: 'Home',
component: Home,
// 根目录的子路由,优化路由,防止每次回退或进入都会加载
//home路由的子路由放置在自身的children路由下
children: [
{
path : '/playListView',
name:'PlayListView',
component:() => import(/* webpackChunkName: "about" */ '../views/playListView.vue'),
children:[
//子路由的子路由放置在自己的children下,以此类推
{
path : ':id',//传入id值,指明是哪一个playlist
name:'PlayListViewInfo',
component:() => import('../views/playListInfo.vue')
}
]
}
]
}

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

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

举个栗子:

<template>
<!-- 歌单视图 歌单详情页-->
<div class="page">
<div>
<m-header>
全部歌单
</m-header>
<div class="play-wrapper">
<play-list :data="playListData" @clickItem = 'gotoPlayListInfo '></play-list>
</div>
</div>
<router-view/> <!-- 该路由组件上的router-view标签标识它的子路由-->
</div>
</template>

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

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

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

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

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

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

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

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

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

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

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

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

举个栗子:

<template>
<div class="page">
<div>
<m-header >全部歌手</m-header>
<artist-list :data="artistsData"
@clickItem="gotoArtistsInfo"
class="artist"></artist-list>
</div>
<transition name="slide"><!--

关于对vue-router的优化(详尽版)的更多相关文章

  1. Vue项目SEO优化的另一种姿态

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

  2. Vue项目性能优化整理

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

  3. 【Vuejs】335-(超全) Vue 项目性能优化实践指南

    点击上方"前端自习课"关注,学习起来~ 前言 Vue 框架通过数据双向绑定和虚拟 DOM 技术,帮我们处理了前端开发中最脏最累的 DOM 操作部分, 我们不再需要去考虑如何操作 D ...

  4. Vue Router 使用方法

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

  5. Vue Router详细教程

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

  6. VUE项目性能优化实践——通过懒加载提升页面响应速度

    本文由葡萄城技术团队原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 最近我司因业务需求,需要在一个内部数据分析平台集成在线Excel功能,既然我 ...

  7. Vue 2.0 + Vue Router + Vuex

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

  8. 电脑公司最新GHOST WIN7系统32,64位优化精简版下载

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

  9. vue router 只需要这么几步

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

随机推荐

  1. coding++:error 阿里云 Redis集群一直Waiting for the cluster to join....存在以下隐患

    1):Redis集群一直Waiting for the cluster to join... 再次进行连接时首先需要以下操作 1.使用redis desktop Manager连接所有节点 调出命令窗 ...

  2. coding++:maven根据不同的运行环境,打包不同的配置文件

    1.使用maven管理项目中的依赖,非常的方便.同时利用maven内置的各种插件,在命令行模式下完成打包.部署等操作,可方便后期的持续集成使用. 2.但是每一个maven工程(比如web项目),开发人 ...

  3. Go相关面试题目总结(日常更新)

    1.go的深拷贝与浅拷贝 深拷贝 会赋值全部的内容 内容一样但是地址不一样 修改任何一个后地址不一样 内容也会一样 changeName(h1)对象传到函数里面也是深拷贝 b := a 这是深拷贝 会 ...

  4. SimpleITK中术语

    在SimpleITK中,各术语对应如下: Width: 宽度,X轴,矢状面Height: 高度,Y轴,冠状面Depth: 深度, Z轴,横断面 引用自:https://blog.csdn.net/Ji ...

  5. 模块 face_recognition 人脸识别

    face_recognition 人脸识别 api 说明 1 load_image_file 将img文件加载到numpy 数组中 2 face_locations 查找图像中所有面部和所有面部特征的 ...

  6. phpStorm 激活方式

    phpStorm10  激活方式 方法一:   注册时选择License server  http://idea.lanyus.com/    方法二:  用户名:Ly  注册码:  \===== L ...

  7. B. The Monster and the Squirrel

    B. The Monster and the Squirrel Ari the monster always wakes up very early with the first ray of the ...

  8. Vertica的这些事(十四)——Vertica实时消费kafka实现

    一. 安装环境 Vertica官方提供了消费kafka的方法,需要注意版本对应 消费kafka原理,是Vertica提供的Udx 首先需要安装相应的环境 /${vertica}/packages/ka ...

  9. 从JDK源码学习Arraylist

    从今天开始从源码去学习一些Java的常用数据结构,打好基础:) Arraylist源码阅读: jdk版本:1.8.0 首先看其构造方法: 构造方法一: 第一种支持初始化容量大小,其中声明一个对象数组, ...

  10. 1048 Find Coins (25分)

    Eva loves to collect coins from all over the universe, including some other planets like Mars. One d ...