目录
vue中的一个插件库,专门用来实现SPA应用;
①、单页面Web应用(single page web application,SPA);
②、整个应用只有一个完整的页面;
③、点击页面的导航链接不会刷新页面,只会进行页面的局部刷新;
④、数据需要通过ajax请求获取;
一个路由就是一组映射关系(key - value),key为路径,value可能是function或components;
后端路由:
①、value为function,用于处理客户端提交的请求;
②、工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据;
前端路由:
①、理解value是components,用于展示页面内容;
②、工作过程:当浏览器的路径改变时,对应的组件就会展示;
命令:npm i vue-router(这个是适用于vue3版本,如果是想使用适用于vue2版本的话,就需要使用npm i vue-router@3命令行)
Vue.use(VueRouter)
新建router/index.js文件
- // 该文件专门用于创建整个应用的路由器
- import VueRouter from 'vue-router'
-
- // 引入组件(路由组件一般放在pages文件夹)
- import About from '../pages/About'
- import Home from '../pages/Home'
-
- // 创建并暴露一个路由器
- export default new VueRouter({
- routes:[
- {
- path:'/about',
- component:About
- },
- {
- path:'/home',
- component:Home
- }
- ]
- })
- <router-link class="list-group-item" active-class="active" to="about">Aboutrouter-link>
- <router-link class="list-group-item" active-class="active" to="home">Homerouter-link>
- <router-view>router-view>
1、路由组件通常放在pages文件夹,而一般组件通常存放在conponents文件夹;
2、切换不同的路由组件时,隐藏的路由组件本质上默认是被销毁了,需要的时候再重新挂载;
3、每个组件之间共用一个router,可以通过组件的$router属性获取;
4、每个组件都有自己的$route属性,里面存储着自己的路由信息;
1、配置路由规则:使用children配置项:
router/index.js
- routes:[
- // 一级路由
- {
- path:'/about',
- component:About
- },
- {
- path:'/home',
- component:Home,
- // 二级路由
- children:[
- {
- path:'news',
- component:News
- },
- {
- path:'message',
- component:Message
- }
- ]
- }
- ]
2、跳转:要写完整路径
<router-link to="/home/message">Messagerouter-link>
字符串写法和对象写法
- <router-link :to="`/home/message/detail?id=${mes.id}&title=${mes.title}`">{{mes.title}}router-link>
-
- <router-link :to="{
- path:'/home/message/detail',
- query:{
- id:mes.id,
- title:mes.title
- }
- }">
- {{mes.title}}
- router-link>
- <ul>
- <li>消息编号:{{$route.query.id}}li>
- <li>消息标题:{{$route.query.title}}li>
- ul>
申明接收使用params参数
- // 创建并暴露一个路由器
- export default new VueRouter({
- routes:[
- // 一级路由
- {
- // 命名路由
- name:'guanyu',
- path:'/about',
- component:About
- },
- {
- path:'/home',
- component:Home,
- // 二级路由
- children:[
- {
- path:'news',
- component:News
- },
- {
- path:'message',
- component:Message,
- children:[
- {
- // 使用占位符:id和:title申明接收params参数
- name:'xiangqing',
- path:'detail/:id/:title',
- component:Detail
- }
- ]
- }
- ]
- }
- ]
- })
- <li v-for="mes in messageList" :key="mes.id">
-
- <router-link :to="`/home/message/detail/${mes.id}/${mes.title}`">{{mes.title}}router-link>
-
-
- <router-link :to="{
- // path:'/home/message/detail',
- // 命名路由通过名字name定位,不需要使用path
- name:'xiangqing',
- params:{
- id:mes.id,
- title:mes.title
- }
- }">
- {{mes.title}}
- router-link>
- li>
路由携带使用params传递参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置项!
- <ul>
- <li>消息编号:{{$route.params.id}}li>
- <li>消息标题:{{$route.params.title}}li>
- ul>
作用:可以简化路由的跳转中路径的编写,通过name属性直接定位到所要跳转的路由;
1、给路由命名:
- routes:[
- // 一级路由
- {
- // 命名路由
- name:'guanyu',
- path:'/about',
- component:About
- // 二级路由
- children:[
- {
- path:'message',
- component:Message,
- children:[
- {
- // 三级路由
- // 命名路由,可以方便直接找到路径
- name:'xiangqing',
- path:'detail',
- component:Detail
- }
- ]
- }
- ]
- }
- ]
2、简化跳转
- <router-link :to="{name:'guanyu'}">Aboutrouter-link>
- <router-link :to="{
- path:'/home/message/detail',
- query:{
- id:mes.id,
- title:mes.title
- }
- }">
- {{mes.title}}
- router-link>
-
-
- <router-link :to="{
- name:'xiangqing',
- query:{
- id:mes.id,
- title:mes.title
- }
- }">
- {{mes.title}}
- router-link>
作用:能够让路由更加方便的接收到参数
- {
- // 命名路由,可以方便直接找到路径
- name:'xiangqing',
- path:'detail/:id/:title',
- component:Detail,
-
- // 路由中的props配置项的第一种写法:对象写法,该对象中的所有key、value都会以props的形式传给Detail组件
- props:{
- a:1,
- b:'hello'
- }
-
- // 路由中的props配置项的第二种写法:值为布尔值,若布尔值为真,就会把该组件用到的所有params参数,以props的形式传给Detail组件
- props:true
-
- // 第三种写法:值为函数,接收route参数
- props($route){
- return {id:$route.params.id,title:$route.params.title}
- }
- // 简写
- props({params}){
- return {id:params.id,title:params.title}
- }
- }
作用:控制路由跳转时,操作浏览器历史记录模式为替换模式;
浏览器的历史记录有两种写入方式:分别为push和replace,push是追加模式,可回退;replace是替换模式,不可回退,路由跳转默认为push;
- <router-link :replace="true" to="about">Aboutrouter-link>
- <router-link replace to="about">Aboutrouter-link>
作用:不借助
在函数中使用this.$router.push能够实现路由跳转功能,并且能够进行回退操作;
<button @click="pushShow(mes)">push查看button>
- methods:{
- pushShow(mes){
- this.$router.push({
- name:'xiangqing',
- params:{
- id:mes.id,
- title:mes.title
- }
- })
- }
- // ...
- }
在函数中使用this.$router.replace能够实现路由跳转功能,不能进行回退操作;
<button @click="replaceShow(mes)">replace查看button>
- methods:{
- replaceShow(mes){
- this.$router.replace({
- name:'xiangqing',
- params:{
- id:mes.id,
- title:mes.title
- }
- })
- }
- // ...
- }
back:实现路由的回退操作,不接收参数;
forward:实现路由的前进操作,不接受参数;
go:实现路由的跳转操作,接收一个参数,正数表示前进,负数表示回退;
- <button @click="back">前进button>
- <button @click="forward">后退button>
- <button @click="text">测试一下gobutton>
- methods:{
- back(){
- // 实现路由的回退
- this.$router.back();
- },
- forward(){
- // 实现路由的前进
- this.$router.forward();
- },
- text(){
- // 参数为正数时,实现路由的前进
- this.$router.go(1);
- // 参数为负数时,实现路由的后退
- this.$router.go(-1);
- }
- }
activated()和deactivated()用于捕获路由的激活状态,当页面展示的时候激活,当页面切走的时候失活;
<li :style="{opacity}">欢迎学习Vueli>
- export default {
- name:'News',
- data(){
- return{
- opacity:1
- }
- },
-
- // 两个路由独有的生命周期钩子
- // 激活
- activated(){
- console.log('News路由被激活了')
- this.timer = setInterval(()=>{
- this.opacity -= 0.01
- if(this.opacity <= 0) this.opacity = 1
- },16)
- },
- // 失活
- deactivated(){
- console.log('News路由失活了')
- clearInterval(this.timer)
- }
- }
作用:
全局前置路由守卫————初始化的时候被调用、每次切换路由的时候被调用;
先使用一个变量获取到路由器router,在暴露之前先调用beforeEach函数,通过判断将不符合条件的路由拦截,使其不能跳转;
beforeEach函数接收三个参数:to、from、next,分别表示:去往的路由、来自哪个路由、确定前往;
三种获取拦截路由的方法:
①、path路径
if(to.path === '/home/news' || to.path === '/home/message')
②、name名称
if(to.name === 'news' || to.name === 'message')
③、meta属性添加配置项
if(to.meta.isAuth)
router/index.js
- // 创建并暴露一个路由器
- const router = new VueRouter({
- routes:[
- {
- path:'/home',
- component:Home,
- children:[
- {
- name:'news',
- path:'news',
- component:News,
- meta:{isAuth:true}
- },
- {
- name:'message',
- path:'message',
- component:Message,
- meta:{isAuth:true}
- }
- ]
- }
- ]
- })
-
- // 全局前置路由守卫————初始化的时候被调用、每次切换路由的时候被调用
- // 接受三个参数:to、from、next,分别表示:去往的路由、来自哪个路由、确定前往
-
- router.beforeEach((to,from,next)=>{
- // 判断是否是需要拦截的路由
-
- //path形式
- //if(to.path === '/home/news' || to.path === '/home/message'){
-
- //name形式
- // if(to.name === 'news' || to.name === 'message'){
-
- //添加meta属性形式
- if(to.meta.isAuth){
- // 判断是否符合条件:学校名是否符合
- if(localStorage.getItem('school') === 'atguigu'){
- next();
- }else{
- alert('学校名不是atguigu,无权限访问!')
- }
- }else{
- // 使用next实现前往下一个路由
- next()
- }
-
- })
-
- export default router
作用:
全局后置路由守卫————初始化的时候被调用、每次切换路由的时候被调用;
afterEach函数接收两个参数:to、from,分别表示:去往的路由、来自哪个路由;
- // 全局后置路由守卫————初始化的时候被调用、每次切换路由的时候被调用
- // 接受两个参数:to、from,分别表示:去往的路由、来自哪个路由
- router.afterEach((to,from)=>{
- // 在后置路由守卫中,就不需要写那么多判断,当执行到后置路由守卫,就表示路由一定切换
- document.title = to.meta.title || '尚硅谷系统'
- })
写在每一个路由内部,使用beforeEnter配置项,只有前置守卫,没有后置守卫;
- // 创建并暴露一个路由器
- const router = new VueRouter({
- routes:[
- {
- name:'news',
- path:'news',
- component:News,
- // meta属性是路由提供给程序员的一个容器,能够存放程序员需要添加的内容
- meta:{isAuth:true,title:'新闻'},
- beforeEnter:(to,from)=>{
- if(to.meta.isAuth){
- if(localStorage.getItem('school') === 'atguigu'){
- // 实现在路由跳转之前替换页面标题
- document.title = to.meta.title || '尚硅谷系统'
- next();
- }else{
- alert('学校名不是atguigu,无权限访问!')
- }
- }else{
- document.title = to.meta.title || '尚硅谷系统'
- // 使用next实现前往下一个路由
- next()
- }
- }
- },
- // ...
- ]
- })
①、通过路由规则,进入该组件时调用beforeRouteEnter,接收三个参数:to、from、next;
- beforeRouteEnter(to,from,next){
- console.log('About--beforeRouteEnter')
- if(to.meta.isAuth){
- if(localStorage.getItem('school') === 'atguigu'){
- next();
- }else{
- alert('学校名不是atguigu,无权限访问!')
- }
- }else{
- // 使用next实现前往下一个路由
- next()
- }
- }
②、通过路由规则,离开该组件时调用beforeRouteLeave,同样接收三个参数:to、from、next;
- beforeRouteLeave(to,from,next){
- console.log('About--beforeRouteLeave')
- next();
- }
用法:在router/index.js文件中,创建路由的时候通过mode属性进行定义,默认为hash;
- const router = new VueRouter({
- mode:'hash',
- // ...
- })
①、地址中不存在#,干净美观;
②、兼容性与hash模式相比相对较差;
③、应用部署上线时,需要后端人员的支持,解决刷新页面服务端404问题;
①、地址永远带着#,不美观;
②、若以后将地址通过第三方手机app分享时,app检验严格,则地址带有#会被标记为不合法;
③、兼容性好;
1、使用
- <keep-alive include="News">
- <router-view>router-view>
- keep-alive>
缓存多个写成数组形式:
- <keep-alive :include="['News','Message']">
- <router-view>router-view>
- keep-alive>
注意:是在父路由的展示区为子路由设置