# 路由配置
## 路由组件
> 路由组件就是一个普通组件,只不过不需要使用全局或者局部注册。在路由配置中绑定对应的路由组件即可
```javascript
const page = {
template: `
`
}
const routes = [
{
path: '/',
component: page // 一旦页面路由匹配了 / 那么vue就会把page渲染到页面的router-view中
}
]
```
## 路由配置
> 路由配置是一个数组
```javascript
const routes = [
// 多个路由配置对象
{
path: '/a/b/c/d/e', // 表示对应的路由路径
component: 组件名,
children: [
// chilren中包含的也是路由配置对象,只不过他的组件会渲染到其父路由的组件中的router-view
{
path: 'f', // path不需要写 / 路由会和父路由进行拼接 /a/b/c/d/e/f
}
]
}, {
path: '/a/b/c/d/e/f', // 这个和上面的情况不一样,他的组件会被渲染到app的router-view中
component: 组件名
}
]
```
## 创建router对象
> router对象是new VueRouter得到的
```javascript
const router = new VueRouter({
routes,
linkActiveClass: '新的类名',
linkExactActiveClass: '精确的新的类名'
})
```
## 在new Vue中配置router
```javascript
const app = new Vue({
el: '#app',
router // 一旦将router加入到这个位置,那么this中就会多两个东西,this.$route this.$router
})
```
## router-link
> router-link默认会被渲染成a标签
```html
```
# 路由参数
## 路由参数分类
### query
```
http://localhost:3000/#/?key=value&key2=value
query
this.$route.query.key
this.$route.query.key2
```
router-link怎么声明
```html
```
### params
> ***注意*** 想要有params参数必须配置动态路由,动态路由的变量,就是params的属性
```javascript
const routes = [
{
path: '/:id'
}
]
```
```html
```
router-link怎么声明
```html
```
# 全局前置守卫
```javascript
const router = new VueRouter()
router.beforeEach((to, from, next) => {
// 判断某些路由是否需要登录才能访问
if (to.matched.some(route => route.meta.自定义属性名)) {
// 验证token是否可以使用
if (验证token) {
next() // 正常跳转
} else {
next({path: '/login', query: {url: to.path}}) // 跳转到登录页面后,会携带对应的url参数 这个url就是登录成功后要跳转的path
}
} else {
next()
}
})
```
```javascript
export default {
methods: {
login () {
// 获取用户名密码,用用户名密码请求登录接口
如果请求成功,则将对应的token存储起来
继续跳转到对应的页面
const url = this.$route.query.url || '/'
this.$router.replace(url)
}
}
}
```
# 编程式导航
* 声明式导航
* 编程式导航
## 导航方式
> 编程式导航利用了router,这个router就是new VueRouter()。有些地方没法直接获取到router,需要使用this.$router
```javascript
// 直接写path
this.$router.push('path')
// 直接写name
this.$router.push('name')
// 写成对象形式
this.$router.push({path: 'path'})
this.$router.push({name: 'name'})
// 携带query参数
this.$router.push({path: 'path', query: {key: "value"}})
this.$router.push({name: 'name', query: {key: "value"}})
// 携带params参数
this.$router.push({name: 'name', params: {key: "value"}})
// push的作用就是去跳转页面,并且会在历史记录里新增新的历史记录
/*
this.$router.replace()
括号中的写法和push一致,replace会将新的页面替换当前历史记录中的页面
this.$router.go() 去对应的历史记录中
this.$router.forward() 历史记录前进
this.$router.back() 历史记录后退
*/
```
# 拦截器
## 请求拦截器
> 拦截请求,然后查询是否有token,如果有则添加到请求头(这样所有的请求就都有token),如果没有则不添加
```javascript
// 添加一个请求拦截器
axios.interceptors.request.use((config) => {
// 获取localStorage中的token如果有则添加,如果没有则不添加
const token = localStorage.getItem('token')
token ? config.headers.common['Authorization'] = "Bearer " + token : null
return config
}, (err) => {
return Promise.reject(err)
})
```
## 响应拦截器
> 拦截响应结果,如果为401,则跳转到登录,router在axios.js不存在,需要我们手动引入
```javascript
// 添加一个响应拦截器
axios.interceptors.response.use((res) => {
if (res.data.res_code === 401) {
// 跳转到登录页
router.push('/login')
}
// 对响应数据做点什么
return res;
}, (error) => {
// 对响应错误做点什么
return Promise.reject(error);
});
```
## token哪来的
> token是在登录操作中获取到的,获取到token后,将其存储在storage里供以后使用
***token在使用时需要加到header,并不是所有的都需要加Bearer前缀***
# 路由组件传参
> 对应模式不同在于路由配置上的props设置不同
- 布尔模式
- 对象模式
- 函数模式
## 布尔模式
组件
```html
{{$route.params.id}}
{{id}}
export default {
props: {
// params中的参数
id: String
}
}
```
路由配置
```javascript
const routes = [
{
path: '/:id',
props: true
}
]
```
## 对象模式
> 传递静态数据可以使用对象模式
组件
```html
{{属性1}} {{属性2}}
export default {
props: {
属性1: 类型,
属性2: 类型
}
}
```
路由配置
```javascript
const routes = [
{
path: '/:id',
props: {
属性1: 值1,
属性2: 值2
}
}
]
```
## 函数模式
> 传递动态数据时可以使用
组件
```html
{{query中的参数}}
export default {
props: {
query中的参数: 类型
}
}
```
路由配置
```javascript
const routes = [
{
path: '/:id',
props: route => {
// 参数route就是this.$route
// 这个函数需要返回的是一个对象
return route.query
}
}
]
```
***注意:这些方法只是为了解耦,不再组件中使用$route***