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

【第5期】前端Vue使用Proxy+Vuex(store、mutations、actions)跨域调通本地后端接口

本期简介

  • 本期要点
  1. 本地开发前后端如何跨域调用
  2. 全局请求、响应处理拦截器处理
  3. 封装HTTP请求模块
  4. 编写API请求映射到后端API
  5. 数据的状态管理

一、 本地开发前后端如何跨域调用

众所周知,只要前端和后端的域名或端口不一样,就存在跨域访问,例如:前端运行后通过http://localhost:3000访问,后端运行后通过http://localhost:8080访问,就存在跨域,跨域直接http调用会失败,因此要解决跨域访问,需要使用proxy

  • proxy配置跨域访问
    proxyTable: {'/api': {target: 'http://127.0.0.1:8080/api',changeOrigin: true,pathRewrite: {'^/api': ''}},'/login': {target: 'http://127.0.0.1:8080/login',changeOrigin: true,pathRewrite: {'^/login': ''}}},
  • /api: 代理路径

    用过nginx的比较容易理解,含义是类似的,当前端调用的接口路径以/api/xxx形式,会命中这条代理规则

  • target: 代理的目标地址

    代理的后端地址,比如前端访问http://127.0.0.1:3000/api/v1/division,那么会代理到后端的http://127.0.0.1:8080/api/v1/division

  • changeOrigin: 是否开启代理
  • pathRewrite: 路径改写

    如果前端访问的是/api/v1/division,后端的接口是/api/v1/division,若上面的pathRewrite写法是’^/api’: ‘api’,那么代理到的目标地址是http://127.0.0.1:8080/api/api/vi/division,因此路径改写需结合target写法以及后端实际接口地址进行改写

通过配置proxyTable,就具备了跨域请求,全栈开发就可以直接本地的前端调用本地的后端接口服务,接下来进行全局的请求响应处理

二、全局请求、响应处理拦截器处理

几乎每个项目都会在所有的请求之前做一些公共的配置或操作,也会在所有的响应中做一些统一数据结构的封装或其他操作

1、全局请求拦截器

Vue请求拦截器可以在所有请求发送到后端之前做一些处理,前后端分离常见的比如设置token

创建src/util/request.js

  • 跨域配置导入
import config from '@/config';
  • 创建axios实例
const _axios = axios.create(config);
  • 请求拦截器
