<el-menu router>el-menu>
把index的值改成约定好的路由地址:
<el-menu-item index="/">
<i class="el-icon-s-home">i>
<span slot="title">首页span>
el-menu-item>
<el-menu-item index="/article">
<i class="el-icon-document">i>
<span slot="title">内容管理span>
el-menu-item>
<el-menu-item index="/image">
<i class="el-icon-picture">i>
<span slot="title">素材管理span>
el-menu-item>
<el-menu-item index="/publish">
<i class="el-icon-s-promotion">i>
<span slot="title">发布文章span>
el-menu-item>
<el-menu-item index="/comment">
<i class="el-icon-chat-dot-round">i>
<span slot="title">评论管理span>
el-menu-item>
<el-menu-item index="/fans">
<i class="el-icon-present">i>
<span slot="title">粉丝管理span>
el-menu-item>
<el-menu-item index="/setting">
<i class="el-icon-setting">i>
<span slot="title">个人设置span>
el-menu-item>
动态绑定激活的菜单
<el-menu :default-active="$route.path">el-menu>
//显示当前的路径
<template>
<div class='container'>div>
template>
<script>
export default {}
script>
<style scoped lang='less'>
.container{
position: absolute;
width: 100%;
height: 100%;
background: url(../../assets/images/404.png) no-repeat center / cover;
}
style>
router/index.js 最后加一个规则
routes: [
{ path: '/login', name: 'login', component: Login },
{
path: '/',
component: Home,
children: [
{ path: '/', name: 'welcome', component: Welcome },
{ path: '/article', name: 'article', component: Article }
]
},
+ // 处理404
+ { path: '*', name: '404', component: NotFound }
]
GET http://ttapi.research.itcast.cn/mp/v1_0/articles 401 (UNAUTHORIZED)
// store/index.js 模块 获取用户 设置用户
// 存储信息的时候:
// 1. 约定信息的KEY是什么 hm-toutiao-77-user
// 2. 存储信息的值是什么 用户信息对象 字符串格式json
const KEY = 'hm-toutiao-77-user'
export default {
setUser (user) {
// 存储用户信息到sessionStorage
window.sessionStorage.setItem(KEY, JSON.stringify(user))
},
getUser () {
// 获取用户信息从sessionStorage
return JSON.parse(window.sessionStorage.getItem(KEY) || '{}')
}
}
保存用户信息: views/login/index.vue
login () {
// 对整个表单进行校验
this.$refs.loginForm.validate(valid => {
if (valid) {
// 请求登录接口
this.$http
.post(
'http://ttapi.research.itcast.cn/mp/v1_0/authorizations',
this.loginForm
)
.then(res => {
// res 响应对象 包含响应主体
// console.log(res.data)
+ // 存储用户信息
+ store.setUser(res.data.data)
// 跳转去首页
this.$router.push('/')
})
.catch(() => {
// 错误提示提示
this.$message.error('手机号或验证码错误')
})
}
})
}
// 路由实例
const router = new VueRouter({ ... })
// 提供函数 beforeEach 前置守卫
router.beforeEach((to, from, next) => {
// to 去的路由对象 from 来自哪里路由对象
// 做事情,获取用户信息
// 判断 是否登录 如果登录 放行 next() 拦截登录 next('/login')
// 注意 排除登录路由
})
最终的代码:router/index.js
// 前置导航守卫
router.beforeEach((to, from, next) => {
// // 1. 判断是不是登录路由
// if (to.path === '/login') return next()
// // 2. 判断是否登录
// if (!store.getUser().token) return next('/login')
// // 3. 放行
// next()
if (to.path !== '/login' && !store.getUser().token) return next('/login')
next()
})
api/index.js
// 配置一个axios 导出一个配置好的axios
import axios from 'axios'
import store from '@/store'
// 进行配置
axios.defaults.baseURL = 'http://ttapi.research.itcast.cn/mp/v1_0/'
axios.defaults.headers = {
Authorization: `Bearer ${store.getUser().token}`
}
// 进行导出
export default axios
main.js 修改
+ import axios from '@/api'
Vue.prototype.$http = axios
场景:
预期:
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
// 修改config,追加headers
return config;
}, function (error) {
// 认为返回错误的promise对象
return Promise.reject(error);
});
// 配置一个axios 导出一个配置好的axios
import axios from 'axios'
import store from '@/store'
// 进行配置
axios.defaults.baseURL = 'http://ttapi.research.itcast.cn/mp/v1_0/'
// 只会执行一次
// axios.defaults.headers = {
// Authorization: `Bearer ${store.getUser().token}`
// }
// 在每次请求之前,获取token信息,追加在headers中
// 请求拦截器:在每次请求前 做某一些事情
axios.interceptors.request.use((config) => {
// 修改config
config.headers = {
Authorization: `Bearer ${store.getUser().token}`
}
return config
}, (error) => {
// 错误处理
return Promise.reject(error)
})
// 进行导出
export default axios
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
// 状态码是401 跳转到登录页面
return Promise.reject(error);
});
最终的代码:api/index.js
// 响应拦截器:在每次响应后 做某一些事情
axios.interceptors.response.use((res) => {
// 成功的时候做一些事情
return res
}, (err) => {
// 失败的时候做一些事情
// 获取响应状态码 err对象包含响应对象 err.response
// 响应对象中包含状态码 err.response.status
if (err.response.status === 401) {
// 跳转到登录页面 this.$router.push('/login')
// 方式1:
// $router.push('/login') 其实 地址栏改成 #/login
// location.hash = '#/login'
// 方式2:
// 此时没有vue实例,$router对象获取不到,通过router实例直接使用
router.push('/login')
}
return Promise.reject(err)
})
异步操作:
// 当请求了A接口的数据才能获取B接口的数据
// xhr 发请求
// const xhr = new XMLHttpRequest()
// xhr.open('get','http://localhost:3000/a')
// xhr.send()
// xhr.onload = function(){
// console.log(xhr.responseText)
// const xhr2 = new XMLHttpRequest()
// xhr2.open('get','http://localhost:3000/b')
// xhr2.send()
// xhr2.onload = function(){
// console.log(xhr2.responseText)
// }
// }
// promise 发请求
// 怎么创建一个promise对象 const proimse = new Promise(回调函数)
// Promise.reject() 返回一个失败的promise对象
// Promise.resolve() 返回一个成功的promise对象
// proimse.then(成功).catch(失败)
const axios = (url) => {
return new Promise((resolve, reject) => {
// resolve 成功的时候应该调用的回调函数
// reject 失败的时候应该调用的回调函数
const xhr = new XMLHttpRequest()
xhr.open('get', url)
xhr.send()
xhr.onload = function () {
// 传参内容 将在then的时候使用
resolve(xhr.responseText)
}
xhr.onerror = function () {
reject('失败错误对象')
}
})
}
// axios('http://localhost:3000/a').then(data=>{
// console.log(data)
// return axios('http://localhost:3000/b')
// }).then(data=>{
// console.log(data)
// })
// async 与 await 的使用只能结合promise
// 返回值是 promise 对象 加上await后返回是then的回调参数
const getData = async () => {
const a = await axios('http://localhost:3000/a')
const b = await axios('http://localhost:3000/b')
console.log(a)
console.log(b)
// await is only valid in async function
// awiat的使用必须在async修饰的函数内使用
}
getData()