vue-router的学习

vue-router

基于Vue做单页面应用时,vue-router可以帮我们将url地址和组件绑定,在我们切换路由组件时,url改变,页面无需从服务端重新加载,即不用刷新,打个比方,我们用美团外卖点外卖时,切换点击左边的菜品标签,若页面总是重新加载,每次重新加载整个页面都闪烁一下,用户的体验很不好。

1. 基本使用

1.1 安装 vue-router:

使用vue2安装对应的router3版本

npm i vue-router@3

使用vue3安装对应的router4版本

npm i vue-router@4

1.2 引入router

在 src 下创建router文件夹,在router文件夹里创建 index.js

/src/router/index.js

js' 复制代码
//引入Vuerouter
import VueRouter from 'vue-router'
//引入想要展示的路由组件
const router = new VueRouter({
  	routes:[
        {
            path: '/xxx',//url
            component: [路由组件名],//对应的组件名
        },
    ]  
})
export default router

在 main.js 文件中引入并注册路由

main.js

vue 复制代码
import Vue from 'vue'
import App from './App.vue'
//1. 引入
import VueRouter from 'vue-router'
import router from './router'
Vue.use(VueRouter)

new Vue({
  render: h => h(App),
  //2. 注册
  router
}).$mount('#app')

1.3 使用router

一般在/src/pages下存放路由组件,在/src/components下存放其他组件

1.3.1 路由导航 <router-link>

<router-link> 用来导航显示想展示的组件,本质上就是个超链接标签<a>,有如下属性

:to="/xxx" --> 去展示对应url对应的组件

active-class="[class名]" --> 当导航被激活时想展示的class样式

replace --> 切换路由时替换当前浏览器的历史记录

push --> 默认为push,再切换路由时追加浏览器历史记录

1.3.2 路由组件展示<router-view>

<router-view>用于把选择了<router-link>对应的组件展示到<router-view>放置的位置

1.4 简单的路由例子

下方的例子就是一个简单的路由,如果导航被激活,就会显示如图的红色,并在下方展示子组件数据

App.vue

<template>
  <div id="app">
    <ul>
        <li v-for="(item,index) in list" 
            :key="item.id">
        <router-link 
            active-class="router-active" 
            :to="item.path">
        {{ item.name }
        </router-link>
         </li>
    </ul>
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
        list: [
          { id: 2, name: '人员', path: '/persons'},
          { id: 3, name: '新闻', path: '/news' }
        ],
    }
  }
}
</script>

<style scoped>
    * {
      margin: 0;
      padding: 0;
    }
    #app ul {
      display: flex;
      padding: 0 10px;
    }
    #app ul li {
      width: 100px;
      height: 50px;
      line-height: 50px;
      list-style: none;
      text-align: center;
      border: 1px solid black;
    }
    #app ul li a {
      display: block;
      text-decoration: none;
      font-weight: bold;
      color: #333333;
    }
     .router-active{
      background-color: #e01222;
      color: #fff;
     }
</style>

/router/index.js

import VueRouter from "vue-router"
//引入想要用的组件
import PersonList from "@/pages/PersonList.vue"
import News from "@/pages/News.vue"
const router = new VueRouter({
    routes: [
        {
            path: '/persons',
            component: PersonList
        },
        {
            path: '/news',
            component: News
        }
        
    ]
})
export default router

/pages/News.vue

<template>
    <div>
        <h3>新闻列表</h3>
        <li v-for="item in NewsList" :key="item.id">
            {{item.title}}
        </li>
    </div>
</template>

<script>
    
    export default{		
        name: '',
        data(){
            return{
                NewsList: [
                    {id:'001',title:'新闻1', path: '/new'},
                    {id:'002',title:'新闻2', path: '/new'},
                    {id:'003',title:'新闻3', path: '/new'},
                ]
            }
        },
    }
</script>

/pages/PersonList.vue

<template>
    <div>
        <ul>
            <li v-for="(item) in personList" :key="item.id">
                {{item.id}} - {{ item.pName }} - {{ item.age }}
            </li>
        </ul>
    </div>
