Dark Horse Headline Project-day02

5. Base address encapsulation

1. Download and install

npm i axios

2. Add packaging files to realize the packaging of axios

// 封装文件为:@/utils/myaxios.js
import axios from 'axios'
// 设置基准路径
axios.defaults.baseURL = 'http://localhost:3000'

// ......还有一大坨代码

export default axios

5.1 Encapsulate the login interface

// @/apis/user.js
---------------------------
// 引入的axios已经配置好基准路径
import axios from '@/utils/myaxios.js'

// 1.登陆
export const login = (data) => {
    
    
    return axios({
    
    
        method:'post',
        url:'/login',
        data
    })
}

5.2 User name and password verification regularity

 if (/^1\d{4}$|^1[35789]\d{9}$/.test(this.user.username) && /^.{3,16}$/.test(this.user.password)) {
        console.log(22);

5.3 Storing token

// 获取token,待会去验证是否可以登录
 localStorage.setItem('token',res.data.data.token)

5.3 Complete login effect: bring id

 this.$router.push({ path: `/personal/${res.data.data.user.id}` })
Two keywords: async and await

Allows us to call asynchronous methods in a synchronous manner, which means that we can directly obtain the return results of asynchronous operations, and proceed to the next step according to the results

await must be in the async function, the function marked by async is the function where the await keyword is located

 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. Personal Hub Page

Insert picture description here

If the login is successful, you should jump to the personal center page

6.1 New single file component

@/views/personal.vue

6.2 Configure routing

Get id through this.$route.params.id

{
    
    
        name: 'personal',
        path: '/personal/:id',
        // 异步组件:请求login页面的时候再引入文件
        component: () =>
            import ('@/views/personal.vue')
    }

6.3 Package interface

    // 获取用户详情
    // 接口类型:【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.4 Login page setting jump

// 实现页面的跳转(嵌套路由)
 this.$router.push({
    
     path: `/personal/${
      
      res.data.data.user.id}` })
// window.location.href='#/personal'

The former has an id on the url, the latter uses this.$route.params.id to get the id

6.5 New mycell subcomponent

</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 Introducing button subcomponents

    <mycell title='我的关注' desc='关注的用户'></mycell>
    <mycell title='我的跟帖' desc='跟帖/回复'></mycell>
    <mycell title='我的收藏' desc='文章/视频'></mycell>
    <mycell title='设置'></mycell>
    <hmbutton type='warning'>退出</hmbutton>

6.8 New date subcomponent:

Package date filter 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 Avatar rendering

The new user does not have an avatar and uses the default avatar, and the old user uses the avatar stored in the edit user information.

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 Complete the overall page effect

Use hook function to render data by default: avatar, username, date

<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. Route navigation guard:

Check ticketof: Judge whether the personal has been logged in, put it in if there is one, if not: go back to the login page

The role of the navigation guard is to guard the navigation

When we are going to some pages, we need to judge whether the current user has logged in. If logged in, we can jump, otherwise we will be redirected to the login page.

The navigation guard is the navigation guard of the route

// 路由的跳转:就是去另外一个组件,页面
// 添加路由守卫,判断是否可以跳转,它是通过进行路由的跳转时自动触发的,不是人为调用的
// 所有路由跳转请求都会经过这个导航守卫
// 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 interceptor

8.1 Request Interceptor: Put the ticket out for inspection

Before you send the request, intercept the current request and process the request message accordingly

// 添加请求拦截器:所有请求都会经过这个拦截器
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);
});

Guess you like

Origin blog.csdn.net/weixin_48371382/article/details/109381773