Vue3 中使用axios

1.安装axios、js-cookie、pinia

axios命令行:

npm install axios

js-cookie命令行:

npm install js-cookie

store命令行:

npm install pinia

2.配置文件

(1)缓存文件配置

src/plugins/auth.js

const sessionCache = {set (key, value) {if (!sessionStorage) {return}if (key != null && value != null) {sessionStorage.setItem(key, value)}},get (key) {if (!sessionStorage) {return null}if (key == null) {return null}return sessionStorage.getItem(key)},setJSON (key, jsonValue) {if (jsonValue != null) {this.set(key, JSON.stringify(jsonValue))}},getJSON (key) {const value = this.get(key)if (value != null) {return JSON.parse(value)}},remove (key) {sessionStorage.removeItem(key);}
}
const localCache = {set (key, value) {if (!localStorage) {return}if (key != null && value != null) {localStorage.setItem(key, value)}},get (key) {if (!localStorage) {return null}if (key == null) {return null}return localStorage.getItem(key)},setJSON (key, jsonValue) {if (jsonValue != null) {this.set(key, JSON.stringify(jsonValue))}},getJSON (key) {const value = this.get(key)if (value != null) {return JSON.parse(value)}},remove (key) {localStorage.removeItem(key);}
}export default {/*** 会话级缓存*/session: sessionCache,/*** 本地缓存*/local: localCache
}

(2)js-cookie文件配置

src/utils/auth.js

import Cookies from 'js-cookie'const TokenKey = 'Admin-gis-jcpt-Token'export function getToken() {return Cookies.get(TokenKey)
}export function setToken(token) {return Cookies.set(TokenKey, token)
}export function removeToken() {return Cookies.remove(TokenKey)
}

(3)axios文件配置

src/utils/axiosHttp.js