</template>

<script>
    export default{		
        name: '',
        data(){
            return{
                personList : [
                    {id:'001',pName:'tom',age:18},
                    {id:'002',pName:'jerry',age:19},
                    {id:'003',pName:'tony',age:12},
                ],
            }
        }
    }
</script>

2. 进阶使用

2.1 多级路由

多级路由是在/router/index.js中routes中的对象中配置children属性,在children里配置下一级路由的映射规则

import VueRouter from "vue-router"
const router = new VueRouter({
    routes: [
        {
            path: '/xxx',
            component: xxx,
            //多级路由配置children属性
            children: [
                {
                    path: 'yy',//记住不要加/ 
                    component: yy
                }
            ]
        }
    ]
})
export default router

此时我们访问到配置的这个子路由的<router-link>的 :to 属性应该写完整的路径,即

<router-link :to="/xxx/yy"></router-link>

2.2 $router 和 $route

route存放着该组件的路由信息,每个路由组件对象都有route,可以传递接参数等等

router是vue路由对象,只会存在一个,可以借助this.router的api实现编程式路由导航

2.3 路由传参

传参有query传参和param传参两种方式,我们通过在路由组件里的 this.$route.[query / param]获取

二者的字符串写法都支持模板字符串,模版字符串用``围起来,里面可以通过 ${变量名} 获取变量,拼接成字符串

2.3.1 query传参

传递参数都是在<router-link>的 to 属性传递,传递方式有字符串写法和对象写法,获取则是通过 this.$route.query.[变量名]

//1.字符串写法
//传递:在<router-link>的to属性通过url传递,即 
			to="/xx?a=a&b=b"
//2. 对象写法
// to="
{
	path: '/xx',
	query:{
		a:a,
		b:b
	}
}
"
2.3.2 params传参

传递参数都是在<router-link>的 to 属性传递,传递方式有字符串写法和对象写法,获取则是通过 this.$route.params.[变量名]

//1. 字符串写法
to="/xx/a/b"
//这种写法需要在route里匹配路径时占位
// /router/index.js

const router = new VueRouter({
    routes: [
        {
            path: '/xx/:school', // [/:变量名] 实现占位,传多少个参数就占多少位
            component: PersonList
        }    
    ]
})

//2. 对象写法
//这种写法需要配置route的name属性,见文章2.4 路由取名
// 配置 name 和 params
to="{
    name: [路由name属性名,即aa],
    params: {
        a : a,
        b : b
    }
}"

// /router/index.js
// 注意 name、path
const router = new VueRouter({
    routes: [
        {
        	name: 'aa'
            path: 'xx/:a', //占位
            component: PersonList
        }    
    ]
})

2.4 路由取名

我们可以给路由取名,通过 to="[路由名]" 即可访问

const router = {
    routes: [
        {
        	//取名
        	name: 'aaa',
            path: '/xxx',
            component: xxx,
            //多级路由配置children属性
            children: [
                {
                    path: 'yy',//记住不要加/ 
                    component: yy
                }
            ]
        }
    ]
}

//访问
<router-link :to="aaa"></router-link>

2.5 缓存路由

我们在切换同级路由时,切换走的路由组件会被销毁,切换到的路由组件会被创建,有时候我们希望切换组件时,保留该组件现有的数据,即不销毁掉该路由组件,这就是缓存路由

缓存路由通过<keep-alive>标签的include属性控制,如果想缓存多个路由,则用 :include="['a组件', 'b组件']",需要在组件里配置name属性,若没配置include则所有都缓存

vue 复制代码
<keep-alive :include="['xx']">
    <router-view></router-view>
</keep-alive>

2.6 路由组件的生命周期函数

引入: 一个路由组件有定时器,并且keep-alive 了,我们不希望定时器在切换的时候依旧执行

解决上述问题,我们可以通过路由组件的activated、deactivated 两个生命周期函数,在路由组件激活时开始,路由切换时关闭即可,这两个生命周期函数仅在<keep-alive>包含当前组件时才会有

