路由是网络工程里面的专业术语,就是通过互联把信息从源地址传输到目的地址的活动。本质上就是一种对应关系。分为前端路由和后端路由。

后端路由:

URL 的请求地址与服务器上的资源对应,根据不同的请求地址返回不同的资源。

前端路由:

在单页面应用中,根据用户触发的事件,改变URL在不刷新页面的前提下,改变显示内容。

1、前端路由实现原理

URL 的 hash 模式

改变 hash 值的时候,#是一个位置标识符,可以进行页面内的位置跳转,并不会刷新页面。

通过 location.hash 改变页面的 hash 值,如:

我们发现页面并不会刷新。

URL 的 history 模式

history 模式,有 5 种改变 url 而不刷新页面的方法,分别为:

history.pushState() //压入栈
history.replaceState() // 替换当前url,不能返回上一个页面
history.back() //返回上一个页面
history.go(n) //n的值可以是大于0的,表示向前几个,小于0时,表示向后退几个
history.forward() //向前一步

history.go(-1) 等价于 history.back()

history.go(1) 等价于 history.forward()

前端三大框架,都有自己的路由:

Angular 有 ngRouter

React 有 ReactRouter

Vue 有 vue-Router

2、vue-Router 基本使用

2.1、安装

npm install vue-router --save

使用 vue-router 的前提是 vue 必须使用

在 router 文件夹内 index.js 引入vue-router

import Vue from 'vue'
import VueRouter from 'vue-router' Vue.use(VueRouter) //引用 vue-router 插件

2.2、配置路由

//配置路由与组件之间的关系
const route=[
{
path: '/',
// 当访问 '/'的时候 路由重定向 到新的地址 '/home'
redirect: '/home',
},
{
path: '/home',
component: home,
},
{
path: '/login',
component: login,
},
]

2.3、实例化

const router = new VueRouter({
mode: "history", //设置模式
routes
});

2.4、挂载路由

到 main.js 中,vue 实例化中,把 router 挂载的 vue 上。

let app = new Vue({
el:'#app',
data:{},
// 挂载到vue上面
router,
})

2.5、页面上添加 router-link 和 router-view

<!-- 添加路由 -->
<router-link to="/home">首页</router-link>
<router-link to="/about">关于</router-link> <!-- 展示路由内容 -->
<router-view />

router-link 默认会被渲染成 a 标签,如:

<router-link to="/home">首页</router-link>
// 渲染成
<a href="#/home">首页</a>

router-view 是用来占位的,将路由对应的组件展示到该位置。

3、router 的模式

路由模式有两种,hash 和 history 模式。

3.1、hash 模式

vue-router 默认使用的是 hash 模式。

hash 的 url 中锚点就是 #xx 号后的内容,通过锚点作为路由地址,我们通常改变的是#号后的内容,实现浏览器渲染指定的组件,锚点发生改变会触发 onhashchange 事件。

3.2、history 模式

history就是正常的 url,没有#号,使用的时候需要服务器进行配置。history模式下,对应的方法与上述 5 个方法是一样的。

vue-router 中可以指定需要的模式:

const router = new VueRouter({
mode:'history'
})

4、router-link的属性

router-link 默认会渲染成 a 标签,但是有时候你想渲染成别的标签也是可以的。

4.1、tag 属性

tag属性是用来设置 router-link 标签渲染类型的,如我们想把 router-link 渲染成 button,如:

<router-link to="/home" tag="button">首页</router-link>

查看渲染后的元素,发现变成 button 标签了,对应的 to 添加的属性值就会失效。此时点击无法跳转到对应内容,可继续阅读下边跳转方式。

除了 button ,tag 的属性值还可以是其他任意标签,router-link 自动渲染成对应的标签。

4.2、replace 属性

replace与上边 history 模式中的 replaceState 对应,跳转的时候不会留下 history 记录,指定replace 的情况下,不能返回上一页。

<router-link to="/home" replace>首页</router-link>

4.3、active-class

active-class 设置 router-link 点击当前选中的类名,默认情况下类名为:router-link-active

<a href="#/"
aria-current="page"
class="router-link-exact-active router-link-active">
首页
</a>

设置当前元素样式需要设置到:router-link-active。

设置 active-class ,如:

<router-link to="/" active-class="active">首页</router-link>
// router-link-active 类名会被替换成 active

