目录
(一)、使用 axios 和 Vuex 对 Vue.js 项目从后台获取数据流程
一、知识点回顾:
(一)、使用 axios 和 Vuex 对 Vue.js 项目从后台获取数据流程
使用 axios 和 Vuex 可以对 Vue.js 项目从后台获取数据的具体流程如下:
1、代理跨域:
2、封装 Axios 请求模块:在项目中创建统一的 axios 请求模块,实现请求拦截器、响应拦截器、全局错误处理等功能,并提供请求方法供组件调用。
3、 定义 Vuex 状态管理模块:在 Vuex 中定义状态管理模块,以便能够在不同组件之间共享数据、方便管理数据状态和简化开发。
4、在 Vuex 中进行异步请求:在 Vuex 的 actions 中使用封装好的 axios 请求模块发送异步请求,并将请求结果通过 mutations 存储到 state 中;在 getters 中定义对于 state 中数据的计算属性方法,供组件使用。
5、在组件中获取 Vuex 中的数据:组件中通过调用 Vuex 的 actions 中的方法来触发数据请求,在组件中使用 computed 属性获取 Getter 中的计算属性获取数据。
6、在组件中进行数据渲染:组件中通过 template 或者 render 函数进行数据渲染,从而在页面上显示数据。
通过使用 axios 和 Vuex 进行优化,可以有效地提高代码的可维护性和复用性,同时还能够方便地进行状态管理和数据跟踪等操作。此外,Vuex 还支持模块化、热重载、插件机制等功能,使得开发更加便利和高效。
二、代理跨域问题
跨域指的是在浏览器中,由于安全策略的限制,一个网页无法通过 AJAX 请求访问非同源的资源。所谓同源是指,两个网址的协议、主机名和端口号全部相同,即使路径不同也被当成不同源。例如,对于页面 http://www.example.com/index.html,它只能发送到同一域名下的网址,例如 http://www.example.com/other.html,而不能发送到 https://www.other.com/index.html。
代理跨域则是一种常见的跨域解决方案。简单来说,就是在服务端进行转发,将跨域请求转换为同源请求。
针对跨域问题,我们可以在 vue.config.js 中配置代理
在 vue.config.js 文件中,我们可以通过 devServer.proxy 属性设置代理来解决跨域问题。例如,我们想要访问后端接口 /api
,则可以按照如下方式进行配置:
module.exports = {
// 关闭eslint
lintOnSave: false,
// 代理跨域
devServer: {
proxy: {
'/api': {
//要访问的跨域的域名
target:'http://gmall-h5-api.atguigu.cn',
}
}
}
}
三、 封装 Axios 请求模块
1、安装依赖
首先,需要在项目中安装 axios 和 Vuex 库。
npm install axios vuex --save
2、封装 axios 请求方法
在 src/utils/request.js 中添加代理地址,由于我们在 vue.config.js
中配置了代理,所以在发送请求时需要将请求地址进行处理。
import axios from "axios";
//引入进度条
import store from "@/store";
//1、对axios二次封装
let requests = axios.create({
//基础路径,requests发出的请求在端口号后面会跟改baseURl
baseURL: '/api',
timeout: 5000,
})
//2、配置请求拦截器
requests.interceptors.request.use(config => {
//config内主要是对请求头Header配置
if (store.state.detail.uuid_token) {
// 请求头添加一个字段(userTempId)和后台设计一致
config.headers.userTempID = store.state.detail.uuid_token;
}
//需要携带token带给服务器
if (store.state.user.token) {
config.headers.token = store.state.user.token;
}
nprogress.start();
return config;
})
//3、配置相应拦截器
requests.interceptors.response.use((res) => {
//响应成功,关闭进度条
nprogress.done()
return res.data;
}, (error) => {
//失败的回调函数
console.log("响应失败" + error)
return Promise.reject(new Error('fail'))
})
//4、对外暴露
export default requests;
3、在 api 目录下的文件中添加请求地址
在 api 目录下api/index.js的对应文件中,我们需要添加请求地址头部,这样发送请求时才能正确地匹配到代理地址。
//当前模块,API进行统一管理,即对请求接口统一管理
import requests from "@/api/request";
//首页三级分类接口
export const reqCateGoryList = () => mockRequests.get('/categorylist');
// 获取广告轮播列表
export const reqGetBannerList = () =>mockRequests.get('/banners');
// 获取首页楼层列表
export const reqGetFloorList = () => mockRequests.get('/floors');
四、Vuex 状态管理模块
1、安装vuex
npm i vuex@3
2、在入口文件main.js引入总仓库并注册
//引入仓库
import store from '@/store';
new Vue({
render: h => h(App),
// 全局事件总线$bus配置
beforeCreate(){
Vue.prototype.$bus = this;
Vue.prototype.$API = API;
},
//需要将router进行注册
router,
// 注册仓库
store
}).$mount('#app')
3、定义 Vuex 状态管理模块:
在store/index.js 中定义状态管理模块,以便能够在不同组件之间共享数据、方便管理数据状态和简化开发。
import Vue from "vue";
import Vuex from 'vuex';
// 需要使用插件一次、
Vue.use(Vuex);
// 引入home小仓库
import home from "./home";
// 对外暴露Store类的一个实例
export default new Vuex.Store ({
// 实现Vuex仓库模块式开发存储数据
modules:{
home,
}
});
4、引入小仓库store/home.js
import { reqCateGoryList, reqGetBannerList, reqGetFloorList } from "@/api";
// state【仓库当中的商品】 (提供唯一的公共数据源)数据状态
const state = {
// state 中数据默认初始值
categoryList: [],
// 轮播图的数组
bannerList: [],
// floor组件数据
floorList: []
};
// mutations【操作商品的工人】 函数,同步操作(用于变更store中的数据)不能执行异步操作,延时器
const mutations = {
CATEGORYLIST(state, categoryList) {
state.categoryList = categoryList;
},
GETBANNERLIST(state, bannerList) {
state.bannerList = bannerList;
},
GETFLOORLIST(state, floorList) {
state.floorList = floorList;
},
};
// actions【发送命令的老板】 用于处理异步任务,必须通过context.commit()触发某个mutations方式间接的变更数据。
const actions = {
// 通过API里面的接口函数调用,向服务器发请求,获取服务器的数据
async categoryList({ commit }) {
let result = await reqCateGoryList()
if (result.code == 200) {
commit("CATEGORYLIST", result.data);
}
},
// 获取首页轮播图的数据
async getBannerList({ commit }) {
let result = await reqGetBannerList();
if (result.code == 200) {
commit("GETBANNERLIST", result.data);
}
},
// 获取floor数据
async getFloorList({ commit }){
let result = await reqGetFloorList();
if (result.code == 200) {
commit("GETFLOORLIST", result.data);
}
}
};
// getters【二次加工】 (用于对store中的数据进行加工处理形成新的数据)(不会修改state中的数据)
const getters = {};
export default {
state,
mutations,
actions,
getters
}
五、在组件中获取 Vuex 中的数据
这个时候home仓库已经有了相应的数组,但是我们需要在TypeNav组件(home中三级联动组件)中拿到数据并进行展示
进入到TypeNav组件当中,用mapState
去获取组件中的数据
//组件挂载完毕可以向服务器发请求
mounted () {
// 异步获取所有分类列表数据
// this.$store.dispatch('getBaseCategoryList') // 在App组件中执行, 减少请求的次数
},
computed: {
// 从vuex管理的state中读取数据到当前组件
...mapState({
// 读取home模块的所有分类数组
categoryList: state => state.home.categoryList
})
},
六、在组件中进行数据渲染