多个路由通过路由器进行管理。

前端路由的概念和原理

(编程中的)路由(router)就是一组key-value对应关系,分为:后端路由和前端路由

后端路由指的是:请求方式、请求地址function处理函数之间的对应关系

在SPA程序中,所有组件的展示和切换都在这唯一的一个页面内完成,此时,不同组件之间的切换需要通过前端路由来实现

通俗易懂的来说,前端路由是:Hash地址(url中#的部分)与组件之间的对应关系

前端路由的工作方式

  • 用户点击了页面上的路由链接
  • 导致了URL地址栏中的Hash值发生了变化
  • 前端路由监听到了Hash地址的变化
  • 前端路由把当前Hash地址对应的组件渲染到浏览器中

实现简易的前端路由(底层实现原理)

App.vue根组件

<template>
<div>
<h1>这是App根组件</h1>
<a href="#/Home">Home</a>&nbsp;
<a href="#/Movie">Movie</a>&nbsp;
<a href="#/About">About</a>&nbsp;
<hr> <component :is="comName"></component>
</div> </template> <script>
import MyHome from './MyHome.vue'
import Mymovie from './MyMovie.vue'
import MyAbout from './MyAbout.vue'
import { walkFunctionParams } from '@vue/compiler-core' export default {
name:'App',
components:{
MyHome,
MyAbout,
Mymovie,
},
data(){
return{
comName:'MyHome'
}
},
created(){
window.onhashchange=()=>{
switch(location.hash){
case '#/Home':
this.comName='MyHome'
break
case '#/Movie':
this.comName='MyMovie'
break
case '#/About':
this.comName='MyAbout'
break
}
}
} }
</script> <style lang="less" scoped> </style>

vue-router的基本使用

vue-router是vue.js官方给出的路由解决方案,它只能结合vue项目进行使用,能够轻松的管理SPA项目中的组件切换。

二者差异主要是在声明router配置文件上。

vue-router 3.x的基本使用步骤

  • 在项目中安装vue-router
npm install vue-router@3.5.2 -S
  • src源代码目录下,新建router/index.js路由模块
//导入包
import Vue from 'vue'
import VueRouter from 'vue-router'
//插件引入
Vue.use(VueRouter)
//创建路由的实例对象
const router = new VueRouter
//向外共享
export default router
  • 在入口文件main.js中引入
import router from '@/router/index.js'
......
new Vue({
...
router:router
...
}).$mount('#app')

vue-router 4.x的基本使用步骤

  • 在项目中安装vue-router
npm install vue-router@next -S
  • 定义路由组件

MyHome.vue、MyMovie.vue、MyAbout.vue

  • 声明路由链接占位符

可以使用<router-link>标签(会被渲染成a链接)来声明路由链接,并使用<router-view>标签来声明路由占位符

<template>
<div>
<h1>这是App根组件</h1>
<!-- <a href="#/Home">Home</a>&nbsp;
<a href="#/Movie">Movie</a>&nbsp;
<a href="#/About">About</a>&nbsp; --> <!-- 声明路由链接 -->
<router-link to="/home">首页</router-link>
<router-link to="/movie">电影</router-link>
<router-link to="/about">我的</router-link>
<hr>
<!-- 路由占位符 -->
<router-view></router-view>
<component :is="comName"></component>
</div> </template>
  • 创建路由模块

从项目中创建router.js路由模块,按照以下四步:

从vue-router中按需导入两个方法

import { createRouter, createWebHashHistory } from 'vue-router'
//createRouter方法用于创建路由的实例对象
//createWebHashHistory用于指定路由的工作方式(hash模式)

导入需要使用路由控制的组件

import MyHome from './MyHome.vue'
import MyMovie from './MyMovie.vue'
import MyAbout from './MyAbout.vue'

创建路由实例对象

const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/home', component: MyHome
},
{
path: '/movie', component: MyMovie
},
{
path: '/about', component: MyAbout
}, ]
})

向外共享路由实例对象

