5.基地址封装
1.下载安装
npm i axios
2.添加封装文件实现axios的封装
// 封装文件为:@/utils/myaxios.js
import axios from 'axios'
// 设置基准路径
axios.defaults.baseURL = 'http://localhost:3000'
// ......还有一大坨代码
export default axios
5.1封装login接口
// @/apis/user.js
---------------------------
// 引入的axios已经配置好基准路径
import axios from '@/utils/myaxios.js'
// 1.登陆
export const login = (data) => {
return axios({
method:'post',
url:'/login',
data
})
}
5.2用户名和密码校验正则
if (/^1\d{4}$|^1[35789]\d{9}$/.test(this.user.username) && /^.{3,16}$/.test(this.user.password)) {
console.log(22);
5.3存储token
// 获取token,待会去验证是否可以登录
localStorage.setItem('token',res.data.data.token)
5.3完成登陆效果:带上id
this.$router.push({ path: `/personal/${res.data.data.user.id}` })
两个关键字:async和await
可以让我们以同步的方式来调用异步方法,意味着我们可以直接获取异步操作的返回结果,根据结果进行下一步的处理
await必须处于async函数中,async标记的函数就是await关键字所在的函数
methods:{
// login(){
// console.log(this.user.username,this.user.password);
// login(this.user)
// .then((res)=>{
// console.log(res);
// })
// .catch((err)=>{
// console.log(err);
// })_
// }
// 发起axios请求:async+函数变成异步:先接收data回来再发请求
async login(){
if (/^1\d{4}$|^1[35789]\d{9}$/.test(this.user.username) && /^.{3,16}$/.test(this.user.password)) {
console.log(22);
let res = await login(this.user)
console.log(res);
if(res.data.message === '用户不存在'){
// 给出用户提示
this.$toast.fail(res.data.message)
}
else{
// 实现页面的跳转
this.$toast.success('登录成功');
// 获取token,待会去验证是否可以登录
localStorage.setItem('token',res.data.data.token)
// 为了后期的操作,将当前用户数据也存储到本地
// window.location.href='#/personal'
this.$router.push({
path: `/personal/${
res.data.data.user.id}` })
}
}else if(this.user.username==''||this.user.password==''){
this.$toast.fail('请输入用户名或密码')
}
else{
this.$toast.fail('用户或密码不正确')
}
}
}
}
6.个人中心页
如果登陆成功,应该跳转到个人中心页
6.1新建单文件组件
@/views/personal.vue
6.2配置路由
通过this.$route.params.id获取到id
{
name: 'personal',
path: '/personal/:id',
// 异步组件:请求login页面的时候再引入文件
component: () =>
import ('@/views/personal.vue')
}
6.3封装接口
// 获取用户详情
// 接口类型:【GET】
// 需要验证:【Authorization 】
// 接口地址:/user/:id
// xhr.setRequestHeader('Conent-Type','applicatio/x-www-form-urlencoded')
export const getUserInfo = (id) => {
return axios({
url: `/user/${
id}`,
// headers: { Authorization: localStorage.getItem('hm_toutiao_56') }
})
}
6.4login页面设置跳转
// 实现页面的跳转(嵌套路由)
this.$router.push({
path: `/personal/${
res.data.data.user.id}` })
// window.location.href='#/personal'
前者url上面带上id,后者使用this.$route.params.id获取id
6.5新建mycell子组件
</style><template>
<div class="mycell">
<div class="left">{
{title}}</div>
<div class="right">{
{desc}}<span class="iconfont iconjiantou1"></span></div>
</div>
</template>
<script>
export default {
props:['title','desc']
}
</script>
<style lang='less' scoped>
.mycell{
padding: 20px 10px;
display: flex;
justify-content: space-between;
border-bottom: 1px solid #ccc;
> .right{
font-size: 13px;
color: #888;
}
}
</style>
6.7引入button子组件
<mycell title='我的关注' desc='关注的用户'></mycell>
<mycell title='我的跟帖' desc='跟帖/回复'></mycell>
<mycell title='我的收藏' desc='文章/视频'></mycell>
<mycell title='设置'></mycell>
<hmbutton type='warning'>退出</hmbutton>
6.8新建日期子组件:
封装日期过滤器 src/utils/myfilter.js
// 封装项目中所需要使用的全局过滤器
// 过滤器的本质是函数
export const dateFormat = (value, spe) => {
console.log(typeof value)
value = new Date(value) // 将value字符串转换为日期格式
let year = value.getFullYear()
let month = value.getMonth() + 1
let day = value.getDate()
return `${
year}${
spe}${
month}${
spe}${
day}`
}
import {
dateFormat } from '@/utils/myfilter.js'
// 由于我们封装是函数,所以得进行注册,确定它是用于过滤器
filters: {
dateFormat
},
<div class="time">{
{
userinfo.create_date | dateFormat('-')}}</div>
6.9头像渲染
新用户没有头像使用默认头像,老用户使用编辑用户信息里存储的头像
if(this.userinfo.head_img){
this.userinfo.head_img=axios.defaults.baseURL+this.userinfo.head_img
}else{
this.userinfo.head_img=axios.defaults.baseURL+'/uploads/image/timg.gif'
}
6.10完成整体页面效果
利用钩子函数默认渲染数据:头像,用户名,日期
<template>
<div class="personal">
<!-- 渲染头部 -->
<router-link :to="'/edit_profile/'+userinfo.id">
<div class="profile">
<img :src="userinfo.head_img" alt />
<div class="profile-center">
<div class="name">
<span class="iconfont" :class='userinfo.gender===0?"iconxingbienv":"iconxingbienan"'></span>{
{userinfo.nickname}}
</div>
<div class="time">{
{userinfo.create_date | dateFormat}}</div>
<!-- 渲染头部结束 -->
</div>
<span class="iconfont iconjiantou1"></span>
</div>
</router-link>
<mycell title='我的关注' desc='关注的用户'></mycell>
<mycell title='我的跟帖' desc='跟帖/回复'></mycell>
<mycell title='我的收藏' desc='文章/视频'></mycell>
<mycell title='设置'></mycell>
<hmbutton type='warning' @click="exit">退出</hmbutton>
</div>
</template>
<script>
// 个人中心页,待会登录页验证成功需要跳过来
// 操作:把个人中心页的结构和样式复制过来
// 配置路由然后实现跳转到个人中心,如果判断登录了放进来给数据 没有:回去登录页
// 使用导航守卫判断带是否登录过,有就放进来,没有:回去登录页
// 使用请求拦截器,在发送请求之前把token带上
import mycell from '@/components/mycell.vue'
import hmbutton from '@/components/hmbutton.vue'
import { getUserInfo } from '@/apis/user.js'
import axios from '@/utils/myaxios.js'
import { dateFormat } from '@/utils/myfilter.js'
export default {
data () {
return {
userinfo:{}
}
},
components:{
mycell,hmbutton
},
// 由于我们封装是函数,所以得进行注册,确定它是用于过滤器
filters:{
dateFormat
},
methods:{
exit(){
localStorage.removeItem('tokens')
this.$router.push({path:'/index'})
}
},
async mounted () {
// 一进来渲染数据:头部
let id = this.$route.params.id
let res = await getUserInfo(id)
console.log(res)
this.userinfo=res.data.data
console.log(this.userinfo);
if(this.userinfo.head_img){
this.userinfo.head_img=axios.defaults.baseURL+this.userinfo.head_img
}else{
this.userinfo.head_img=axios.defaults.baseURL+'/uploads/image/timg.gif'
}
}
};
7.路由导航守卫:
验票的:判断personal是否登录过,有就放进来,没有:回去登录页
导航守卫的作用就是用来守卫导航的
我们在进行某些页面的时候需要判断当前用户是否登陆过,如果登陆过,则可以跳转,否则重定向到登陆页
导航守卫是路由的导航守卫
// 路由的跳转:就是去另外一个组件,页面
// 添加路由守卫,判断是否可以跳转,它是通过进行路由的跳转时自动触发的,不是人为调用的
// 所有路由跳转请求都会经过这个导航守卫
// to:目标路由
// from:源路由
// next:下一步的操作,就是用户当前需要进行的操作
router.beforeEach((to, from, next) => {
// 并不是每个页面的访问都需要先登陆
if (to.name == 'personal') {
// 这里说明你要访问个人中心页
// 如果用户登陆过,则进行路由的跳转,否则重定向到登陆页
let token = localStorage.getItem('token')
if (token) {
// 如果有token说明你登陆过了
next()
} else {
Toast('请先登录')
// 如果是访问需要授权的页面且没有登陆过,则重定向到登陆页
next({
name: 'Login' })
}
} else {
// 如果不是访问需要授权的页面,如新闻页,那么不需要判断是否登陆
next()
}
})
// 暴露
export default router
8.axios拦截器
8.1请求拦截器:把票放出来检查
在你发送请求之前,拦截当前的请求,并对请求报文 做出相应的处理
// 添加请求拦截器:所有请求都会经过这个拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
// 获取token
let token = localStorage.getItem('toutiao_52_token')
// 判断是否有token如果有,则以请求头的方式进行传递
if(token){
config.headers.Authorization = token
}
// 可以拦截请求对报文进行处理,但是拦截器并不会代替你来发请求,只是对发送请求时所传递的报文 数据进行必要的处理
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});