1、路由配置
路由组件
路由组件就是一个普通组件,只不过不需要使用全局或者局部注册。在路由配置中绑定对应的路由组件即可
const page = {
template: `
`
}
const routes = [
{
path: '/',
component: page // 一旦页面路由匹配了 / 那么vue就会把page渲染到页面的router-view中
}
]
路由配置
路由配置是一个数组
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得到的
const router = new VueRouter({
routes,
linkActiveClass: '新的类名',
linkExactActiveClass: '精确的新的类名'
})
在new Vue中配置router
const app = new Vue({
el: '#app',
router // 一旦将router加入到这个位置,那么this中就会多两个东西,this.$route this.$router
})
router-link
router-link默认会被渲染成a标签
2、路由参数
路由参数分类
query
http://localhost:3000/#/?key=value&key2=value
query
this.$route.query.key
this.$route.query.key2
router-link怎么声明
params
注意 想要有params参数必须配置动态路由,动态路由的变量,就是params的属性
const routes = [
{
path: '/:id'
}
]
{{$route.params.id}}
router-link怎么声明
3、全局前置守卫
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()
}
})
export default {
methods: {
login () {
// 获取用户名密码,用用户名密码请求登录接口
如果请求成功,则将对应的token存储起来
继续跳转到对应的页面
const url = this.$route.query.url || '/'
this.$router.replace(url)
}
}
}
4、 编程式导航
- 声明式导航
- 编程式导航
导航方式
编程式导航利用了router,这个router就是new VueRouter()。有些地方没法直接获取到router,需要使用this.$router
// 直接写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() 历史记录后退
*/
5、 拦截器
请求拦截器
拦截请求,然后查询是否有token,如果有则添加到请求头(这样所有的请求就都有token),如果没有则不添加
// 添加一个请求拦截器
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不存在,需要我们手动引入
// 添加一个响应拦截器
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前缀