export default router

在main.js中导入并挂载路由模块

import { createApp } from 'vue'
import App from './App.vue'
import './index.css' import router from './components/router' const app = createApp(App)
//挂载路由写法
app.use(router)
app.mount('#app')
  • 导入并挂载路由模块

vue-router的高级用法

路由重定向

指的是:用户在访问地址A的时候,强制用户跳转到地址C,从而展示特点的组件页面

通过路由规则的redirect属性,指定新的路由地址

const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/home', component: MyHome
},
{
path: '/',redirect:'/home' //访问根路径会重定向到home组件
},
{
path: '/movie', component: MyMovie
},
{
path: '/about', component: MyAbout
}, ]
})
路由传参

query参数

<router-link :to="/about/home/message?id=123&title='abc'">我的</router-link>

<router-link :to="{
path:'/about/home/message',
query:{
id:123,
title:'abc'
}
}">
我的
</router-link>

params参数

声明时:

path:'/about/home/message/:id/:title'
<router-link :to="/about/home/message/123/abc">我的</router-link>

<router-link :to="{
name:'my',
params:{
id:123,
title:'abc'
}
}">
我的
</router-link>

this.$route 是路由的"参数对象"

this.$router 是路由的"导航对象"

路由高亮
  • 使用默认的高亮class类名

被激活的路由链接,默认会使用router-link-active的类名,开发者可以使用此类名选择器,为激活的路由链接设置高亮样式

  • 自定义路由高亮的class类

在创建路由的实例对象时,开发者可以基于linkActiveClass属性,自定义类名

const router = createRouter({
history: createWebHashHistory(),
linkActiveClass:'active-router',
routes: [
{
path: '/home', component: MyHome
},
{
path: '/',redirect:'/home' //访问根路径会重定向到home组件
},
{
path: '/movie', component: MyMovie
},
{
path: '/about', component: MyAbout
}, ]
})
嵌套路由

通过路由来实现组件的嵌套展示

步骤:

  • 声明子路由链接和子路由占位符
<template>
<div>MyAbout组件</div>
<hr>
<router-link to="/about/tab1">tab1</router-link>&nbsp;
<router-link to="/about/tab2">tab2</router-link> <router-view></router-view>
</template>
  • 在父路由规则中,通过children属性嵌套声明子路由规则
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/home', component: MyHome
},
{
path: '/movie', component: MyMovie
},
{
path: '/about', component: MyAbout,children:[
{
path:'tab1',component:Tab1
},
{
path:'tab2',component:Tab2
},
]
}, ]
})

子路由规则的path不要以/开头

在嵌套路由中实现路由的重定向

const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/home', component: MyHome
},
{
path: '/movie', component: MyMovie
},
{
path: '/about',
component: MyAbout,
redirect:'/about/tab1',
children:[
{
path:'tab1',component:Tab1
},
{
path:'tab2',component:Tab2
},
]
}, ]
})
动态路由匹配

指的是:把Hash地址中可变的部分定义为参数项,从而提高路由规则的复用性,在vue-router中使用英文冒号:来定义路由的参数

  {
path: '/movie/:id', component: MyMovie
},

获取动态路由参数值的方法:

  • $route.params参数对象
<template>
<div>Mymovie组件---{{$route.params.id}}</div> </template>
  • 使用props接受路由参数
{
path: '/movie/:id', component: MyMovie,
props: true,
},

为了简化路由参数的获取形式,vue-router允许在路由规则开启props传参

编程式导航

通过调用API实现导航的方式,叫做编程式导航,与之对应的,通过点击链接实现导航的方式,叫做声明式导航

  • 普通网页中点击a链接,vue项目中点击<router-link>都属于声明式导航
  • 平台网页中调用location.herf跳转到新页面的方式,属于编程式导航