import axios from "axios";
import { getToken } from '@/utils/auth';
import cache from '@/plugins/cache';
import store from "@/store";axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';// 传参方式json
//axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded';//传参方式表单
// 设置接口超时时间
const timeout = 60000;
// 设置请求地址
const baseURL = 'http://192.168.1.167:8080/gis_jcpt';// 创建axios实例
const service = axios.create({// axios中请求配置有baseURL选项,表示请求URL公共部分//baseURL: process.env.VUE_APP_BASE_API,baseURL:baseURL,// 超时timeout: timeout})// http request 请求拦截器
service.interceptors.request.use(config =>{// 是否需要设置 tokenconst isToken = (config.headers || {}).isToken === false// 是否需要防止数据重复提交const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;if (getToken() && !isToken) {//console.log("getToken",getToken());config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改}// get请求映射params参数if (config.method === 'get' && config.params) {let url = config.url + '?' + tansParams(config.params);url = url.slice(0, -1);config.params = {};config.url = url;}if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {const requestObj = {url: config.url,data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,time: new Date().getTime()}const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小const limitSize = 5 * 1024 * 1024; // 限制存放数据5Mif (requestSize >= limitSize) {console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。')return config;}const sessionObj = cache.session.getJSON('sessionObj')if (sessionObj === undefined || sessionObj === null || sessionObj === '') {cache.session.setJSON('sessionObj', requestObj)} else {const s_url = sessionObj.url;                  // 请求地址const s_data = sessionObj.data;                // 请求数据const s_time = sessionObj.time;                // 请求时间const interval = 1000;                         // 间隔时间(ms),小于此时间视为重复提交if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {const message = '数据正在处理,请勿重复提交';console.warn(`[${s_url}]: ` + message)return Promise.reject(new Error(message))} else {cache.session.setJSON('sessionObj', requestObj)}}}return config;},error =>{console.log(error)return Promise.reject(error);}
)// http response 响应拦截器
service.interceptors.response.use(response =>{// 未设置状态码则默认成功状态const code = response.data.code || 200;const msg = response.data.msg || '请求错误';if(code === 401){// 登录状态过期-退出store.dispatch('Logout').then(()=>{location.href = '/';})}else if(code === 500){return Promise.reject(new Error(msg));}else if(code === 601){//return Promise.reject('error');}else if(code !== 200){return Promise.reject('error');    }else {return response.data;}},error =>{console.log('err' + error)let { message } = error;if (message == "Network Error") {message = "后端接口连接异常";} else if (message.includes("timeout")) {message = "系统接口请求超时";} else if (message.includes("Request failed with status code")) {message = "系统接口" + message.substr(message.length - 3) + "异常";}console.log("message",message);return Promise.reject(error)}
)export default service;

登录请求为例:

src/api/login.js

import request  from "@/utils/axiosHttp";// 登录方法
export function login(username, password, code, uuid) {const data = {username,password,code,uuid}return request({url: '/login',headers: {isToken: false,repeatSubmit: false},method: 'post',data: data})}// 获取用户详细信息
export function getInfo() {return request({url: '/getInfo',method: 'get'})}// 退出方法export function logout() {return request({url: '/logout',method: 'post'})}// 获取验证码
export function getCodeImg() {return request({url: '/captchaImage',headers: {isToken: false,},method: 'get',timeout: 20000})}

(4)pinia文件配置:

src/store/index.js

// store/index.js
import { createStore } from 'vuex';
import {login, logout, getInfo} from '@/api/login';
import { getToken, setToken, removeToken } from '@/utils/auth';export default createStore({state: {isLoggedIn: false, // 初始状态为未登录user: null // 存储用户信息},getters: {isLoggedIn: state => state.isLoggedIn,user: state => state.user,},mutations: {SET_TOKEN: (state, token) => {state.token = token},SET_ID: (state, id) => {state.id = id},SET_NAME: (state, name) => {state.name = name},SET_AVATAR: (state, avatar) => {state.avatar = avatar},SET_ROLES: (state, roles) => {state.roles = roles},SET_PERMISSIONS: (state, permissions) => {state.permissions = permissions},setLoginStatus(state, status) {  state.isLoggedIn = status;},setUser(state, user) {state.user = user;}},actions: {Login({ commit }, user) {const username = user.username.trim();const password = user.password;const code = user.code;const uuid = user.uuid;return new Promise((resolve,reject)=>{login(username,password,code,uuid).then(res =>{console.log("res",res);if(res.code === 200){setToken(res.token);commit('SET_TOKEN', res.token);resolve(true);}else{alert(res.data.msg);}}).catch(error =>{reject(error);})})// 执行登录逻辑...//commit('setLoginStatus', true);//commit('setUser', user);//localStorage.setItem('auth', JSON.stringify(user)); // 保存到localStorage},// 获取用户信息GetInfo({ commit, state }) {return new Promise((resolve, reject) => {getInfo().then(res => {const user = res.user// 获取头像//const avatar = (user.avatar == "" || user.avatar == null) ? "@/assets/images/figure-1.png" : process.env.VUE_APP_BASE_API + user.avatar;const avatar = "@/assets/images/figure-1.png"; if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组commit('SET_ROLES', res.roles)commit('SET_PERMISSIONS', res.permissions)} else {commit('SET_ROLES', ['ROLE_DEFAULT'])}commit('SET_ID', user.userId)commit('SET_NAME', user.userName)commit('SET_AVATAR', avatar)resolve(res)}).catch(error => {reject(error)})})},// 退出系统Logout({ commit }) {const logoutToken = {token:getToken(),}return new Promise((resolve,reject)=>{logout(logoutToken).then(() => {commit('SET_TOKEN', '')commit('SET_ROLES', [])commit('SET_PERMISSIONS', [])removeToken()resolve()}).catch(error => {reject(error)})})// 执行登出逻辑...// commit('setLoginStatus', false);// commit('setUser', null);// localStorage.removeItem('auth'); // 从localStorage移除}}
});

 3.使用示例

登录:

***
***
<script setup>
import {onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex';
import { _service } from '@/api';
import { useRequest } from 'alova/client';
import {getCodeImg} from '@/api/login';const router = useRouter()
const store = useStore();
const code = ref('');
const codeUrl = ref('');
const uuid = ref('');
const username = ref('admin');
const password = ref('xxzxadmin');
// 验证码开关
const captchaEnabled = ref('');onMounted(()=>{getCode();
});// 获取验证码
const getCode = async() =>{getCodeImg().then(res => {//console.log("res",res);captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;if (captchaEnabled.value) {codeUrl.value = "data:image/gif;base64," + res.img;uuid.value = res.uuid;}});
}// 登录方法
const loginHandle = () => {// router.push('/')const user = {username: username.value,password: password.value,code: code.value,uuid: uuid.value};store.dispatch('Login', user).then((isLogin) => {if(isLogin){// 登录成功后跳转到首页或其他页面router.push('/index');}}).catch((error) => { console.error('Login failed:', error);alert(error);// 调用获取验证码方法getCode();});}
</script>
***
***

获取用户信息:

onMounted(()=>{// 获取用户信息store.dispatch('GetInfo').then((res)=>{console.log("GetInfo",res);})
})

 

退出:

***
***
<script setup>
import { useRouter } from 'vue-router';
import store from "@/store";const router = useRouter()// 退出按钮
const logout = () =>{// 退出store.dispatch('Logout').then(()=>{// 退出成功后跳转到登录页面//router.push('/');// 跳转到退出页面(当前页面打开URL页面)location.href = '/';})
}</script>
***
***

后台为若依

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/65095.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从AI换脸到篡改图像,合合信息如何提升视觉内容安全?

本文目录 引言一、AI“真假之战”下的发展现状与考验挑战1.1 视觉内容安全现状与技术分类1.2视觉内容安全企业1.3视觉内容安全领域挑战 二、开山之石&#xff1a;引领视觉内容安全的创新之路2.1合合内容安全系统2.2发起编制相关技术规范2.3参与篡改检测挑战赛 三、视觉内容安全…

IBatis和MyBatis在细节上的不同有哪些

iBatis 和 MyBatis 都是流行的 Java 持久化框架&#xff0c;用于简化数据库交互。MyBatis 是从 iBatis 演化而来&#xff0c;MyBatis 在 iBatis 的基础上做了很多改进和优化&#xff0c;因此两者在设计和功能上存在一些差异。以下是它们在细节上的主要区别&#xff1a; 1. 框架…

解决Ubuntu下无法装载 Windows D盘的问题

电脑安装了 Windows 和 Ubuntu 24.04 后&#xff0c;在Ubuntu系统上装载 D盘&#xff0c;发现无法装载错误如下&#xff1a; Error mounting /dev/nvme0n1p4 at /media/jackeysong/Data: wrong fs type, bad option, bad superblock on /dev/nvme0n1p4, missing codepage or h…

STM32-笔记10-手写延时函数(SysTick)

1、什么是SysTick Systick&#xff0c;即滴答定时器&#xff0c;是内核中的一个特殊定时器&#xff0c;用于提供系统级的定时服务。该定时器是一个24位的倒计数定时器‌。它从设定的初值&#xff08;即重载值&#xff09;开始计数&#xff0c;每经过一个系统时钟周期&#xff0…

“AI+Security”系列第4期(一)之“洞” 见未来:AI 驱动的漏洞挖掘新范式

在数字化浪潮下&#xff0c;安全漏洞问题日益严峻&#xff0c;成为各行业发展的重大挑战。近日&#xff0c;“AISecurity” 系列第 4 期线下活动于北京成功举办&#xff0c;聚焦 “洞” 见未来&#xff1a;AI 驱动的漏洞挖掘新范式&#xff0c;汇聚了安全领域的众多专家。 本次…

LeetCode 热题 100_LRU 缓存(35_146_中等_C++)(哈希表 + 双向链表)(构造函数声明+初始化列表=进行变量初始化和赋值)

LeetCode 热题 100_LRU 缓存&#xff08;35_146&#xff09; 题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;代码实现&#xff08;思路一&#xff08;哈希表 双向链表&#xff09;&#xff09;&#xff1a;部分代码解读 题目描述&#xf…

攻防世界 PHP2

开启场景 访问 /index.php&#xff0c;页面无变化 访问 /index.phps index.php 和 index.phps 文件之间的主要区别在于它们的文件扩展名。 index.php&#xff1a;这是一个标准的 PHP 文件&#xff0c;通常用于编写 PHP 代码。当用户访问 index.php 文件时&#xff0c;Web 服务器…

AI应用-本地模型实现AI生成PPT(简易版)

文章目录 前言技术栈效果展示 一、实现思路二、实现步骤1.本地安装marp-cli2.后端实现3.前端实现 三、代码地址及说明 前言 在许多项目中&#xff0c;生成 PPT 是常见的需求&#xff0c;尤其在教育和报告展示中。传统的生成 PPT 的方法需要手动创建&#xff0c;而使用生成模型…

项目2路由交换

背景 某学校为满足日常教学生活需求&#xff0c;推动数字校园的建设&#xff0c;学校有办公楼和学生宿舍楼和服务器集群三块区域&#xff0c;请合理规划IP地址和VLAN&#xff0c;实现企业内部能够互联互通现要求外网能通过公网地址访问服务器集群&#xff0c;学生和老师能正常…

快速掌握Haproxy原理架构

文章目录 一、原理架构二、无负载均衡三、四层负载均衡的工作流程四、七层负载均衡工作流程五、基础属性mode 属性retries 属性maxconn 属性clitimeout 属性servtimeout 属性states uri 属性 一、原理架构 四层tcp代理&#xff1a;Haproxy仅在客户端和服务器之间双向转发流量&…

02、并发编程的三大特性

并发编程有三大特性分别是&#xff0c;原子性&#xff0c;可见性&#xff0c;有序性。会产生这些特性的根本原因是现在的服务器都是多CPU多核心数的&#xff0c;每个CPU都有自己单独的一套缓存和pc系统&#xff0c;而且程序在运行时按照JMM的规范&#xff0c;它们是需要先把数据…

企业数字化转型和人工智能(AI)之间的关系

企业数字化转型和人工智能&#xff08;AI&#xff09;之间的关系可以被理解为 “驱动与支撑” 的关系&#xff1a;AI 是数字化转型的重要技术驱动力&#xff0c;而数字化转型为 AI 的应用提供了场景和数据支持。两者相辅相成&#xff0c;共同推动企业向智能化发展。 数字化转型…

STM32和精准的型号STM32F03C8T6 ——ADC通道数目区别

注意表达方式的区别 5&#xff0e;STM32芯片内部集成的&#xff08;12&#xff09;位ADC是一种逐次逼近型模拟数字转换器&#xff0c;具 有&#xff08;18&#xff09;个通道&#xff0c;可测量&#xff08;16&#xff09;个外部和(2)个内部信号源。 书上原话&#xff1a;STM32…

【项目构建】Gradle入门

本文适用&#xff1a; 不知道什么是项目构建&#xff0c;可以了解下Ant&#xff0c;Maven&#xff0c;Gradle的区别。知道什么是项目构建&#xff0c;了解Ant&#xff0c;Maven&#xff0c;可以看到Gradle是怎么做的。知道什么是项目构建&#xff0c;了解Ant&#xff0c;Maven&…

java栈--数据结构

前言 java实现数据结构栈&#xff1a;用顺序表存储的栈和数组存储的栈。 本文源代码网址&#xff1a;https://gitee.com/zfranklin/java/tree/master/dataStructure/src/com/njupt/stack https://gitee.com/zfranklin/java/tree/master/dataStructure/src/com/njupt/stack 栈…

2.5.2 文件结构、目录及存取

文章目录 文件结构文件目录存取 文件结构 文件结构是文件的组织形式。从用户角度观察到的结构是逻辑结构&#xff0c;从机器实现存储的角度观察&#xff0c;看到的是物理结构。 逻辑结构 有结构的记录式文件&#xff1a;文件中记录的长度都相同&#xff0c;称为定长记录。文件…

Highcharts 饼图:数据可视化利器

Highcharts 饼图&#xff1a;数据可视化利器 引言 在数据可视化的领域中&#xff0c;饼图作为一种经典且直观的图表类型&#xff0c;被广泛应用于各种行业和场景中。Highcharts&#xff0c;作为一个功能强大且易于使用的JavaScript图表库&#xff0c;为我们提供了创建交互式和…

关于科研中使用linux服务器的集锦

文章目录 常用的linux命令下载COCO2017数据集 常用的linux命令 一个文件移动到另一个目录下的命令是&#xff1a;mv -v ./old_name ./new_name 如果目标文件夹中已经有同名文件或文件夹&#xff0c;mv 会覆盖它们&#xff08;除非使用了 -i 选项来提示确认&#xff09;。 使用…

<项目代码>YOLO Visdrone航拍目标识别<目标检测>

项目代码下载链接 &#xff1c;项目代码&#xff1e;YOLO Visdrone航拍目标识别&#xff1c;目标检测&#xff1e;https://download.csdn.net/download/qq_53332949/90163918YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一…

linux命令中cp命令-rf与-a的差别

在Linux系统中&#xff0c;cp 命令用于复制文件和目录。cp -rf 和 cp -a 都常用于递归复制目录及其内容&#xff0c;但它们在功能和行为上存在一些差别&#xff1a; 1. 选项含义 cp -rf&#xff1a; -r&#xff08;recursive&#xff09;&#xff1a;表示递归复制。当源文件是…