vue-cli项目中的技术栈

165 阅读2分钟

封装Axios

vue项目中,经常使用axios库实现与后台数据交互。

全局安装axios库之后,可以自己封装请求。

import axios from 'axios'
import { ElMessage } from 'element-plus'           //使用element plus ui组件实现提醒信息

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'  //设置post请求头
axios.defaults.baseURL = '//blog-server.hunger-valley.com'     //请求的baseUrl


export default function request(url, type = 'GET', data = {}) {
  return new Promise((resolve, reject) => {
    let option = {
      url,
      method: type,
    }
    if(type.toLowerCase() === 'get') {               //get请求,它跟 post 请求的区别是提交的参数不一样
      option.params = data
    }else {
      option.data = data                             //post 
    }
    if(localStorage.token) {            //再次请求时,如果localStorage中存在token,则将token加在请求头上
      axios.defaults.headers.common['Authorization']  = localStorage.token
    }
    axios(option).then(res => {
      if(res.data.status === 'ok') {                        //跟后端的约定res.data/res.data.msg都是约定
        if(res.data.token) {
          localStorage.token = res.data.token
        }
        resolve(res.data)
      }else{
        ElMessage.error(res.data.msg)
        reject(res.data)
      }
    }).catch(err => {
      ElMessage.error('网络异常')
      reject({ msg: '网络异常' })
    })
  })
}

拦截器

分为请求拦截器和响应拦截器。

axios.interceptors.request.use(                    //请求拦截器,每次请求前判断localStorage中是否存在token,如果存在,给所有请求头加上token
   config => {
      const token = localStorage.token
      token && (config.headers.Authorization = token);
      return config;
   },
   error => {
      return Promise.error(error)
   }
)
axios.interceptors.response.use(           //如果返回的状态码是200,说明请求成功,否则抛出错误。
   response => {
      if (response.status === 200){
          return Promise.resolve(response)
      } else {
          return Promise.reject(response)
      }
   },
   error => {
      if (error.response.status){
          switch (error.response.status) {
              case 401:                         //未登录,需跳转到登录界面,登录功后返回当前页面
                 router.replace({
                     path:'/login',
                     query: {
                         redirect:router.currentRoute.fullPath
                     }
                 });
                 break;
              case 403:                       // token 过期,清除token并返回登录界面。
                 ElMessage.error('登录过期,请重新登录');
                 localStorage.removeItem('token');
                 setTimeout(()=>{
                     router.replace({
                         path:'/login',
                         query: {
                             redirect:router.currentRoute.fullPath
                     }
                 });
                 })                 
          }
      }
   }
)

vuex

各组件公用的数据,如果按组件通信的方法传递会很复杂。这时就要考虑使用vuex。

在入口文件:

import { createApp } from 'vue'
import App from './App.vue'
import store from "@/store/modules/auth/index.js

createApp(App)
     .use(store)
     .mount('#app')

使用store封装vuex的各种操作

import {createStore} from 'vuex'
import getters from './getters'
import actions from "./actions"
import mutations from "./mutations"

const state ={
  user: null,
  isLogin: false
}
const store = createStore({
  state,                               //数据在state中
  getters,                             // 读数据
  actions,                             //异步操作数据
  mutations                            // 同步修改数据
})

export default store

在组件中,使用vuex中方法的方式如下:

import {useStore} from 'vuex'
import {computed} from 'vue'

export default {
  setup() {
    const store = useStore()
    return {
      onLogout: () => store.dispatch('logout'),              //调用dispatch和commit来获取actions和  mutation   
      isLogin: computed(() => store.getters.isLogin),         //在 computed 函数中访问 state 和 getters

      user: computed(() => store.getters.user),
      checkLogin: () => store.dispatch('checkLogin'),
    }
  }
}
</script>