vue-router中编程式导航API

  • this.$router.push('hash地址') 跳转到指定Hash地址,并增加一条历史记录,从而展示对应的组件。
  • this.$router.replace('hash地址') 跳转到指定Hash地址,并替换当前的历史记录,从而展示对应的组件。
  • this.$router.go('数值n') 实现导航历史的前进、后退(-1),超过最大层数,则原地不动。

$router.back() 后退到上一层页面

$router.forward() 前进到下一层页面

命名路由

通过name属性为路由规则定义名称,叫做命名路由,name值不能重复,具有唯一性

Hash地址特别长时体现出命名路由的优势

  • 使用命名路由实现声明式导航
<template>
<h3>
MyHome组件
</h3>
<router-link :to="{name:'mov',params:{id : 3}}">goToMovie</router-link>
</template> <script>
export default {
name:'MyHome',
}
</script>
  • 使用命名路由实现编程式导航
<template>
<h3>
MyHome组件
</h3>
<button @click="goToMovie(3)">
goToMovie
</button>
</template> <script>
export default {
method: {
goToMovie(id) {
this.$router.push({name:'mov',params:{id : 3}})
}
}
}
</script>
导航守卫

导航守卫可以控制路由的访问权限

如何声明全局的导航守卫

全局的导航守卫会拦截每个路由规则,从而对每个路由都进行访问权限的控制

const router = createRouter({
...
})
//调用路由实例对象的beforeEach函数,fn必须是一个函数吗,每次拦截后,都会调用fn进行处理
//声明全局的导航守卫,fn称为守卫方法
router.beforeEach(fn) router.beforeEach(()=>{
console.log('Ok')
})

守卫方法的三个形参(可选)

router.beforeEach((to,from,mext)=>{
console.log('Ok')
//to 目标路由对象(信息)
//from当前导航正要离开的路由对象
//next 是一个函数,表示放行
})

注:

在守卫方法中不声明next形参,则默认允许用户访问每一个路由

在守卫方法中声明了next形参,则必须调用next()函数,否则不允许用户访问如何一个路由!

next函数的3种调用方式

//声明全局的导航守卫
router.beforeEach((to, from, next) => {
if (to.path === '/main') {
//证明用户要访问后台主页
next(false)//强制用户停留在之前所处的组件
next('login')//强制用户调转到指定页面
} else {
//证明用户要访问的不是后台主页
next()
}
})

结合token控制后台主页的访问权限

router.beforeEach((to, from, next) => {
const tokenStr = localStorage.getItem('token') //读取token if (to.path === '/main' && !tokenStr) { //token不存在,需要登录
//证明用户要访问后台主页
// next(false)//强制用户停留在之前所处的组件
next('login')//强制用户调转到指定页面
} else {
//证明用户要访问的不是后台主页
next()
}
})

Hash&History

路由器的两种工作模式:hash&history

对于url来说:#及后面的内容就是hash值,hash值不会带给服务器。

hash模式:

  1. 地址中永远带着#号,不美观;
  2. 若地址校验严格,会被标记为不合法;
  3. 兼容性较好;

