前期回顾
vite + vue3 + ts配置《企业级项目》二次封装el-table、分页_0.活在风浪里的博客-CSDN博客封装的功能有哪些?分页、表格排序、文字居中、溢出隐藏、操作列、开关、宽、最小宽、type类型(selection/index/expand)、格式化 、不同页面不同操作列、vuex、vue持久化插件、(此处没有接口所以用到,还涉及了query与params传值区别)子组件说思路:data数据请求接口拿到,表头数据一般也是后台接口,如没,前台可自定义自己写......https://blog.csdn.net/m0_57904695/article/details/125613767?spm=1001.2014.3001.5501
目录
前言
我要实现什么效果?
代码简单吗?
念及此
一、封装axiso前先配置环境变量
第一步: 配置环境变量
第二步:封装axios
二:封装loading
loading.vue
index.ts
在main.ts引入index.ts
三:封装返回顶部
MyBackTop.vue
index.ts
在main.ts引入index.ts
结语
全局封装一次!
项目中切换路由显示loading,
发起axios显示loading,
每个页面显示返回顶部
极简
在根目录新建三个文件
.env.development
NODE_ENV='development'
.env.production
NODE_ENV='production'
.env.staging
NODE_ENV='production'
完成!
解释:
正文:
一:先写baseUrl.js 匹配环境变量
let baseURL = "";
if (process.env.NODE_ENV === "development") {
// 开发环境 因为我这里写了配置跨域的重定路径所以是api 如下图
baseURL = "/api";
} else if (process.env.NODE_ENV === "production") {
// 正式环境 真正的上线网址 不是跨域别名路径,在network不显示
baseURL = "";
} else {
// 测试环境
baseURL = "";
}
export default baseURL;
二: 网址配好后写 http.js 创建axiso实例
import axios from "axios";
// 导入element-ElMessage 弹框
// import { ElMessage } from "element-plus";
// 导入配置的环境变量url
import baseURL from "./baseURL";
// 导入路由,没有this,使用路由实例跳转
import router from "../route/router.ts";
// 导入main全局配置文件
import app from "../../src/main";
// 开启loading
app.config.globalProperties.$loading.showLoading();
// 创建axios实例
const http = axios.create({
baseURL, //配置了跨域,起了别名api,在baseBUL用了别名,这里使用baseURL,配置在下面vue.config.js
timeout: 6000,
withDirectives: true, // 是否携带cookies
});
// 请求拦截
http.interceptors.request.use(
(config) => {
// 在请求发送之前做一些处理 config是axios的配置对象
// console.log(config);
// 携带token
config.headers["Authorization"] =
"Bearer " + JSON.parse(localStorage.getItem("remember_token")) || null;
// 配置完成将config返回
return config;
},
(err) => {
// 当请求失败时做一些处理 抛出错误
throw new Error(err);
}
);
// 响应拦截
http.interceptors.response.use(
(res) => {
// 在返回响应之前做一些处理 res是axios的配置对象
// console.log(res);
// 关闭loading
app.config.globalProperties.$loading.hideLoading();
// 根据后台状态码统一封装提示信息 就不需要在页面接口在单独写了
// 这里根据实际接口的嵌套情况和状态码来写 这里只是我的接口嵌套情况
let { status, msg } = res.data.meta;
//key = value status等于200就执行200下的代码 执行完break退出循环
switch (status) {
case 200:
ElMessage({
showClose: true,
message: msg,
type: "success",
});
break;
case 401:
ElMessage({
showClose: true,
message: "未授权",
type: "error",
});
// console.log(this);
// this是undefined所以引入路由;
router.push("/login"); //未授权跳转到login
break;
}
// 这里根据接口返回的数据嵌套结构来返回 比如我的接口返回的是{data:{message:{}}}
return res.data.message;
},
(err) => {
// 当响应失败时做一些处理 抛出错误
throw new Error(err);
}
);
// 导出 http实例 方便调用
export default http;
三:请求封装好了 封装请求方法 request.js
import http from "./http";
// post请求: 传参数没有明确规定使用params接受参数就是要使用data请求体接受,get请求要使用params接受
// put 也相当与post请求,如果报参数错误,就是接受参数的请求体错了post/put用data,get请求用params
function request({ method = 'get', url, data = {}, params = {} }) {
return http({
method,
url,
data,
params
})
}
export default request;
四:请求方法好了 封装api.js
// 导入请求的方法
// 不使用箭头函数
// export function home() {
// return request({ url: '/home', })
// }
import request from "./request";
// 用户登陆的接口 post请求使用data请求体 默认封装的get 如果是get请求不需要写methiod
export const login = (data) => request({ method: "post", url: '/login', data: data });
// 获取用户列表的接口 ,需要有默认参数. pagenum: 1,pagesize: 10,,所以要接收,
export const getUserList = (params) => request({ url: '/users', params });
// put请求修改用户id users/:uId/state/:type
export const getEdit = (data) => request({
method: "put",
data,
url: "users/" + data.uid + "/state/" + data.type,
})
export const order = () => request({ url: "/home/floordata" });
在src下的 components 新建 俩个文件
疯狂加载中...
import { createApp } from "vue";
// 导入写好的Loading.vue文件
import Loading from "./Loading.vue";
export default {
loading: null,
/* 每当这个插件被添加到应用程序中时,如果它是一个对象,就会调用 install 方法。
如果它是一个 function,则函数本身将被调用。在这两种情况下——它都会收到两个参数:由 Vue 的 createApp 生成的 app 对象和用户传入的选项。 */
install(app) {
if (this.loading) {
// 防止多次载入
app.config.globalProperties.$loading = this.loading;
return;
}
// 创建Loading实例,用于挂载
let instance = createApp(Loading);
// 创建div元素装载Loading对象
let div = document.createElement("div");
let body = document.body;
// 导入body中
body.appendChild(div);
this.loading = instance.mount(div);
// 挂载vue身上
app.config.globalProperties.$loading = this.loading;
},
};
// 自定义loading组件 import Loading from "./components/MyLoading/index.ts"; app.use(Loading); export default app; // 这里导出app的目的,是为了在后面演示js文件中使用插件
封装完成,现在 在请求拦截前和路由跳转前 开启一下全局生效
router.ts
router.beforeEach((to, from, next) => { if (to.meta.loading) { app.config.globalProperties.$loading.showLoading(); next(); } else { next(); } }); router.afterEach((to, from) => { if (to.meta.loading) { app.config.globalProperties.$loading.hideLoading(); } });
封装请求loading完成
在src 的components 下新建 俩个文件
import { createApp } from "vue";
import BackTop from "./MyBackTop.vue";
export default {
BackTop: null,
install(app) {
if (this.BackTop) {
app.config.globalProperties.$BackTop = this.BackTop;
return;
}
let instance = createApp(BackTop);
let div = document.createElement("div");
let body = document.body;
body.appendChild(div);
this.BackTop = instance.mount(div);
app.config.globalProperties.$BackTop = this.BackTop;
},
};
// 自定义回到顶部组件 import BackTop from "./components/MyBackTop/index.ts" app.use(BackTop); export default app; // 这里导出app的目的,是为了在后面演示js文件中使用插件
目前为止我们实现了 axios封装 loading 封装 返回顶部封装 !本人亲测保证能用