如果需要把全局的 router-link 的选择类名都修改成自定义的,一个一个单独设置工作量太大,可以在 router 中统一设置。

const router=new VueRouter({
routes,
mode: 'hash',
linkActiveClasss: 'active' //统一设置类名
})

5、vue-Rrouter 页面跳转方式

5.1、router-link 实现

// 简单写法
<router-link to="/">首页</router-link> //使用动态的path
<router-link :to="{ path : '/' }"></router-link>
可以使用path 也可以使用name //带传参跳转1
<router-link :to="
{ name:'home', params:{ id:'123' , name:'gq' }}
">
</router-link> //带传参跳转
<router-link :to="
{ path:'/', query:{ id:'123' , name:'gq' }}
">
</router-link>

5.2、通过 js 实现跳转

// 简单写法
this.$router.push({ path:'/' })
// push 与history.pushState 一样 //带参跳转
this.$router.push({
name: 'home' , params: { id:'123' , name:'gq' }
}) //带多种参数
this.$router.push({
name: 'home' ,
params: { id:'123' , name:'gq' },
query: { plan:'private' }
})

6、动态路由

在某些情况下,一个页面的 path 路径可能是不确定的,如:希望的路径为 /user/123或 /user/456 。后边的值为用户 id 或其他值。

配置路由

routers:[
{
path: '/user/:id',
component:()=>{ import('../views/user.vue') }
}
]

添加路由

<router-link to="/user/123"> user:123 </router-link>
<router-link to="/user/456"> user:456 </router-link> //动态设置后边id值
<router-link :to=" '/user/'+id "> user:{{ id }} </router-link>

获取后边动态值

this.$route.params.id 
此处的 id 是配置路由处设置的 id ,只要保持一致就可以了

方式二:使用 query 进行传参

<router-link to="/user?id=123"></router-link>

//取值时
this.$route.query.id

另外,this.$router.addRoutes([]) 也可以添加动态路由,里面传的是一个数组,与 routes 配置一样。

7、路由的懒加载

懒加载通俗的讲就是使用的时候再加载,不使用的时候不加载。

打包构建应用程序的时候,js包会变得很大,影响加载速度,如果我们能把不同路由对应的组件分割成不同的代码块,然后访问路由的时候才加载对应的组件,这样就更加高效了。

路由懒加载到底做了什么呢?主要作用就是将路由对应的组件打包成一个js代码块,只有路由访问的时候,才加载对应的 js 。

//直接引用的
import Home from './component/home'
const routes = [
{
path:'/home',
component:Home
}
] //懒加载
const routes = [
{
path:'/home',
component:()=>{ import('./component/home') }
}
]

8、嵌套路由

实际应用中,通常由多层嵌套的组件组合而成。

实现步骤:

第一:创建对应的子组件,并且在路由映射中配置对应的子路由。

第二:组件内部使用 router-view 标签

{
path: "/body",
component: ()=> import( "../components/bodyLayout.vue"),,
children:[
{
path: "manager",
component: ()=> import( "../components/blankView.vue"),
children:[
{
path: "user",
component: ()=> import( "../views/manager/user.vue")
},
]
},
]
}

访问 user 组件时,路由为:/body/manager/user

注意:嵌套路由设置 path 时,不能添加 “/”,否则路由就变了。

{
path: "/user",
component: ()=> import( "../views/manager/user.vue")
}
//此时访问路由就变成了 " /user "

9、router 与 route 区别

试着在main.js 打印 router 在任意组件内打印 this.$router,打印结果如图:

我们发现两个结果是一模一样的。这样我们就不难理解下面的意思了。

router 为 VueRouter 实例,拥有自己的方法,如:使用 new VueRouter创建的实例,想要导航到不同url,可以使用 router.push ,跳转方式中有介绍。

route 为当前活跃状态路由对象,有当前路由的信息,可以通过该对象,获取 path、params参数、query参数、name、matched、hash

10、路由守卫

为什么使用导航守卫?我们来考虑一个需求:在 SPA应用中,网页标题跟着页面切换如何变动?

// 在对应的组件内添加
created(){
document.title="测试"
}
访问该组件时,标题自动切换为 ”测试“

如果使用上述方法,那么对应已开发的组件有多少个,我们就得添加多少次,实在是太麻烦了,所以我们要借助路由守卫,统一修改,也便于维护。

10.1、全局守卫

