黑马头条项目-day02

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);
});

猜你喜欢

转载自blog.csdn.net/weixin_48371382/article/details/109381773