_axios.interceptors.request.use(config => {// 请求前设置tokenlet authKey = 'X-Auth-Token';let token = localStorage.getItem(authKey);if (token) {config.headers[authKey] = token;}return config;},err => {return Promise.reject(err);}
);

2、全局响应拦截器

同样在src/util/request.js中配置全局响应拦截器,这里的逻辑有

    1. 从请求头中获取X-Auth-Token,若有,缓存到localStorage中,便于在请求拦截器中每次携带到请求中,能获取到Token主要是登录的时候会返回,其他接口请求不会返回
    1. 异常捕获时,若响应码是403禁止访问类的,则重定向到登录页,这样无需在其他请求是时单独再做这类处理。
    1. 其他:有的后端接口是不同人开发的,也可能会跨项目进行接口调用,每个接口调用很多时候记不清是什么数据结构,为了前端业务使用统一的结构,一般会在响应中将数据结构进行统一
_axios.interceptors.response.use(res => {// 这里处理响应let token = res.headers.get('X-Auth-Token');if (token) {console.log(token);localStorage.setItem('X-Auth-Token', token);}return res;},err => {if (err) {console.log(err);let title = '错误码: ' + (err.response.status || err.response.data.code);let msg = (err.response.data.msg || err.response.statusText);if (err.response.data.code === 403) {router.push('/Login');} else {notice.error(title, msg);return Promise.reject(err);}}}
);

三、封装HTTP请求模块

在src/util/request.js中创建GET、POST、PUT等抽象方法,并导出http,在其他地方可以import后使用

1、封装GET请求

const http = {get (url, params) {return new Promise((resolve, reject) => {_axios({url,params,headers: {'Content-Type': 'application/json;charset=UTF-8'},method: 'GET'}).then(res => {resolve(res.data);return res;}).catch(err => {reject(err);});});}
};export default http;

2、封装POST请求

const http = {post (url, body) {return new Promise((resolve, reject) => {_axios({url,data: body || {},headers: {'Content-Type': 'application/json;charset=UTF-8'},method: 'POST'}).then(res => {resolve(res.data);return res;}).catch(err => {reject(err);});});},
};export default http;

3、封装PUT请求

const http = {put (url, body) {return new Promise((resolve, reject) => {_axios({url,data: body || {},headers: {'Content-Type': 'application/json;charset=UTF-8'},method: 'PUT'}).then(res => {resolve(res.data);return res;}).catch(err => {reject(err);});});}
};export default http;

四、编写API请求映射到后端API

前面封装的http各种请求与业务无关,是抽象封装的,接下来创建业务调用模块

1、创建src/api/apis.js业务请求的接口文件

  • 导入封装的http请求文件
import http from '@/util/request';
  • 以业务功能为单位定义请求模块

const division = {};
const login = {};
const user = {};

2、定义业务请求

division.getFlatCities = () => {return http.get('/api/v1/division/flat_cities',{});
};user.register = (data) => {return http.post('/api/v1/register',data);
};login.login = (data) => {return http.post('/login',data);
};login.logout = () => {return http.post('/api/v1/logout');
};

这样,在其他地方import apis from ‘@/src/api/apis’后就可以调用业务后端请求了,这样可以统一在apis.js中配置前端到后端的请求映射,单独在vue组件中使用axios也可以直接调用接口,只是这样非常的不友好。

五、数据的状态管理

有时候,我们需要把后端接口请求到的数据缓存起来,在其他各个vue组件中使用,那么这里就会有额外的操作(本地数据缓存),为了统一,我们使用vuex中的actions来封装一下请求后端接口的逻辑,举例:获取行政区划的平铺数据
刚刚apis.js的定义是这样:

division.getFlatCities = () => {return http.get('/api/v1/division/flat_cities',{});
};

1、store

我们在src/vuex/store.js中添加一个变量,用于记录行政区划的平铺数据:

import Vue from 'vue';
import Vuex from 'vuex';
import * as actions from './actions';
import * as mutations from './mutations';
import * as getters from './getters';export default new Vuex.Store({state: {flatCities: {},}
}

2、mutations

然后在/src/vuex/mutations.js中创建修改store.state.flatCities的方法,理论上,mutations是唯一能修改store.state的方式,参数一就是store.state,参数二是调用SET_FLAT_CITIES方法的入参

export const SET_FLAT_CITIES = (state, flatCities) => {state.flatCities = flatCities;
};

3、actions

继续在/src/vuex/actions.js中定义含缓存操作的业务请求方法


export const loadFlatCities = ({commit, state}) => {let cacheData = localStorage.getItem('flatCities');if (cacheData) {// 有缓存,直接取缓存commit('SET_FLAT_CITIES', JSON.parse(cacheData));} else {apis.division.getFlatCities().then(res => {commit('SET_FLAT_CITIES', res.body);localStorage.setItem('flatCities', JSON.stringify(res.body));});}
};

4、…mapActions

vue组件中通过…mapActions映射到loadFlatCities方法
vue组件中从vuex引入mappActions

import {mapState, mapActions} from 'vuex';

通过…mapActions中添加loadFlatCities将其映射进来,这样就可以通过this.loadFlatCities()进行调用,和methos()中定义的方法调用方式一样。

methods: {...mapActions(['logout', 'isLogin', 'loadFlatCities', 'autoLocation', 'changeCurrentLocation']),showLocation () {this.isShowLocation = true;},省略

5、$store.state.xxx读取数据状态

当在组件的created()中调用了this.loadFlatCities()时,localStorage和$store.state.flatCities都有后端返回的行政区划平铺,可以直接在组件中进行渲染了。

<div v-for="(flatDivision, fIndex) in $store.state.flatCities" :key="fIndex"><Row> <Col span="1"><div class="province-first-letter">{{ flatDivision.letter }}</div></Col><Col span="23"><div v-for="(province, index) in flatDivision.provinces" class="province-item" :key="index"><Row><Col span="1">{{ province.shortName }}</Col><Col span="23"><span v-for="(ct, index) in province.children" :key="index" class="city-item"@click="changeCity(province, ct)">{{ ct.shortName }}</span></Col></Row></div></Col></Row>
</div>

6、行政区划平铺渲染效果

在这里插入图片描述

相关文章:

【第5期】前端Vue使用Proxy+Vuex(store、mutations、actions)跨域调通本地后端接口

本期简介 本期要点 本地开发前后端如何跨域调用全局请求、响应处理拦截器处理封装HTTP请求模块编写API请求映射到后端API数据的状态管理 一、 本地开发前后端如何跨域调用 众所周知&#xff0c;只要前端和后端的域名或端口不一样&#xff0c;就存在跨域访问&#xff0c;例如&…...

在Visual Studio(VS)编译器中,Release和Debug区别

一、 优化级别 1、Debug&#xff08;调试&#xff09; 在Debug模式下&#xff0c;编译器不会对代码进行优化&#xff0c;而是专注于生成易于调试的代码。这使得开发者可以在调试过程中更直观地跟踪变量的值和程序的执行流程。 2、Release&#xff08;发布&#xff09; 在Relea…...

子网划分问题(实战超详解)_主机分配地址

文章目录: 子网划分的核心思想 第一步,考虑借几位作为子网号 第二步,确定子网的网络地址 第三步,明确网络地址,广播地址,可用IP地址范围 一些可能出现的疑问 实战 题目一 子网划分的核心思想 网络号不变,借用主机号来产生新的网络 划分前的网络:网络号主机号 划分后的网络:原网…...

【QT】单例模式,Q_GLOBAL_STATIC 宏的使用和使用静态成员函数,eg:{简单的日志记录器}

简单的日志记录器为例 。 创建一个Logger类&#xff0c;该类负责记录应用程序的日志消息 使用 Q_GLOBAL_STATIC 宏 解析&#xff1a;Q_GLOBAL_STATIC 是一个 Qt 宏&#xff0c;用于创建全局静态实例。它确保在需要时只创建一次实例&#xff0c;而不管该实例是在哪个线程中创建…...

利用小红书笔记详情API:构建高效的内容创作与运营体系

随着社交媒体的兴起&#xff0c;小红书作为国内知名的内容分享平台&#xff0c;吸引了大量用户和内容创作者。为了更好地获取小红书上的优质内容&#xff0c;许多企业和开发者选择使用小红书笔记详情API。本文将探讨如何利用该API构建高效的内容创作与运营体系。 一、小红书笔记…...

【K8S 二进制部署】部署单Master Kurbernetes集群

目录 一、基本架构和系统初始化 1、集群架构&#xff1a; 2、操作系统初始化配置&#xff1a; 2.1、关闭防火墙和安全机制&#xff1a; 2.2、关闭swap 2.3、根据规划设置主机名 2.4、三台主机全部互相映射 2.5、调整内核参数 3、时间同步&#xff08;所有节点时间必须同…...

vue中常见的指令

简单介绍一下常见的vue中用到的指令 v-on 指定当前的事件&#xff0c;语法糖为&#xff0c;如例子所示&#xff0c;指定按钮的事件为addCounter&#xff0c;点击会使变量counter 1 <!DOCTYPE html> <html><head><meta charset"utf-8" />…...

单片机原理及应用:开关控制LED多种点亮模式

从这篇文章开始&#xff0c;我们不再只研究单一的外设工作&#xff0c;而是将LED、数码管、开关、按键搭配在一起研究&#xff0c;这篇文章主要介绍LED和开关能擦出怎样的火花&#xff0c;同时也介绍一些函数封装的知识。 由于开关有闭合与打开两种状态&#xff0c;LED有左移流…...

你真的了解UVM sequence的运行机制吗

1. 前言 UVM在sequence里提供了很多的callback方法给用户&#xff0c;从而更灵活地完成各种复杂场景的交互和控制执行顺序。我们可能在很多情况下只使用了body()方法&#xff0c;本文将介绍sequence里常见的callback方法&#xff0c;以及在不同场景下&#xff0c;它们的是否被…...

Bug升级记

2023.12.28 &#xff08;1) 小程序session_key泄露隐患 核心&#xff1a;session_key这个字段及对应值不应该传到小程序客户端等服务器外的环境 错误操作&#xff1a;直接在小程序调用https://api.weixin.qq.com/sns/jscode2session并将session_key作为参数进行明文传输 正确操…...

爬虫详细教程第1天

爬虫详细教程第一天 1.爬虫概述1.1什么是爬虫&#xff1f;1.2爬虫工具——Python1.3爬虫合法吗&#xff1f;1.4爬虫的矛与盾1.4.1反爬机制1.4.2反爬策略1.4.3robots.txt协议 2.爬虫使用的软件2.1使用的开发工具: 3.第一个爬虫4.web请求4.1讲解一下web请求的全部过程4.2页面渲染…...

[Linux] MySQL数据库的备份与恢复

一、数据库备份的分类和备份策略 1.1 数据库备份的分类 1&#xff09;物理备份 物理备份&#xff1a;对数据库操作系统的物理文件&#xff08;如数据文件、日志文件等&#xff09;的备份。 物理备份方法&#xff1a; 冷备份(脱机备份) &#xff1a;是在关闭数据库的时候进…...

Django、Python版本升级问题大汇总

Django3.0升级到4.1,Python3.8升级到3.11.6问题大汇总 报错1:ERROR: Could not build wheels for cffi, uWSGI, which is required to install pyproject.toml-based projects ERROR: Could not build wheels for cffi, uWSGI, which is required to install pyproject.tom…...

2023-12-30 AIGC-LangChain介绍

摘要: 2023-12-30 AIGC-LangChain介绍 LangChain介绍 1. https://youtu.be/Ix9WIZpArm0?t353 2. https://www.freecodecamp.org/news/langchain-how-to-create-custom-knowledge-chatbots/ 3. https://www.pinecone.io/learn/langchain-conversational-memory/ 4. https://de…...

pytorch01:概念、张量操作、线性回归与逻辑回归

目录 一、pytorch介绍1.1pytorch简介1.2发展历史1.3pytorch优点 二、张量简介与创建2.1什么是张量&#xff1f;2.2Tensor与Variable2.3张量的创建2.3.1 直接创建torch.tensor()2.3.2 从numpy创建tensor 2.4根据数值创建2.4.1 torch.zeros()2.4.2 torch.zeros_like()2.4.3 torch…...

storyBook play学习

场景 在官方给出的案例中&#xff0c; Page.stories.js import { within, userEvent } from storybook/testing-library import MyPage from ./Page.vueexport default {title: Example/Page,component: MyPage,parameters: {// More on how to position stories at: https:/…...

Android Matrix画布Canvas旋转Rotate,Kotlin

Android Matrix画布Canvas旋转Rotate&#xff0c;Kotlin private fun f1() {val originBmp BitmapFactory.decodeResource(resources, R.mipmap.pic).copy(Bitmap.Config.ARGB_8888, true)val newBmp Bitmap.createBitmap(originBmp.width, originBmp.height, Bitmap.Config.…...

私有部署ELK,搭建自己的日志中心(三)-- Logstash的安装与使用

一、部署ELK 上文把采集端filebeat如何使用介绍完&#xff0c;现在随着数据的链路&#xff0c;继续~~ 同样&#xff0c;使用docker-compose部署&#xff1a; version: "3" services:elasticsearch:container_name: elasticsearchimage: elastic/elasticsearch:7.9…...

2023就这样过去了,2024会更好吗?

2023年&#xff0c;不是很好 2023年是疫情后的第一年&#xff0c;疫情过去了&#xff0c;大家都有大多的希望&#xff0c;希望经济可以恢复&#xff0c;希望信心可以恢复&#xff0c;但是整体都是远远低于预期的。年初的一片热潮&#xff0c;年中的一片哀嚎&#xff0c;年底基…...

SpringBoot加载配置的6种方式

从配置文件中获取属性应该是SpringBoot开发中最为常用的功能之一&#xff0c;简单回顾一下这六种的使用方式&#xff1a; 说明Environment对象Environment是springboot核心的环境配置接口&#xff0c;它提供了简单的方法来访问应用程序属性&#xff0c;包括系统属性、操作系统…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...