目录
路由
路由的分类
后端路由
前端路由
vue中路由的使用
引入路由文件以及vue文件
创建路由对象:
路由案例
vue-router
前言
单页面应用与多页面应用
vue-router的使用
路由静态加载与懒加载
带参数的路由匹配
路由正则
路由嵌套
路由嵌套架构版
路由嵌套项目版
编程式导航
普通形式
通过名字进行跳转并携带参数
替换当前位置
路由表
方式一
方式二
命名路由
命名视图(厉害)
路由重定向
通过路径进行重定向
通过路由名进行重定向
函数进行重定向
别名路径访问
统一测试
路由组件传参
普通情况
命名视图下的路由组件传参
路由的模式
Hash模式
HTML5模式
路由导航守卫
全局前置守卫
局部路由守卫
组件内的路由导航守卫
含义:一个路由就是一组映射关系(key-value)
理解:key为路径,value可能是function或component
注意:引入时需要注意顺序,路由是基于vue存在的
const luyou = new VueRouter({
routes:[
{path:"/t",component:home},
{path:"/n",component:help}
]
})
属性routes:路由规则集(路由表),内部为一个路由规则数组
点我显示主页
点我显示帮助
注意:
单页面应用 | 多页面应用 | |
组成 | 一个外壳页面和多个页面片段组成 | 多个完整页面构成 |
资源共用 | 共有,只需要在外壳部分加载 | 不共用,每个页面都需要加载 |
刷新方式 | 页面局部刷新或更改 | 整页刷新 |
用户体验 | 页面片段间的切换快,用户体验良好 | 页面切换加载缓慢,流畅度不够,用户体验比较差 |
转场动画 | 容易实现 | 无法实现 |
数据传递 | 容易 | 依赖url传参、或者cookie、localStorage等 |
在vue中引入路由
安装路由:npm install --save vue-router
配置独立的路由文件
在src文件下新建一个文件夹router里面建一个index.js文件作为路由的配置文件
// 路由配置文件index.js
//引入路由
import {createRouter,createWebHashHistory} from "vue-router"
//引入组件
import Home from '../components/Home.vue'
//配置路由规则(路由表)
const routes=[
{path:"/",component:Home},
//异步加载方式:如果页面没有被显示出来component后面的代码是不会执行的,不会执行的话就节省了内存空间(路由懒加载)
{path:"/about",component:()=>import('../components/About.vue')}
]
// 创建路由器
const router=createRouter({
history:createWebHashHistory(),
routes
})
//导出路由器
export default router
//main.js文件内
import { createApp } from 'vue'
import App from './App.vue'
//引入路由
import router from './router/index.js'
const app=createApp(App)
//注册全局路由
app.use(router).mount('#app')
home页面 |
about页面
懒加载:用到时才会加载对应的组件,这样可以使项目的运行变得高效
//静态导入
import Home from "../components/Home.vue"
//动态导入
const About=()=>import("../components/About.vue")
const routes=[
//静态加载
{path:"/",component:Home},
//路由懒加载
{path:"/about",component:About},
]
前言:路由是管理页面之间的跳转关系的,在跳转的过程中,页面与页面之间也需要传递参数
最终效果:随着路由传递的参数改变,导致同一组件内容的改变
const routes=[
//路由传递参数,用:name作为占位符
{path:"/about/:name",component:()=>import('../components/About.vue')},
]
网易页面
京东页面
{{$route.params.name}}
const routes = [
//路由正则(传递的name参数必须为数字)
{ path: "/about/:name(\\d+)", component: () => import('../components/About.vue') },
//正则匹配about页面,表示后面的参数可以有多个(+表示一个或多个;*表示0个或多个;?表示一个或多个)
{ path: "/about/:name+", component: () => import('../components/About.vue') },
//正则匹配,若找不到以上对应的路由则走该路由
{ path: "/:path(.*)", component: () => import('../components/Error.vue') },
]
网易页面
666页面
多参数页面
找不到页面
{{$route.params.name}}
404
前言:一个程序的ui是由多个嵌套组件组成,在这种情况下,url的片段通常对应于特定的嵌套组件结构,通过路由嵌套可以表达这种组件的嵌套关系
home
help
我是home组件
help1
help2
我是help1组件
我是help2组件
注意:路由里面的children属性为子路由,里面为路由规则数组
理解过程:
访问“/”路径就重定向到“/t”路径,所以在你访问的时候主页面默认就是home组件,结果你点击了help组件,由于其存在子路由,并且我默认在里面设置了重定向到help1组件,所以,当你点击help组件时会默认看到help1组件,点击了help2组件跳到help2,其他的以此类推
const routes=[
{path:"/",component:()=>import("../components/Home")},
{path:"/about",component:()=>import("../components/About"),
redirect:"/about/second",//路由重定向
children:[
//注意:子路由路径前面不带/,因为自动帮你识别了
{path:"first",component:()=>import("../components/First")},
{path:"second",component:()=>import("../components/Second")}
]
}
]
home |
about
About
first |
second
注意:$router是一个全局路由容器,里面包含着许多路由对象,$route是$router容器中活跃的那个路由对象
跳转到特定的组件:this.$router.push("/about")
前进一步:
- this.$router.forward()
- this.$router.go(1)
后退一步:
- this.$router.back()
- this.$router.go(-1)
刷新页面:this.$router.go(0)
注意:go方法内的参数为前进或后退的步数
home
const routes=[
{path:"/about",component:()=>import('../components/About.vue')},
//路由传递参数,用:name作为占位符
{name:"about",path:"/about/:name",component:()=>import('../components/About.vue')},
]
about
{{$route.params.name}}
{{$route.query.app}}
前言:他的作用类似于router-push,唯一不同的是,它在导航时不会向history添加新纪录,正如他的名字所暗示的那样,它仅仅是取代了当前的页面
const routes=[
{path:"/",component:()=>import('../components/Home.vue')},
{path:"/about",component:()=>import('../components/About.vue')},
]
home
about
const routes=[
{path:"/",component:()=>import('../components/Home.vue')},
{name:"about",path:"/about/:name",component:()=>import('../components/About.vue')},
]
about
about
{{$route.params.name}}
场景:我们想要同时展示多个视图,这时候命名视图就派上用场了,可以在页面上拥有多个单独命名的视图,而不是一个单独的出口,若route-view没有名字,那么默认为default(一个视图使用一个组件渲染,因此多个视图就用多个组件渲染)
const routes=[
{path:"/num",
components:{
//default代表当访问该num路径对应的路由的话,那么就默认跳到First组件
default:()=>import("../components/First.vue"),
Second:()=>import("../components/Second.vue"),
Third:()=>import("../components/Third.vue")
}}
]
数字集
const routes=[
//路由重定向
{path:"/",redirect:"/home"},
{path:"/home",component:()=>import("../components/Home.vue")}
]
const routes=[
//通过路由名进行重定向
{path:"/",redirect:{name:"home"}},
{name:"home",path:"/home",component:()=>import("../components/Home.vue")}
]
const routes=[
//通过路由名进行重定向
{path:"/",redirect:(to)=>{
//to表示当前路径,里面可以用to进行一些判断
console.log(to);
return{path:"/home"}
}},
{path:"/home",component:()=>import("../components/Home.vue")}
]
注意:此别名路径不仅能用于重定向,也可以直接访问
const routes=[
//通过路由名进行重定向
{path:"/",redirect:"/building"},
//为该路由起小名为/building
{alias:"/building",path:"/home",component:()=>import("../components/Home.vue")}
]
开始页面
前言:通常情况下在组件中使用$route会与路由紧密耦合,这就限制了组件的灵活性,因为他只能用于特定的url,但是我们也可以通过props配置来解除这种行为
注意:当props设置为true的时候,那么$route.params将被设置为组件的props
const routes=[
//路由组件传参
{path:"/home/:app",component:()=>import("../components/Home.vue"),props:true}
]
{{$route.params.app}}
{{app}}
路由组件传参
const routes=[
//路由组件传参
{path:"/num/:app",components:{
default:()=>import("../components/First.vue"),
Second:()=>import("../components/Second.vue"),
Third:()=>import("../components/Third.vue")
},
//让默认的为true进而开启路由组件传参
props:{default:true,Second:false,Third:false}}
]
first内
{{app}}
路由组件传参
我们常用的模式
const router = createRouter({
//哈希模式,通过createWebHashHistory()创建的
history: createWebHashHistory(),
routes
})
注意:
const router = createRouter({
//HTML5模式,通过createWebHistory()创建的
history: createWebHistory(),
routes
})
注意:使用这种历史模式时,url看起来会很正常(没有#号),但是由于我们的应用是一个单页的客户端应用,没有适当的服务器配置,容易报404错误
Hash模式与HTML5模式的主要区别:有无哈希符号#
含义:路由导航守卫主要是用来通过跳转或取消的方式守卫导航
理解:就是实际中不可能让你想走那个页面就走那个页面,必须通过判断来决定你可不可以走该页面
说明:beforeEach用户的每次请求在访问目标网址之前都会被拦截
注意:该全局路由守卫放到全局路由对象中使用
参数:
用法:
路由对象.beforeEach((to, from, next) => {
if(条件判断){
return next()
}
})
注意:如果返回值给next()则表示此路由可以放行,当然如果next(false)就会放行失败
//路由导航守卫
//调用路由实例里面的BeforeEach方法
router.beforeEach((to,from,next)=>{
//若去往路径为/则直接放行
if(to.fullPath=="/"){
//请求放行
return next();
}else{
console.log(to);
console.log(from);
alert("请先登录")
}
})
const routes=[
{path:"/",component:()=>import("../components/Home.vue")},
{path:"/about",component:()=>import("../components/About.vue"),
//局部路由组件(在进入about组件之前进行判断)
beforeEnter: (to, from, next) => {
//若请求从/来则放行
if(from.fullPath=="/"){
next()
}
}},
]
home