1>、使用 router.beforeEach 注册一个全局前置守卫,只要路由变动时,都会经过它。beforeEach 接收的参数是一个函数,包含的参数有三个。

router.beforeEach((to,from,next)=>{
// 路由从 from 跳转到 to
// 我们只需要在路由上增加一个 name属性就可以了
document.title = from.name
next()
})

注意:上述三个参数顺序不能改变。next 不能丢,必须添加,否则页面跳转的时候没法到下一步,卡在空白区域。

2>、使用 router.afterEach 注册一个全局后置守卫。

router.afterEach((to,from)=>{
console.log('后置守卫')
})

这两个守卫都是全局守卫,afterEach 是在路由跳转完成才执行的,所以不需要 next 。参数只有两个。

10.2、路由独享守卫

路由配置上直接定义的守卫,用法与全局守卫一致,只是将其放在其中一个路由对象中,只有这个路由下起作用。

{
path: "/test",
name: "测试",
component: ()=> import( "../views/manager/test.vue"),
beforeEnter:(to,from,next)=>{
console.log('test进入前')
next()
}
}

这些守卫与全局前置守卫的方法参数是一样的。

10.3、组件内守卫

可以在路由组件内直接定义路由导航守卫,定义在组件内的就是组件内守卫。

const Foo = {
template: `...`,
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}

注意:beforeRouteLeave 离开路由时执行,必须添加 next,否则无法正常跳转到下一个路由。

11、keep-alive

切换路由的时候页面每次都会重新渲染,我们有的组件会存在一些数据需要保留,不希望来回切换时每次都重新渲染,所以就使用 keep-alive 包裹组件,这样只有第一次执行加载时会执行 created mounted 等钩子函数。

keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

<div id="app">
<router-link to="/home">home</router-link>
<router-link to="/login">login</router-link>
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>

添加 keep-alive 组件,切换的时候,组件只会在第一次的时候渲染组件,之后进入不会重新渲染。

11.1、keep-alive 特定方法

activated(){
console.log('activated')
},
deactivated(){
console.log("deactivated")
}

这两个函数,只有组件被保持了状态,使用keep-alive时,才是有效会执行的。

keep-alive生命周期执行顺序:

created -> mounted -> activated

deactivated 在退出后才会触发

11.2、keep-alive 属性

keep-alive 有两个非常重要的属性:

include - 字符串或正则表达式,只有匹配组件的时候才会被缓存

exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存

<keep-alive include="test">
<router-view></router-view>
</keep-alive> //test组件 添加name属性
<template>
<div>
test
</div>
</template>
<script>
export default {
name:'test'
}
<script>

此时只有 test 组件会被缓存,其他任意组件都不会缓存。

如果还有其他组件同时需要被缓存,include可添加多个值,只用逗号隔开,但不能添加空格。

<keep-alive include="test,user">
<router-view></router-view>
</keep-alive>

exclude的使用:

<keep-alive exclude="test,user">
<router-view></router-view>
</keep-alive>

正好与上实例相反,只有 test,user 两个组件不被缓存,其他的被缓存。