activated 路由组件被激活时激活

deactivated 路由组件被切换的时候激活

2.7 路由守卫

引入 : 有些路由组件需要判断权限,没权限就不给看

2.7.1 全局前置路由守卫

配置在 /router/index.js 里,路由组件的初始化和每次切换时调用

一般用于权限控制

/router/index.js

js 复制代码
// to : 目标路由
// from : 从哪个路由切换的,是一个Object对象
// next	: 要切换到哪个路由,是一个Object对象
router.beforeEach((to, from, next) -> {
	//权限验证
	next(); //放行
})
2.7.2 全局后置路由守卫

配置在 /router/index.js 里,路由组件的初始化和每次切换后调用

/router/index.js

js 复制代码
// to : 目标路由,是一个Object对象
// from : 从哪个路由切换的,是一个Object对象
//由于是在路由器切换后调用的,所以不需要 next
router.afterEach((to, from) -> {
    
})
2.7.3 独享前置路由守卫

只有前置,没有后置,配置在 /router/index.js 里,存在该独享前置路由守卫的路由组件被激活时触发

/router/index.js

js 复制代码
routes = new VueRouter({
{
    path: '/xx',
    beforeEnter:(to, from, next) => {
    	
    	next();//放行
    }
})
2.7.4 组件内路由守卫

配置在路由组件里

beforeRouteEnter() 在切换到该路由组件时调用

beforeRouteLeave() 在离开该路由组件时前调用

//通过路由规则进入时调用
beforeRouteEnter(to, from, next) {
	
	next(); //放行
}
//通过路由规则离开前调用
beforeRouteLeave(to, from, next) {

	next(); //放行
}
2.7.5 路由守卫的执行顺序

如果各种守卫都配置了,

路由组件初始化时,触发顺序如下:

全局前置路由守卫 -> 全局后置路由守卫

组件被激活时,触发顺序如下:

全局前置路由守卫 -> 独享前置路由守卫 -> 组件内路由前置守卫 -> 全局后置路由守卫

组件被切换走时,触发顺序如下:

组件内路由离开守卫 -> 全局前置路由守卫 -> 全局后置路由守卫

2.8 路由器的工作模式

工作模式通过router的mode属性配置,有history 和 hash 两种,默认是hash

hash : 只有#之前的url会随着请求会发给服务器,不会带上路由组件的url

history : 会把我们配置的路由组件的url也带上

打个比方:

// 我们想请求的地址 : https://localhost:8080/students
// 此时,我们在路由组件Person准备发送请求,即此时的url为:  https://localhost:8080/#/person
// 我们发送 /students 的请求
// history : https://localhost:8080/person/students
// hash : https://localhost:8080/person
// 此时,history当前请求不到资源

修改路由的工作模式如下:

const router = new VueRouter({
	mode: ['hash' / 'history'],
	routes: [
		
	]
})
相关推荐
夏花里的尘埃2 小时前
vue3实现echarts——小demo
前端·vue.js·echarts
木觞清2 小时前
Django学习第三天
python·学习·django
努力学习的木子2 小时前
uniapp如何隐藏默认的页面头部导航栏,uniapp开发小程序如何隐藏默认的页面头部导航栏
前端·小程序·uni-app
java小郭5 小时前
html的浮动作用详解
前端·html
水星记_5 小时前
echarts-wordcloud:打造个性化词云库
前端·vue
强迫老板HelloWord6 小时前
前端JS特效第22波:jQuery滑动手风琴内容切换特效
前端·javascript·jquery
luanluan88887 小时前
维护el-table列,循环生成el-table
javascript·vue.js·ecmascript·element plus
续亮~7 小时前
9、程序化创意
前端·javascript·人工智能
muren7 小时前
昇思MindSpore学习笔记2-01 LLM原理和实践 --基于 MindSpore 实现 BERT 对话情绪识别
笔记·深度学习·学习
RainbowFish8 小时前
「Vue学习之路」—— vue的常用指令
前端·vue.js