当前位置: 首页 > news >正文

前端初始化项目对axios的封装和token的存储应用以及config.js代理的配置 比较全的了。

记得配置完vue.confing.js要重启项目
前提是你全部搭建了项目,现在开始写代码了。没有下载的没了要下载啊
可以npm i axios 或者yarn add axios 等
上图
在这里插入图片描述
这里是我的package.json文件,用什么自己下载什么。
一定要记得,你下载了什么就在mian.js 里引入什么在这里插入图片描述
代码

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
import echarts from "echarts";
import axios from 'axios'
import api from './request/http/api' // 导入api接口// 导入api接口 这个是后来写的,直接引过来了,代码在下边。
Vue.prototype.$api = api; // 将api挂载到vue的原型上
Vue.prototype.$echarts = echarts;
Vue.prototype.$axios = axios;
Vue.config.productionTip = false
Vue.use(Antd);
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

好了,此时就可以写axios 的封装和 vue.config.js代理了
上图在这里插入图片描述

代码你可以直接拿走,把后边的改了就行

module.exports = {
  devServer: {
    port: 8000, // 端口号
    proxy: { // 代理
       [process.env.NODE_ENV]: {
        target: "http://iot-dev.com", // 接口的域名,也就是需要跨域的目标url ,我这里是项目用到的
        changeOrigin: true, // 开启代理,将基于名称的虚拟托管网站的选项,如果不配置,请求会报404
        ws: true,
        pathRewrite: { // 重写地址
          "^/api": "" // 若请求的路径在目标url下,但不在/api 下,则将其转换成空
        }
      },
      // 第二个代理
      "/api": {
        target: "http://iot-dev..com", // 接口的域名,也就是需要跨域的目标url ,我这里是项目用到的
        changeOrigin: true, // 开启代理,将基于名称的虚拟托管网站的选项,如果不配置,请求会报404
        ws: true,
        pathRewrite: { // 重写地址
          "^/api": "" // 若请求的路径在目标url下,但不在/api 下,则将其转换成空
        }
      }
    },
  },
}

然后是写静态页面,假设我们已经创建了一个登录页面,此时要根据接口存token 并且在后续用token。
在template里写代码 上图
在这里插入图片描述
在这里插入图片描述
上代码 ,样式自己写吧,我也有点懒

 div
      <input type="text" v-model="loginForm.username" placeholder="用户名"/
      <input type="text" v-model="loginForm.password" placeholder="密码"/
      <button @click="login">登录</button>
div
    
    
 import { mapMutations} from 'vuex'
export default {
  name: "Home",
  components: {},
  data(){
    return {
      loginForm: {
        username:'',
        password:'',
      },
    }
  },
  methods: {
    ...mapMutations(['changeLogin']),
    login() {
      let _this = this
      if (this.loginForm.username === '' || this.loginForm.password === '') {
        alert ('账号密码不能为空')
      } else {
        this.axios({
          method: 'post',
          url: '/user/login',
          data: _this.loginForm
        }).then(res => {
          console.log(res.data)
          _this.userToken = "Bearer" + res.data.data.body.token
          // 将用户token保存到vuex 里
          _this.changeLogin({Authorization: _this.userToken})
          _this.$router.push('/about')
          alert('登录成功')
        }).catch(err => {
          alert('账号或密码错误')
          console.log(err)
        })
      }
    },}

这个是页面的简单逻辑。这里我们token用到了vuex。所以我们在store仓库里就要用到 在store下的index.js文件里写,你也可以单独拿出去写,但是记得要导出结合引入
上图 store在这里插入图片描述

上代码

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    // 存token
    Authorization: localStorage.getItem('token') ? localStorage.getItem('token') : ''
  },
  mutations: {
    // 修改token,并将token存入localStorage
    changeLogin(state, user) {
      state.Authorization = user.Authorization;
      localStorage.setItem('token', user.Authorization);
    },
    }

好了这个时候我们要记得在跟路由router下的index.js 里搞搞
在这里插入图片描述
上代码
import Vue from ‘vue’
import VueRouter from ‘vue-router’
import login from '…/views/login.vue’

Vue.use(VueRouter)

const routes = [
这里应该在写一个重定向的路由,自己写吧。看你们定哪里就写那个路由吧。
  {
    path: '/',
    name: 'login',
    component: login
  },]
  const router = new VueRouter({
  routes
})