一文让你彻底搞懂 vue-Router的更多相关文章

  1. C语言重点——指针篇(一文让你完全搞懂指针)| 从内存理解指针 | 指针完全解析

    有干货.更有故事,微信搜索[编程指北]关注这个不一样的程序员,等你来撩~ 注:这篇文章好好看完一定会让你掌握好指针的本质 C语言最核心的知识就是指针,所以,这一篇的文章主题是「指针与内存模型」 说到指 ...

  2. C\C++语言重点——指针篇 | 为什么指针被誉为 C 语言灵魂?(一文让你完全搞懂指针)

    本篇文章来自小北学长的公众号,仅做学习使用,部分内容做了适当理解性修改和添加了博主的个人经历. 注:这篇文章好好看完一定会让你掌握好指针的本质! 看到标题有没有想到什么? 是的,这一篇的文章主题是「指 ...

  3. 一文带你快速搞懂动态字符串SDS,面试不再懵逼

    目录 redis源码分析系列文章 前言 API使用 embstr和raw的区别 SDSHdr的定义 SDS具体逻辑图 SDS的优势 更快速的获取字符串长度 数据安全,不会截断 SDS关键代码分析 获取 ...

  4. 面试都在问的微服务、服务治理、RPC、下一代微服务框架... 一文带你彻底搞懂!

    文章每周持续更新,「三连」让更多人看到是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 单体式应用程序 与微服务相对的另一个概念是传统的单体式应用程序( ...

  5. 面试都在问的「微服务」「RPC」「服务治理」「下一代微服务」一文带你彻底搞懂!

    ❝ 文章每周持续更新,各位的「三连」是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) ❞ 单体式应用程序 与微服务相对的另一个概念是传统的「单体式应用程 ...

  6. 一文带大家彻底搞懂Hystrix!

    前言? Netflix Hystrix断路器是什么? Netflix Hystrix是SOA/微服务架构中提供服务隔离.熔断.降级机制的工具/框架.Netflix Hystrix是断路器的一种实现,用 ...

  7. 搞懂ELK并不是一件特别难的事(ELK)

    本篇文章主要介绍elk的一些框架组成,原理和实践,采用的ELK本版为7.7.0版本 一.ELK介绍 1.1.ELK简介 ELK是Elasticsearch.Logstash.Kibana三大开源框架首 ...

  8. 不想再被鄙视?那就看进来! 一文搞懂Python2字符编码

    程序员都自视清高,觉得自己是创造者,经常鄙视不太懂技术的产品或者QA.可悲的是,程序员之间也相互鄙视,程序员的鄙视链流传甚广,作为一个Python程序员,自然最关心的是下面这幅图啦 我们项目组一值使用 ...

  9. 一文搞懂RAM、ROM、SDRAM、DRAM、DDR、flash等存储介质

    一文搞懂RAM.ROM.SDRAM.DRAM.DDR.flash等存储介质 存储介质基本分类:ROM和RAM RAM:随机访问存储器(Random Access Memory),易失性.是与CPU直接 ...

随机推荐

  1. 零基础学Java之Java学习笔记(三):变量和数据类型

    为什么需要变量? 变量是一个程序的基本组成单位. 变量的概念: 变量相当于内存中一个数据存储空间的表示,你可以把变量看做是一个房间的门牌号,通过门牌号我们可以找到房 间,而通过变量名可以访问到变量(值 ...

  2. 从 FFmpeg 性能加速到端云一体媒体系统优化

    7 月 31 日,阿里云视频云受邀参加由开放原子开源基金会.Linux 基金会亚太区.开源中国共同举办的全球开源技术峰会 GOTC 2021 ,在大会的音视频性能优化专场上,分享了开源 FFmpeg ...

  3. Django 反向解析 request CBV

    正则路径中的分组 无名分组 分组的概念:就是给某一段正则表达式用小括号括起来 无名分组按位置传参数,一一对应. view中除去request,其他形参数量要与urls中分组数量一致. 无名分组就是将括 ...

  4. SQL 练习36

    查询不同课程成绩相同的学生的学生编号.课程编号.学生成绩 select a.cid, a.sid, a.score from sc as a,sc as b WHERE a.sid = b.sid a ...

  5. js判断对象的某个属性是否存在

    参考:https://www.jb51.net/article/141994.htm 原始数据, [ {"name":"向阳镇","id": ...

  6. 处理URLs

    问题 你有一个包含相对URLs路径的HTML文档,需要将这些相对路径转换成绝对路径的URLs. 方法 在你解析文档时确保有指定base URI,然后 使用 abs: 属性前缀来取得包含base URI ...

  7. 【springcloud】服务熔断与降级(Hystrix)

    转自:https://blog.csdn.net/pengjunlee/article/details/86688858 服务熔断 服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的 ...

  8. Spring Data JPA:解析CriteriaBuilder

    源码 在Spring Data JPA相关的文章[地址]中提到了有哪几种方式可以构建Specification的实例,该处需要借助CriteriaBuilder,回顾一下Specification中t ...

  9. vue3.0入门(一)

    前言 最近在b站上学习了飞哥的vue教程 学习案例已上传,下载地址 使用方式 使用在线cdn 下载js文件并自托管,引入到项目后使用 使用npm安装后,用cli来构建项目 声明式渲染 Vue2需引入v ...

  10. JavaSE-Java基础面试题

    重载与重写的区别 重载:本类中,方法名相同,参数列表不同,(参数类型.参数顺序.参数个数),返回值类型可以不同,访问修饰符可不同 重写:子类中,方法名相同,参数不能改,返回值类型一致或其子类,访问权限 ...