辰風依恛
文章35
标签0
分类11
小程序封装抽离

小程序封装抽离

小程序封装抽离

来源于uniapp项目

请求封装

单一路径

原生请求

只针对一个根路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
export const BASE_URL = "https://www.brrfid-pm.cn/WXAPI" // 接口前缀
export const IMAGE_BASE_URL = "https://www.brrfid-pm.cn/WXAPI/image/" // 图片前缀
export const downLoadUrl = "https://www.brrfid-pm.cn/api/download/v2/" // 下载地址
class API {
/**
* 封装的请求
* @param {*} url 请求地址
* @param {*} method 请求类型
* @param {*} data 请求数据
* @param {*} header 请求头
* @param {*} animation
* @returns
*/
request(url, method, data, header = {}, showLoading = true) {
return new Promise((resolve, reject) => {
const token = uni.getStorageSync("token");

if (token) {
header.token = token
}
console.log('请求前数据 :>>', data);
// 请求加载动画
showLoading && uni.showLoading({
title: '加载中'
});


uni.request({
url: BASE_URL + url,
method,
header,
data,
success: (res) => {
console.log('请求后数据 :>> ', res.data);
if (res.data.code == 401) {
uni.navigateTo({
url: '/pages/managerial/login/login',
});
}
resolve(res.data)
},
fail: (err) => {
reject(err)
},
complete: () => {
showLoading && uni.hideLoading();
}
})
})
}

/**
* get请求
* @param {*} url 请求地址
* @param {*} data 请求参数
* @param {*} header 请求头
* @param {*} showLoading 是否执行加载动画
* @returns Promise
*/
get(url, data, header, showLoading) {
return this.request(url, "GET", data, header, showLoading)
}

/**
* post请求
* @param {*} url 请求地址
* @param {*} data 请求参数
* @param {*} header 请求头
* @param {*} showLoading 是否执行加载动画
* @returns Promise
*/
post(url, data, header, showLoading) {
return this.request(url, "POST", data, header, showLoading)
}

/**
* put请求
* @param {*} url 请求地址
* @param {*} data 请求参数
* @param {*} header 请求头
* @param {*} showLoading 是否执行加载动画
* @returns Promise
*/
put(url, data, header, showLoading) {
return this.request(url, "PUT", data, header, showLoading)
}

/**
* delete请求
* @param {*} url 请求地址
* @param {*} data 请求参数
* @param {*} header 请求头
* @param {*} showLoading 是否执行加载动画
* @returns Promise
*/
delete(url, data, header, showLoading) {
return this.request(url, "DELETE", data, header, showLoading)
}
}

const request = new API()

export default request

多个路径

在class中加一个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class API {
/**
* 构造函数中添加了baseUrl参数,允许在创建API实例时设置基础URL。
* @param {string} [baseUrl='https://www.brrfid-pm.cn/WXAPI'] - API的基础URL。
*/
constructor(baseUrl = 'https://www.brrfid-pm.cn/WXAPI') {
this.baseUrl = baseUrl
}

// ... 其他原有方法不变 ...

/**
* 封装的请求
* 新增baseUrlKey参数,用于动态选择基础URL
* @param {*} url 请求地址(相对路径)
* @param {*} method 请求类型
* @param {*} data 请求数据
* @param {*} header 请求头
* @param {*} showLoading 是否显示加载动画
* @returns
*/
request(url, method, data, header = {}, showLoading = true) {
const fullUrl = this.baseUrl + url;
// ... 其余代码逻辑保持不变 ...
}

// ... 其他请求方法(get, post, put, delete)保持不变
}

const request = new API() // 默认路径
const customApi = new API('https://xxx.xxx.xxx') // 其他路径

公共函数/过滤器

在根路径创建global文件夹用于存放全局的函数、变量、过滤器等

所有的文件需要再main.js中引入

例如:import ‘./global/filter.js’;

全局过滤器

filter.js 用于存放全局的过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import Vue from 'vue'

// 字符串有/n时替换为<br/>,并且在前面补一段话
Vue.filter('replaceNewlineWithBr', function (value) {
let str = "产品描述:";
str += value?.replace(/\n/g, "<br/>");
return str;
})