history模式:

  1. 地址干净,美观;
  2. 兼容性比hash模式较差;
  3. 应用部署上线需要后端支持,解决刷新页面服务端404问题;(node可以使用connect-history-api-fallback

万字血书Vue—路由的更多相关文章

  1. Vue路由vue-router

    前面的话 在Web开发中,路由是指根据URL分配到对应的处理程序.对于大多数单页面应用,都推荐使用官方支持的vue-router.Vue-router通过管理URL,实现URL和组件的对应,以及通过U ...

  2. 攻克vue路由

    先下手 路由是个好功能,但是每次都感觉没法开始下手,愣愣的看半天官方文档,所以做个快速开始教程. 首先先搭好HTML文件结构: <!--link和view在一个父元素下--> <di ...

  3. Vue路由学习心得

    GoodBoy and GoodGirl~进来了就看完点个赞再离开,写了这么多也不容易的~ 一.介绍  1.概念:路由其实就是指向的意思,当我们点击home按钮时,页面中就要显示home的内容,点击l ...

  4. VUE路由新页面打开的方法总结

    平常做单页面的场景比较多,所以大部分的业务是在同一个页面进行跳转.要通过VUE路由使用新页面打开且传递参数,可以采用以下两个方法: 1.router-link的target <router-li ...

  5. vue路由参数变化刷新数据

    当路由到某个组件时,由于组件会复用,所以生命周期函数不会再次执行, 如果这个组件是模板组件,靠传入不同数据来显示的.那么,可能会发生参数变化了但页面数据却不变化. 问题 假如有个组件 info.vue ...

  6. 10.3 Vue 路由系统

     Vue 路由系统  简单示例 main.js  import Vue from 'vue' import App from './App.vue' //https://router.vuejs.or ...

  7. vue路由原理剖析

    单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面, 实现这一点主要是两种方式: 1.Hash: 通过改变hash值 2.History: 利用history对象新特性(详情可出门左拐见:  ...

  8. 3种vue路由传参的基本模式

    路由是连接各个页面的桥梁,而参数在其中扮演者异常重要的角色,在一定意义上,决定着两座桥梁是否能够连接成功. 在vue路由中,支持3中传参方式. 场景,点击父组件的li元素跳转到子组件中,并携带参数,便 ...

  9. 14.vue路由&脚手架

    一.vue路由:https://router.vuejs.org/zh/ 1.定义 let router = new VueRouter({ mode:"history/hash" ...

  10. react router @4 和 vue路由 详解(八)vue路由守卫

    完整版:https://www.cnblogs.com/yangyangxxb/p/10066650.html 13.vue路由守卫 a.beforeEach 全局守卫 (每个路由调用前都会触发,根据 ...

随机推荐

  1. php中self和$this还有parent的区别

    1.self代表类,$this代表对象 2.能用$this的地方一定使用self,能用self的地方不一定能用$this 3.parent只能调用静态属性,并且可以调用父类中公有和受保护的方法 静态的 ...

  2. <鸳鸯刀>&<白马啸西风>随笔

    这两部作品比较小众,也不如之前的作品优秀,因此简单写一下好了. <鸳鸯刀> 陕西西安府威信镖局的总镖头."铁鞭镇八方"周威信,带领一支七十多人的镖队正前往京城.路途之上 ...

  3. Typora --Markdown 文本工具

    标题: #+空+name  一级 ##+空+name  二级 ###+空+name  三级 ......------六级  (可排版折叠) 字体: 粗体:两边加** 斜体:两边加* 斜体加粗:*** ...

  4. 48. Rotate Image via java

    need to use scratch to find the pattern class Solution { public void rotate(int[][] matrix) { int n= ...

  5. 27 python 发送短信

    腾讯云短信服务,来进行发送短信. 注册账号 开通服务 + 缴费 (实名.企业认证,公众号) API服务.SDK服务 API,接口 import requests # 在此之前还会处理签名和加密的工作量 ...

  6. 半成品 java 身份证校验

    public static Boolean is18Card(String idCard18) { //证件省份 HashMap<String, String> aCity = new H ...

  7. js中宏任务,微任务,异步,同步,执行的顺序

     [微任务]包括:Promise ,    process.nextTick() *node.js里面的  [宏任务]包括:整体代码script,  setTimeout    setInterval ...

  8. python基础篇 26-redis操作

    redis的基本操作: redis_conf ={ 'host':'192.168.64.128', 'password':'Aa123456', 'db':'0', 'port':6379, 'de ...

  9. Sharp7与S7NetPlus 性能测试

    介绍 ​ Sharp7和都S7NetPlus是纯C#实现的基于以太网与S7系列的西门子PLC通讯的开源库.都支持.net core 跨平台可以部署在linxu, docker,windwos 中. 测 ...

  10. C# 自定义组元扩展类(Tuple)

    组元Tuple没有构造函数,自定义一个有构造函数的组元TupleEx. namespace TupleEx { public class TupleEx<T1> { /// <sum ...