// 导航守卫
// 使用router.beforeEach 注册全局前置守卫,判断用户是否登录

router.beforeEach((to, from, next) => {
  if (to.path === '/login') {
    next()
  } else {
    let token = localStorage.getItem('token')
    if (!token || token === '' || token === 'null') {
      next('/login')
    } else {
      next()
    }
  }
  
})
export default router

弄到了这里也就差不多了,剩下的就是封装axios了。这里我觉的写的比较全了,您要是有建议可以沟通一下啊,我也比较小白。

一、axios的封装

在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,
它是基于promise的http库,可运行在浏览器端和node.js中。
他可以拦截请求和响应、取消请求、转换json、客户端防御XSRF等。
安装
npm install axios; // 安装axios
引入
一般我会在项目的src目录中,新建一个request文件夹,
然后在里面新建一个http文件夹创建index.js和一个api.js文件。
http文件夹下的index.js 用来封装我们的axios,api.js用来统一管理我们的接口。

http-===index.js文件内容:

// http.js文件下的index.js用来封装我们的axios的

import { message } from 'ant-design-vue';
import axios from 'axios'; // 引入axios
import QS from 'qs'; // 引入qs模块,用来序列化post类型的数据,后面会提到
import { Toast } from 'vant'; // vant 里的轻提示组件
import router from '../../router'; // 根路径地址
import store from '@/store/index'; // 引入vuex里的文件库

// 允许跨域携带cookie信息是登录请求预处理,没有此设置,后端就无法讲数据保存到cookie中
// axios.defaults.withCredentials = true 这个一般写在mian.js 中,但是注意会报错
// 解决:在这里我们只需要改成(后端改的) response['Access-Control-Allow-Origin'] = "http://127.0.0.1:8080前端地址"

// axios.defaults.baseURL //可以设置axios的默认请求地址
// 环境的切换 process.env.NODE_ENV是vue.config.js的文件夹下proxy的代理名称
if (process.env.NODE_ENV == 'development') { // 开发环境
  axios.defaults.baseURL = '/api1'
} else if (process.env.NODE_ENV == 'debug') { // 测试环境
  axios.defaults.baseURL = '/api2'
} else if (process.env.NODE_ENV == 'production') { // 生产环境
  axios.defaults.baseURL = '/api3'
}

 axios.defaults.timeout = 10000; // 设置请求超时
// 请求头
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';

// axios.defaults.headers = { // 创建 axios 实例
//   'Content-Type': 'application/json'
// };
// 请求拦截=====请求前的处理//axios设置请求拦截器
axios.interceptors.request.use(config => {
  // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,
  // 不用每次请求都手动添加了  即使本地存在token,也有可能token是过期的,
  // 所以在响应拦截器中要对返回状态进行判断
  const token = store.state.token
  // const token = localStorage.getItem('token')
  // if(token && (config.headers.Authorization = token)){}
  token && (config.headers.Authorization = token) // Authorization令牌
  if ((config.method === 'get' || config.method === 'delete') && config.data) {
    config.url += '?' + objToStr(config.data || {})
  } else if (config.method === 'deleteall') { // 全部删除
    config.method = 'delete'
  } else if (config.method === 'upload') { // 上传
    config.method = 'post'
    config.headers = {'Content-Type' : 'application/x-www-form-urlencoded'} //设置响应头
  }
  if (config.api) {
    config.url = config.api +config.url
  } else {
    config.url = "/api/platform_device" + config.url
  }
  console.log(axios.defaults)
  return config
}, err => {
  if (err.response) {
        const data = err.response.data
        data.message && message.err(data.message)
      }
      console.log(err)
      return Promise.error(err)
})

