路由(vue-router)
1、安装并使用
-
npm i vue-router@3 / yarn add vue-router@3
- vue-router3以上的版本只能用于vue3,vue2只能用3或以下的版本
-
main.js引入
import Vue from 'vue' import App from './App.vue' import router from './router'; new Vue({ router, render: h => h(App), }).$mount('#app') -
创建router/index.js
-
index.js
import Vue from 'vue' import VueRouter from 'vue-router'; Vue.use(VueRouter); const router = new VueRouter({ routes: [ { path: '/home', component: () => import("../xxx/xxx/xxx.vue") }, { path: '/about', component: () => import("../xxx/xxx/xxx.vue") }, ] }) export default router
-
-
使用
<!-- 路由切换 --> <!-- active-class:路由激活后的样式 --> <router-link to='/home'>到home</router-link> <router-link to='/about'>到about</router-link> <!-- 指定展示的位置 --> <router-view></router-view> -
注意点:
- 路由组件通常单独创建一个文件夹存放,一般该文件夹名称为pages或views,一般组件通常放在components文件夹中
- 通过切换,“隐藏”了的路由组件,默认是被销毁了,需要的时候再去挂载
- 每个组件都有自己的$route属性,里面存储自己的路由信息
- 整个应用只有一个router,可以通过$router属性获取到
2、嵌套(多级)路由
-
配置router/index.js
import Vue from 'vue' import VueRouter from 'vue-router'; Vue.use(VueRouter); const router = new VueRouter({ routes: [{ path: '/home', component: () => import("../components/home.vue") }, { path: '/about', component: () => import("../components/about.vue"), children: [{ // 两种写法: // 1、直接写子路由的path,不用加斜杠,vue会自动拼接 // path: 'xxxx', // 2、自己拼接path,必须携带父路由的path,格式:/父路由/子路由 path: '/about/xxxx', component: () => import("../xxx/xxxx.vue") }] }, ] }) export default router -
about中使用
注意:跳转时,必须写完整的子路由path地址
<!-- 使用路由跳转 --> <!-- active-class:路由激活后的样式 --> <router-link active-class="active" to='/home/xxxx'>到home的子路由</router-link> <!-- 展示的位置 --> <router-view></router-view>
3、命名路由
-
配置router/index.js
import Vue from 'vue' import VueRouter from 'vue-router'; Vue.use(VueRouter); const router = new VueRouter({ routes: [{ name:'home', path: '/home', component: () => import("../components/home.vue") }, { name: 'about', path: '/about', component: () => import("../components/about.vue"), }, ] }) export default router -
跳转
<router-link :to="{name: 'home'}"> to home</router-link>
4、路由传参
4.1、query传参
-
html中传参
-
传参
<!-- 字符串传参 --> <router-link active-class="active" :to="`/home?id=${111}&name=${'小明'}`">到home</router-link> <!-- 对象传参 --> <router-link active-class="active" :to="{ path:'/home', query:{ id:111, name:'小明' } }">到home</router-link> <!-- 使用命名路由query传参 --> <router-link active-class="active" :to="{ name:'/home', query:{ id:111, name:'小明' } }">到home</router-link>
-
-
js中传参
this.$router.push({ path:'/home', query:{ id:111, name:'小明' } }) // 使用命名路由query传参 this.$router.push({ name:'home', query:{ id:111, name:'小明' } }) -
接收参数
mounted() { console.log(this.$route.query.xxxx); },
4.2、params传参
params传参只能使用name,不能使用path
-
html中传参
-
使用对象传参
<router-link active-class="active" :to="{ name:'home', params:{ id:111, name:'小明' } }">到home</router-link> -
使用字符串
params使用字符串方式传参,需要在router/index.js中配置占位符
配置router/index.js:
import Vue from 'vue' import VueRouter from 'vue-router'; Vue.use(VueRouter); const router = new VueRouter({ routes: [{ name:'home', path: '/home/:id/:name', component: () => import("../components/home.vue") }, { name: 'about', path: '/about/:id/:name', component: () => import("../components/about.vue"), }, ] }) export default router使用
<router-link active-class="active" to='/about/111/小明'>到about</router-link>
-
-
js中传参
this.$router.push({ name:'home', params:{ id:111, name:'小明' } }) -
接收参数
mounted() { console.log(this.$route.params.xxxx); },
5、路由的props配置
-
第一种写法
这种写法,是在router/index.js配死了的,也就是说,在router/index.js中配置的什么字段,在组件中就只能接收什么字段,并且这种方法是以字符串方式返回
-
配置router/index.js:
import Vue from 'vue' import VueRouter from 'vue-router'; Vue.use(VueRouter); const router = new VueRouter({ routes: [{ name:'home', path: '/home', props:{id:'111',name:'小明'}, component: () => import("../components/home.vue") } ] }) export default router -
home组件中接收
<template> <div class="home"> 1111 </div> </template> <script> export default { name: 'home', props:['id','name'], } </script> <style scoped> </style>
-
-
第二种写法
配置props为一个boolean值,为true时,会将该组件收到的所有params参数,以props的形式传给about组件,并且值为一个对象
-
配置router/index.js:
import Vue from 'vue' import VueRouter from 'vue-router'; Vue.use(VueRouter); const router = new VueRouter({ routes: [ { name: 'about', path: '/about', props:true, component: () => import("../components/about.vue"), }, ] }) export default router -
在app.vue传入params
<router-link active-class="active" :to="{ name:'about', params:{ id:111, name:'小明' } }">到about</router-link> -
about组件中接收
<template> <div class="about"> <button>{{id}}{{name}}</button> </div> </template> <script> export default { name: 'about', props:['id','name'], } </script> <style scoped> </style>
-
-
第三种写法
配置props为函数,该函数会接收到一个$route参数,以props的形式传给组件,并且值为一个对象,接收参数的方式与前面两种一致
import Vue from 'vue' import VueRouter from 'vue-router'; Vue.use(VueRouter); const router = new VueRouter({ routes: [{ name:'home', path: '/home', props($route) { return { id: $route.query.id, name: $route.query.name } }, component: () => import("../components/home.vue") }, { name: 'about', path: '/about', props($route) { return { id: $route.params.id, name: $route.params.name } }, component: () => import("../components/about.vue"), }, ] }) export default router
6、router-link的replace属性
-
作用:控制路由跳转时操作浏览器历史记录的模式
-
浏览器的历史记录有两种写入方式,分别为push和replace,push是追加历史记录,replace是替换当前记录,默认为push
-
如何开启replace:
<router-link replace to="/xxx"></router-link>
7、前进,后退,替换
// query传参
this.$router.push({
path:'/xxxx',
query:{}
})
// params传参
this.$router.push({
name:'xxxx',
params:{}
})
// params传参
this.$router.replace({
name:'xxxx',
// path:'/xxxx',
// query:{},
params:{}
})
// 前进
this.$router.forward()
// 后退
this.$router.back()
// 传入的参数为正数就是前进,负数为后退
this.$router.go(-1)
8、keep-alive
-
作用:让不展示的路由组件保持挂载,不被销毁
-
代码:
<!-- keep-alive:缓存路由组件 --> <!-- include:只缓存某一个组件,若要缓存多个组件,可写一个数组 :include="['xxx','xxx']" --> <keep-alive include="home"> <!-- 展示的位置 --> <router-view></router-view> </keep-alive>
9、生命周期activated&deactivated
-
作用:路由组件所独有的两个钩子函数,用于捕获路由组件的激活状态
-
详情:
activated:路由组件激活时触发
deactivated:路由组件销毁时触发
10、路由守卫
- 作用:对路由进行权限控制
- 分类:全局守卫,独享守卫,组件内守卫
10.1、全局前置路由守卫
// 全局前置路由守卫
// 初始化的时候被调用,每次路由切换之前被调用
router.beforeEach((to,from,next) => {
// to:要去的目标路由
// from:当前所在的路由
// next:放行
// 判断有没有登录
if (localStorage.getItem("token")) {
// 如果登录过允许跳转
next();
} else {
// 如果没登陆过,但要跳转到登录页,允许跳转
if (to.path === "/login") {
next();
} else {
// 否则跳转到登录页
next("/login");
}
}
})
10.2、全局后置路由守卫
// 全局后置路由守卫
// 初始化的时候被调用,每次路由切换之后被调用
router.afterEach((to,from,next) => {
// to:要去的目标路由
// from:当前所在的路由
// next:放行
})
10.3、独享路由守卫
作用:某一个路由所独享的路由守卫
import Vue from 'vue'
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const router = new VueRouter({
routes: [{
name: 'xxxx',
path: '/xxxx',
// 独享路由守卫
// 组件初始化的时候被调用,在路由切换之前被调用
beforeEnter: (to, from, next) => {
// to:要去的目标路由
// from:当前所在的路由
// next:放行
},
component: () => import("../xxxx/xxxx.vue"),
children: [{
name: 'xxxx',
path: '/xxxx',
// 独享路由守卫
// 组件初始化的时候被调用,在路由切换之前被调用
beforeEnter: (to, from, next) => {
// to:要去的目标路由
// from:当前所在的路由
// next:放行
},
component: () => import("../xxxx/xxxx.vue"),
}]
},
]
})
export default router
10.4、组件内路由守卫
-
beforeRouteEnter
// 通过路由规则, 进入该组件之前调用 beforeRouteEnter(to,from,next){ // to:要去的目标路由 // from:当前所在的路由 // next:放行 } -
beforeRouteLeave
// 通过路由规则, 离开该组件之前调用 beforeRouteLeave(to,from,next){ // to:要去的目标路由 // from:当前所在的路由 // next:放行 }
11、hash和history模式
- 对于url来说,什么是hash至?——#及其后面的内容就是hash值。
- hash值不会包含在HTTP请求中,即:hash值不会带给服务器。
- hash模式:
- 地址中永远带着#号,不美观
- 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
- 兼容性较好
- history模式:
- 地址干净、美观
- 兼容性和hash模式相比略差
- 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题