路由! 本节可能有点长,你忍一下
-后端路由:后端路由指的是:请求方式、请求地址与function处理函数之间的对应关系。
const express = require('express')
const router=express.Router()
router.get('/userlist',function(req,res)){/* 路由的处理函数 */}
router.post('/userlist',function(req,res)){/* 路由的处理函数 */}
module.exports=router
-SPA与前端路由
SPA指的是一个web网站只有唯一的一个HTML页面,所有组件的展示与切换都在这唯一的一个页面内完成。此时,不同组件之间的切换需要通过前端路由来实现。
-前端路由
通俗易懂的概念:Hash地址与组件之间的对应关系。
前端路由工作方式
-
用户点击了页面上的路由链接
-
导致了URL地址栏中的Hash 值发生了变化
-
前端路由监听了到Hash地址的变化
-
前端路由把当前Hash地址对应的组件渲染都浏览器中
<template> <div> <h1>App 组件</h1> <a href="#/home">Home</a> <a href="#/movie">Movie</a> <a href="#/about">About</a> <hr /> <component :is="comName"></component> </div> </template> <script> import MyHome from "./MyHome.vue"; import MyMovie from "./MyMovie.vue"; import MyAbout from "./MyAbout.vue"; export default { name: "MyApp", 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; } }; }, component: { MyHome, MyMovie, MyAbout, }, }; </script>
vue-router
vue-router 是vue.js 官方给出的路由解决方案。它只能结合vue项目进行使用,能够轻松的管理SPA项目中组件的切换。
- vue-router目前有3.x的版本和4.x的版本。其中:
- vue-router 3.x只能结合vue2进行使用
- vue-router 4.x只能结合vue3进行使用
vue-router 4.x 的基本使用步骤:
1.在项目中安装 vue-router npm install vue-router@next -S
2.定义路由组件
3.声明路由链接和占位符 可以使用<router-link>标签来声明路由链接,
并使用<router-view>标签来声明路由占位符。
<template>
<div>
<h1>vue-router的基本使用</h1>
<!-- 生命路由链接 -->
<router-link to="/home">首页</router-link>
<router-link to="/movie">电影</router-link>
<router-link to="/about">关于</router-link>
<!-- 路由的占位符 -->
<router-view></router-view>
</div>
</template>
4.创建路由模块 创建router.js路由模块
-
4.1)从 vue-router中按需导入两个方法
-
4.2)导入需要使用路由控制的组件
-
4.3)创建路由实例对象
-
4.4)向外共享路由实例对象
import { createRouter, createWebHashHistory } from 'router-vue' //createRouter:用于创建路由的实例对象 // createWebHashHistory: 用于指定路由的工作模式(hash模式) import Home from './MyHome.vue' import Movie from './MyMovie.vue' import About from './MyAbout.vue' const router=createRouter({ history:createWebHashHistory(), routes:[ { path:'/home',component:Home }, { path:'/movie',component:Movie }, { path:'/home',component:About }, ] }) export default router5.导入并挂载路由模块 在main.js中导入并挂载路由模块
路由高级用法
路由重定向指的是:用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件页面。
通过路由规则的 redirect属性,指定一个新的路由地址,可以很方便地设置路由的重定向
routes:[
{ path:'/', redirect: '/home' },
{ path:'/home',component:Home },
{ path:'/movie',component:Movie },
{ path:'/home',component:About },
]
被激活的路由链接,默认会应用一个叫做 router-link-active 的类名。开发者可以使用此类名选择器,为激活的路由链接设詈高亮的样式:
.router-link-active {
background-color:blue;
color:white;
font-weight:bold;
}
也可以通过:linkActiveClass:'自定义高亮类名'
嵌套路由
通过路由实现组件的嵌套展示,叫做嵌套路由。
声明子路由链接和子路由占位符
<template>
<div>
<h1>MyAbout 子组件</h1>
<!-- 生命子路由链接 -->
<router-link to="/about/tabOne">tabOne</router-link>
<router-link to="/about/tabTo">tabTo</router-link>
<!-- 路由的占位符 -->
<router-view></router-view>
</div>
</template>
在父路由规则中,通过 children 属性嵌套声明子路由规则
在router.js路由模块中,导入需要的组件,并使用 children 属性声明子路由规则。
import TabOne from './tabs/MyTabOne.vue'
import TabTo from './tabs/MyTabTo.vue'
const router=createRouter({
history:createWebHashHistory(),
routes:[
{ path:'/home',component:Home },
{ path:'/movie',component:Movie },
{ path:'/about',
component:About,
redirect:'/about/tabOne',
children:[
{path:'tabOne',component:TabOne},
{path:'tabTo',component:MyTabTo},
] },
]
})
export default router
redirect:'/about/tabOne' 重定向子路由
动态路由匹配
动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。在vue-router 中使用英文的冒号( : )来定义路由的参数项。
//路由中的动态参数:进行声明,冒号后面的动态参数的名称
{ path:'/movie/:id',component:Movie },
通过动态路由匹配的方式渲染出来的组件中,可以使用 $route.params 对象访问到动态匹配的参数值。为了简化路由参数的获取形式,vue-router 允许在路由规则中开启 props传参。
{ path:'/movie/:id', component:Movie , props:true },
export default{
props:[ 'id']
}
通过调用API实现导航的方式,叫做编程式导航。与之对应的,通过点击链接实现导航的方式,叫做声明式导航。
- 普通网页中点击
<a>链接、vue 项目中点击<router-link>都属于声明式导航 - 普通网页中调用
location.href跳转到新页面的方式,属于编程式导航
vue-router提供了许多编程式导航的API,其中最常用的两个API分别是:
this.$router.push('hash地址') //跳转到指定Hash地址,从而展示对应的组件
this.$router.go(数值n) //实现导航历史的前进、后退(n为1 表示前进 为-1 表示后退)
为<router-link>标签动态绑定 to 属性的值,并通过 name 属性指定要跳转到的路由规则。期间还可以用params 属性指定跳转期间要携带的路由参数。
<router-link to =" {name:'mov' ,params:{ id:4 } ">go to movie</router-link>
{ name:'mov',path:'/movie',component:Movie },
调用push 函数期间指定一个配置对象,name是要跳转到的路由规则、params是携带的路由参数:
this.$router.push( {name:'mov',params:{ id:3 }} )
导航守卫
可以控制路由的访问权限
全局导航守卫会拦截每个路由规则,从而对每个路由进行访问权限的控制。 可以按照如下的方式定义全局导航守卫:
const router=createRouter({...})
//调用路由实例对象的beforeEach函数,声明全局前置守卫
//fn 必须是一个函数,每次拦截到路由的请求,都会调用fn进行处理
//因此fn叫做‘守卫方法’
router.beforeEach(fn) // fn回调函数
全局导航守卫的守卫方法中接收3个形参:
router.beforeEach((to,from,next)=>{
// to 目标路由对象
//from 当前导航正要离开的路由对象
//next 是一个函数,表示放行 不声明表示默认每个路由都可以访问
})
- 直接放行:next()
- 强制其停留在当前页面:next(false)
- 强制其跳转到登录页面:next(' /login')