function objToStr(obj) {
  if (obj && typeof obj === 'object') {
    let urlQuery = ''
    for (const name in obj) {
      urlQuery += name + '=' + obj[name] + '&'
    }
    return urlQuery.slice(0, urlQuery.length - 1)
  } else {
    return ''
  }
}
// 响应的拦截
// 响应拦截器=====请求后的处理
axios.interceptors.response.use((res) => {
  if (res.status === 200 && res.data) {
    if (res.data.status === 200 && res.data.rel) {
      return Promise.resolve(res.data)
    } else {
      res.data.message && message.error(res.data.message)
      return Promise.reject(res.data)
}
  }
  return Promise.reject(res.data)
}, error => { // 服务器状态码不是200的情况
  if (error.response.status) {
    switch (error.response.status) {
      case 401: // 未登录
        router.replace({
          path: '/login',
          query: {
            redirect: router.currentRoute.fullPath
          }
        });
        break;
      case 403: // token过期
        Toast({
          message: '登录过期,请重新登录',
          duration: 1000, // 时长
          forbidClick: true // 不允许点击
        });
        // 清除token
        localStorage.removeItem('token');
        store.commit('loginSuccess', null);
        // 跳转登录页面,并将浏览器的页面fullPath传过去
        // 登录成功之后跳转需要访问的页面
        setTimeout(() => {
          router.replace({
            path: '/login',
            query: {
              redirect: router.currentRoute.fullPath
            }
          })
        }, 1000);
        break;
      case 404: // 请求不存在
        Toast({
          message: '网络请求不存在',
          duration: 1500,
          forbidClick: true
        })
        break;
      default: // 其他的错误
        Toast({
          message: error.response.data.message,
          duration: 1500,
          forbidClick: true
        })
    }
    return Promise.reject(error.response)
  }
})

export {
  axios, QS
}

好了,剩下的就是封装api接口了*
在这里插入图片描述

api.js 文件**

// api.js用来统一管理我们的接口
import { axios, QS} from './index' //引入qs模块,用来序列化post类型的数据

// 获取设备列表-分页
export function facilityPageList(params) {
  return axios({
    url: '/device/myEquipment/queryMyEquipmentPage',
    method: 'post',
    data: params
    // headers: {
    //   'Content-Type': 'application/x-www-form-urlencoded'
    // }
  })
}

// 或者写成下边的样子

/**
 * get方法,对应get请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
 export function get(url, params){
  return new Promise((resolve, reject) =>{
      axios.get(url, {
          params: params
      })
      .then(res => {
          resolve(res.data);
      })
      .catch(err => {
          reject(err.data)
      })
  });
}
/**
* post方法,对应post请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
*/
export function post(url, params) {
  return new Promise((resolve, reject) => {
      axios.post(url, QS.stringify(params))
      .then(res => {
          resolve(res.data);
      })
      .catch(err => {
          reject(err.data)
      })
  });
}

可以直接拿走用。

相关文章:

  • 开机自启动redis
  • 在一个div标签中平行放置两个echarts 环形图
  • node-webkit,html打包成桌面应用,pc应用
  • 【HTML5】Web存储
  • 利用 vuex写一个todoList
  • Java日志组件2---Log4j(org.apache.log4j.Logger)
  • react项目搭建
  • mybatis3.0 配置等值连接两种方式:resultMap和resulttype
  • react官方脚手架安装
  • 怎么用ChemDraw 15.1 Pro绘制彩色结构
  • react实现打印功能
  • 关于CreateProcess函数一些经验
  • 前端解决跨域 cors
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 斐波那契数列 的计算规则
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 【翻译】babel对TC39装饰器草案的实现
  • 【刷算法】从上往下打印二叉树
  • Apache Pulsar 2.1 重磅发布
  • EOS是什么
  • ES6 ...操作符
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • JavaScript新鲜事·第5期
  • JavaScript中的对象个人分享
  • React Transition Group -- Transition 组件
  • Vue.js-Day01
  • vue-router 实现分析
  • 多线程 start 和 run 方法到底有什么区别?
  • 构造函数(constructor)与原型链(prototype)关系
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 手机端车牌号码键盘的vue组件
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 优化 Vue 项目编译文件大小
  • 走向全栈之MongoDB的使用
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • # 安徽锐锋科技IDMS系统简介
  • (1)(1.11) SiK Radio v2(一)
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (SpringBoot)第七章:SpringBoot日志文件
  • (ZT)薛涌:谈贫说富
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (第27天)Oracle 数据泵转换分区表
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)计算机毕业设计大学生兼职系统
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (十一)图像的罗伯特梯度锐化
  • (小白学Java)Java简介和基本配置
  • (转)平衡树
  • (转载)从 Java 代码到 Java 堆
  • (转载)虚函数剖析
  • ./和../以及/和~之间的区别