// 价格小数位补0
Vue.filter('formatPrice', function (price) {
if (!price) {
return
}
// 将价格转换为字符串,便于操作
let priceStr = price.toString();
// 使用正则表达式检查小数点及之后的数字
let match = priceStr.match(/(\.\d*)?$/);
// 如果没有小数点或者小数点后不足两位
if (!match || match[0].length < 3) {
// 补足到小数点后两位
return price.toFixed(2);
} else {
// 如果小数点后已经两位或以上,直接返回原价
return priceStr;
}
})

// 订单状态
Vue.filter('fnStatus', function (value) {
const typesObj = {
1: "未支付",
2: "已支付",
3: "生产中",
4: "已完成",
5: "已取消",
};
return typesObj[value];
})

全局函数以及变量等

mixin.js 用于存放全局的变量已经函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// main.js 或者你的入口文件
import Vue from 'vue';
import { BASE_URL, downLoadUrl } from '@/api/request';

Vue.mixin({
data() {
return {
navBarHeight: uni.getStorageSync("navBarHeight") || 90, // 顶部高度
tabBarHeight: uni.getStorageSync("tabBarHeight") || 80, // 底部高度
imgurl: this.imgurl, // 图片前缀
BASE_URL: BASE_URL, // 请求前缀
downLoadUrl: downLoadUrl, // 下载文件前缀
}
},
methods: {
// 复制
copy(text) {
uni.setClipboardData({
data: text,
success: (res) => {
this.$u.toast("复制成功");
},
fail: (err) => {
this.$u.toast("复制失败");
},
});
},
// 计算表单高度
getNavBarHeight(className) {
return new Promise((resolve, reject) => {
const query = uni.createSelectorQuery().in(this);
query
.select(className)
.boundingClientRect((data) => {
console.log("data.height :>> ", data.height);
resolve(data.height);
})
.exec();
});
},
// 跳转页面
goPage(url) {
if (!url) {
return;
}
uni.navigateTo({
url: url,
});
},
// 图片上传
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: this.BASE_URL + "/uploadImage", // 仅为示例,非真实的接口地址
filePath: url,
header: {
token: uni.getStorageSync('token') || ''
},
name: "file",
success: (res) => {
console.log('res :>> ', res);
let data = JSON.parse(res.data).url
setTimeout(() => {
resolve(data);
}, 1000);
},
});
});
},
// 文件下载
downloadFilePromise(url) {
console.log('url :>> ', url);
console.log('this.downLoadUrl + url :>> ', this.downLoadUrl + url);
return new Promise((resolve, reject) => {
const downloadTask = uni.downloadFile({
url: this.downLoadUrl + url, // 文件下载地址
success: (res) => {
if (res.statusCode === 200) {
// 下载成功处理
console.log('下载成功');
// 保存到本地文件系统
uni.saveFile({
tempFilePath: res.tempFilePath, //临时文件路径
filePath: `${wx.env.USER_DATA_PATH}/${url}`, // 指定保存路径和文件名
success: (saveRes) => {
console.log('文件保存成功', saveRes.savedFilePath);
resolve(saveRes.savedFilePath)
},
fail: (err) => {
console.log('保存文件失败', err);
}
});
} else {
console.log('下载失败', res.statusCode);
}
},
fail: (err) => {
console.log('下载过程中出错', err);
}
});

downloadTask.onProgressUpdate((res) => {
uni.showLoading({
title: `下载进度 ${res.progress}%`,
mask: true,
});
if (res.progress == 100) {
uni.hideLoading();
uni.showToast({
title: "下载成功",
icon: "success",
duration: 1500,
});
}
});
})
}
}
});

路由/分包/组件

路由

路由使用HBuilderX创建基本上没有问题

个人不习惯嵌套多个文件夹

分包

按照官方的要求创建分包,后面创建页面会自动识别是哪一个分包,如果能够确保自己设置的没有问题,但是创建的时候没有识别,就重启HBuilderX

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"subPackages": [
{
"root": "products",
"pages": [
{
"path": "detail/detail",
"style": {
"navigationBarTitleText": "产品详情",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}
]
},
]
····省略其他内容···
"lazyCodeLoading": "requiredComponents"

组件

只要组件安装在项目的 components 目录下,并符合 components/组件名称/组件名称.vue 目录结构。就可以不用引用、注册,直接在页面中使用。

官方说明:https://uniapp.dcloud.net.cn/tutorial/vue-components.html#%E5%B1%80%E9%83%A8%E6%B3%A8%E5%86%8C

本文作者:辰風依恛
本文链接:https://766187397.github.io/2025/07/10/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%B0%81%E8%A3%85%E6%8A%BD%E7%A6%BB/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可
×