@hlw-uni/mp-vue 2.1.52 → 2.1.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/app.d.ts +2 -20
  2. package/dist/composables/ad/index.d.ts +11 -73
  3. package/dist/composables/device/index.d.ts +5 -70
  4. package/dist/composables/index.d.ts +6 -14
  5. package/dist/composables/navigator/index.d.ts +15 -39
  6. package/dist/composables/request/client.d.ts +21 -0
  7. package/dist/composables/request/index.d.ts +6 -0
  8. package/dist/composables/request/service.d.ts +30 -0
  9. package/dist/composables/{http → request}/types.d.ts +0 -3
  10. package/dist/composables/share/index.d.ts +7 -66
  11. package/dist/composables/utils/index.d.ts +25 -32
  12. package/dist/hlw.d.ts +2 -4
  13. package/dist/index.d.ts +2 -3
  14. package/dist/index.js +614 -1253
  15. package/dist/index.mjs +613 -1252
  16. package/package.json +2 -1
  17. package/src/app.ts +3 -143
  18. package/src/components/hlw-ad/index.vue +6 -5
  19. package/src/components/hlw-page/index.vue +1 -1
  20. package/src/composables/ad/README.md +58 -0
  21. package/src/composables/ad/index.ts +117 -376
  22. package/src/composables/device/README.md +50 -0
  23. package/src/composables/device/index.ts +110 -83
  24. package/src/composables/index.ts +10 -39
  25. package/src/composables/msg/README.md +79 -0
  26. package/src/composables/navigator/README.md +71 -0
  27. package/src/composables/navigator/index.ts +77 -77
  28. package/src/composables/refs/README.md +40 -0
  29. package/src/composables/request/README.md +124 -0
  30. package/src/composables/{http → request}/adapters/oss.ts +1 -0
  31. package/src/composables/request/client.ts +204 -0
  32. package/src/composables/request/index.ts +15 -0
  33. package/src/composables/request/service.ts +54 -0
  34. package/src/composables/{http → request}/types.ts +0 -4
  35. package/src/composables/share/README.md +53 -0
  36. package/src/composables/share/index.ts +64 -168
  37. package/src/composables/theme/README.md +131 -0
  38. package/src/composables/theme/index.ts +4 -2
  39. package/src/composables/theme/palette.ts +22 -4
  40. package/src/composables/utils/README.md +81 -0
  41. package/src/composables/utils/index.ts +131 -95
  42. package/src/hlw.ts +6 -14
  43. package/src/index.ts +2 -3
  44. package/dist/composables/_internal/unwrap.d.ts +0 -15
  45. package/dist/composables/algo/index.d.ts +0 -7
  46. package/dist/composables/algo/uuid.d.ts +0 -17
  47. package/dist/composables/color/index.d.ts +0 -8
  48. package/dist/composables/contact/index.d.ts +0 -32
  49. package/dist/composables/format/index.d.ts +0 -9
  50. package/dist/composables/http/client.d.ts +0 -66
  51. package/dist/composables/http/index.d.ts +0 -8
  52. package/dist/composables/loading/index.d.ts +0 -7
  53. package/dist/composables/page-meta/index.d.ts +0 -18
  54. package/dist/composables/storage/index.d.ts +0 -16
  55. package/dist/composables/validate/index.d.ts +0 -12
  56. package/dist/error.d.ts +0 -1
  57. package/src/composables/_internal/unwrap.ts +0 -19
  58. package/src/composables/algo/index.ts +0 -7
  59. package/src/composables/algo/uuid.ts +0 -27
  60. package/src/composables/color/index.ts +0 -44
  61. package/src/composables/contact/index.ts +0 -92
  62. package/src/composables/format/index.ts +0 -48
  63. package/src/composables/http/client.ts +0 -237
  64. package/src/composables/http/index.ts +0 -8
  65. package/src/composables/http/useRequest.ts +0 -107
  66. package/src/composables/loading/index.ts +0 -23
  67. package/src/composables/page-meta/index.ts +0 -49
  68. package/src/composables/storage/index.ts +0 -76
  69. package/src/composables/validate/index.ts +0 -58
  70. package/src/error.ts +0 -5
  71. /package/dist/composables/{http → request}/adapters/alist.d.ts +0 -0
  72. /package/dist/composables/{http → request}/adapters/base.d.ts +0 -0
  73. /package/dist/composables/{http → request}/adapters/cos.d.ts +0 -0
  74. /package/dist/composables/{http → request}/adapters/index.d.ts +0 -0
  75. /package/dist/composables/{http → request}/adapters/oss.d.ts +0 -0
  76. /package/dist/composables/{http → request}/adapters/qiniu.d.ts +0 -0
  77. /package/src/composables/{http → request}/adapters/alist.ts +0 -0
  78. /package/src/composables/{http → request}/adapters/base.ts +0 -0
  79. /package/src/composables/{http → request}/adapters/cos.ts +0 -0
  80. /package/src/composables/{http → request}/adapters/index.ts +0 -0
  81. /package/src/composables/{http → request}/adapters/qiniu.ts +0 -0
@@ -0,0 +1,124 @@
1
+ # request 调用文档
2
+
3
+ `request` 模块封装 `uni.request`、请求拦截器、响应拦截器、错误拦截器、上传和服务类组织方式。
4
+
5
+ ## 引入
6
+
7
+ ```ts
8
+ import {
9
+ useRequest,
10
+ useUpload,
11
+ BaseService,
12
+ ServiceNamespace,
13
+ ServicePrefix,
14
+ } from "@hlw-uni/mp-vue";
15
+ ```
16
+
17
+ ## useRequest
18
+
19
+ ```ts
20
+ const request = useRequest();
21
+
22
+ request.setBaseURL("https://api.example.com");
23
+
24
+ const offRequest = request.onRequest((config) => {
25
+ config.headers = {
26
+ ...config.headers,
27
+ "x-token": uni.getStorageSync("token"),
28
+ };
29
+ return config;
30
+ });
31
+
32
+ const res = await request.get<{ name: string }>("/user/profile");
33
+
34
+ offRequest();
35
+ ```
36
+
37
+ ## API
38
+
39
+ | 方法 | 说明 |
40
+ | --- | --- |
41
+ | `request(config)` | 发起完整配置请求 |
42
+ | `get(url, data?)` | GET 请求 |
43
+ | `post(url, data?)` | POST 请求 |
44
+ | `put(url, data?)` | PUT 请求 |
45
+ | `del(url, data?)` | DELETE 请求 |
46
+ | `setBaseURL(url)` | 设置全局基础地址 |
47
+ | `onRequest(fn)` | 注册请求拦截器,返回取消函数 |
48
+ | `onResponse(fn)` | 注册响应拦截器,返回取消函数 |
49
+ | `onError(fn)` | 注册错误拦截器,返回取消函数 |
50
+ | `upload(config)` | 上传文件 |
51
+ | `resolveServiceUrl(namespace, url, servicePrefix?)` | 生成服务类请求地址 |
52
+
53
+ ## 响应格式
54
+
55
+ ```ts
56
+ interface ApiResponse<T = unknown> {
57
+ code: number;
58
+ data: T;
59
+ info: string;
60
+ }
61
+ ```
62
+
63
+ ## useUpload
64
+
65
+ ```ts
66
+ const { uploading, upload } = useUpload();
67
+
68
+ const result = await upload({
69
+ type: "local",
70
+ server: "https://api.example.com/upload",
71
+ url: "https://api.example.com/upload",
72
+ filePath: tempFilePath,
73
+ header: {
74
+ "x-token": uni.getStorageSync("token"),
75
+ },
76
+ });
77
+
78
+ console.log(uploading.value, result.data);
79
+ ```
80
+
81
+ 上传类型:
82
+
83
+ | 类型 | 说明 |
84
+ | --- | --- |
85
+ | `local` | 直接上传到业务接口 |
86
+ | `cos` | 腾讯云 COS 表单上传 |
87
+ | `oss` | 阿里云 OSS 表单上传 |
88
+ | `qiniu` | 七牛云表单上传 |
89
+ | `alist` | Alist 上传 |
90
+
91
+ ## BaseService
92
+
93
+ ```ts
94
+ @ServicePrefix("api")
95
+ @ServiceNamespace("user")
96
+ class UserService extends BaseService {
97
+ profile() {
98
+ return this.get<{ nickname: string }>("/profile");
99
+ }
100
+
101
+ update(data: { nickname: string }) {
102
+ return this.post("/update", data);
103
+ }
104
+ }
105
+
106
+ const userService = new UserService();
107
+ const profile = await userService.profile();
108
+ ```
109
+
110
+ 上面的 `profile()` 会请求 `/api/user/profile`。如果传入绝对地址,例如 `https://example.com/a`,则不会拼接前缀。
111
+
112
+ ## UploadConfig
113
+
114
+ ```ts
115
+ interface UploadConfig {
116
+ server: string;
117
+ filePath: string;
118
+ fileName?: string;
119
+ type: string;
120
+ credentials?: Record<string, string>;
121
+ header?: Record<string, string>;
122
+ url?: string;
123
+ }
124
+ ```
@@ -11,6 +11,7 @@ export const ossAdapter: UploadAdapter = {
11
11
  buildFormData(ctx) {
12
12
  const c = ctx.credentials ?? {};
13
13
  return {
14
+ key: c["key"] ?? ctx.fileName,
14
15
  policy: c["policy"] ?? "",
15
16
  signature: c["signature"] ?? "",
16
17
  OSSAccessKeyId: c["accessKeyId"] ?? "",
@@ -0,0 +1,204 @@
1
+ import { ref } from "vue";
2
+ import type {
3
+ ApiResponse,
4
+ ErrorInterceptor,
5
+ RequestConfig,
6
+ RequestInterceptor,
7
+ ResponseInterceptor,
8
+ UploadConfig,
9
+ UploadResult,
10
+ } from "./types";
11
+ import { getAdapter } from "./adapters";
12
+
13
+ export interface RequestClient {
14
+ request<T = unknown>(config: RequestConfig): Promise<ApiResponse<T>>;
15
+ get<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>>;
16
+ post<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>>;
17
+ put<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>>;
18
+ del<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>>;
19
+ upload(config: UploadConfig): Promise<UploadResult>;
20
+ setBaseURL(url: string): void;
21
+ resolveServiceUrl(namespace: string, url: string, servicePrefix?: string): string;
22
+ onRequest(fn: RequestInterceptor): () => void;
23
+ onResponse<T = unknown>(fn: ResponseInterceptor<T>): () => void;
24
+ onError(fn: ErrorInterceptor): () => void;
25
+ }
26
+
27
+ class UniRequestClient implements RequestClient {
28
+ private reqInterceptors: RequestInterceptor[] = [];
29
+ private resInterceptors: ResponseInterceptor[] = [];
30
+ private errInterceptors: ErrorInterceptor[] = [];
31
+ private baseURL = "";
32
+ private defaultHeaders: Record<string, string> = { "Content-Type": "application/json" };
33
+
34
+ setBaseURL(url: string): void {
35
+ this.baseURL = url;
36
+ }
37
+
38
+ onRequest(fn: RequestInterceptor): () => void {
39
+ this.reqInterceptors.push(fn);
40
+ return () => this.remove(this.reqInterceptors, fn);
41
+ }
42
+
43
+ onResponse<T = unknown>(fn: ResponseInterceptor<T>): () => void {
44
+ const item = fn as ResponseInterceptor;
45
+ this.resInterceptors.push(item);
46
+ return () => this.remove(this.resInterceptors, item);
47
+ }
48
+
49
+ onError(fn: ErrorInterceptor): () => void {
50
+ this.errInterceptors.push(fn);
51
+ return () => this.remove(this.errInterceptors, fn);
52
+ }
53
+
54
+ async request<T = unknown>(config: RequestConfig): Promise<ApiResponse<T>> {
55
+ let cfg: RequestConfig = {
56
+ method: "GET",
57
+ ...config,
58
+ headers: { ...this.defaultHeaders, ...config.headers },
59
+ };
60
+
61
+ for (const fn of this.reqInterceptors) {
62
+ cfg = await fn(cfg);
63
+ }
64
+
65
+ try {
66
+ const res = await this.send<T>(this.resolveUrl(cfg.url), cfg);
67
+ for (const fn of this.resInterceptors) {
68
+ const next = await fn(res as ApiResponse<unknown>);
69
+ if (next !== undefined) return next as ApiResponse<T>;
70
+ }
71
+ return res;
72
+ } catch (e) {
73
+ const err = e as Error;
74
+ for (const fn of this.errInterceptors) {
75
+ await fn(err);
76
+ }
77
+ throw err;
78
+ }
79
+ }
80
+
81
+ get<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
82
+ return this.request<T>({ url, method: "GET", data });
83
+ }
84
+
85
+ post<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
86
+ return this.request<T>({ url, method: "POST", data });
87
+ }
88
+
89
+ put<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
90
+ return this.request<T>({ url, method: "PUT", data });
91
+ }
92
+
93
+ del<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
94
+ return this.request<T>({ url, method: "DELETE", data });
95
+ }
96
+
97
+ upload(config: UploadConfig): Promise<UploadResult> {
98
+ const fileName = config.fileName ?? config.filePath.split("/").pop() ?? "file";
99
+ const server = config.type === "local" && config.url ? config.url : config.server;
100
+ const formData = config.type === "local"
101
+ ? (config.credentials ?? {})
102
+ : getAdapter(config.type).buildFormData({
103
+ filePath: config.filePath,
104
+ fileName,
105
+ credentials: config.credentials,
106
+ });
107
+
108
+ return new Promise((resolve, reject) => {
109
+ uni.uploadFile({
110
+ url: server,
111
+ filePath: config.filePath,
112
+ name: "file",
113
+ formData: formData as unknown as UniNamespace.UploadFileOption["formData"],
114
+ header: config.header as Record<string, string>,
115
+ success: (res) => {
116
+ if (res.statusCode < 200 || res.statusCode >= 300) {
117
+ reject(new Error(`上传失败: ${res.statusCode}`));
118
+ return;
119
+ }
120
+
121
+ try {
122
+ const body = JSON.parse(res.data);
123
+ resolve({
124
+ code: body.code ?? 1,
125
+ msg: body.msg ?? body.message ?? "上传成功",
126
+ data: body.data ?? "",
127
+ });
128
+ } catch {
129
+ resolve({ code: 1, msg: "上传成功", data: res.data });
130
+ }
131
+ },
132
+ fail: (err) => reject(new Error(err.errMsg || "上传失败")),
133
+ });
134
+ });
135
+ }
136
+
137
+ resolveServiceUrl(namespace: string, url: string, servicePrefix = ""): string {
138
+ if (isAbsolute(url)) return url;
139
+
140
+ const ns = namespace.replace(/^\/+|\/+$/g, "").replace(/\//g, ".");
141
+ const prefixValue = servicePrefix.replace(/^\/+|\/+$/g, "");
142
+ const path = url.startsWith("/") ? url : `/${url}`;
143
+ const prefix = [prefixValue, ns].filter(Boolean).join("/");
144
+
145
+ return prefix ? `/${prefix}${path}` : path;
146
+ }
147
+
148
+ private resolveUrl(url: string): string {
149
+ if (isAbsolute(url)) return url;
150
+ return `${this.baseURL}${url}`;
151
+ }
152
+
153
+ private send<T>(url: string, cfg: RequestConfig): Promise<ApiResponse<T>> {
154
+ return new Promise((resolve, reject) => {
155
+ uni.request({
156
+ url,
157
+ method: cfg.method,
158
+ data: cfg.data as UniNamespace.RequestOptions["data"],
159
+ header: cfg.headers as Record<string, string>,
160
+ timeout: cfg.timeout,
161
+ success: (res) => {
162
+ if (res.statusCode >= 200 && res.statusCode < 300) {
163
+ resolve(res.data as ApiResponse<T>);
164
+ return;
165
+ }
166
+
167
+ const body = res.data as Record<string, unknown> | undefined;
168
+ reject(new Error(String(body?.info ?? body?.message ?? `请求失败: ${res.statusCode}`)));
169
+ },
170
+ fail: (err) => reject(new Error(err.errMsg || "网络请求失败")),
171
+ });
172
+ });
173
+ }
174
+
175
+ private remove<T>(items: T[], item: T): void {
176
+ const index = items.indexOf(item);
177
+ if (index > -1) items.splice(index, 1);
178
+ }
179
+ }
180
+
181
+ function isAbsolute(url: string): boolean {
182
+ return /^(https?:)?\/\//.test(url) || url.startsWith("file://");
183
+ }
184
+
185
+ const requestClient = new UniRequestClient();
186
+
187
+ export function useRequest(): RequestClient {
188
+ return requestClient;
189
+ }
190
+
191
+ export function useUpload() {
192
+ const uploading = ref(false);
193
+
194
+ async function upload(options: UploadConfig): Promise<UploadResult> {
195
+ uploading.value = true;
196
+ try {
197
+ return await requestClient.upload(options);
198
+ } finally {
199
+ uploading.value = false;
200
+ }
201
+ }
202
+
203
+ return { uploading, upload };
204
+ }
@@ -0,0 +1,15 @@
1
+ export { useRequest, useUpload } from "./client";
2
+ export { BaseService, ServiceNamespace, ServicePrefix } from "./service";
3
+ export type { RequestClient } from "./client";
4
+ export type {
5
+ ApiResponse,
6
+ PageResult,
7
+ RequestConfig,
8
+ RequestInterceptor,
9
+ ResponseInterceptor,
10
+ ErrorInterceptor,
11
+ UploadConfig,
12
+ UploadResult,
13
+ } from "./types";
14
+ export type { ServiceNamespaceOptions, ServicePrefixOptions, ServiceRequestConfig } from "./service";
15
+ export * from "./adapters";
@@ -0,0 +1,54 @@
1
+ import { useRequest } from "./client";
2
+ import type { ApiResponse, RequestConfig } from "./types";
3
+
4
+ export type ServiceRequestConfig = Omit<RequestConfig, "url"> & {
5
+ url: string;
6
+ };
7
+
8
+ export interface ServiceNamespaceOptions {
9
+ namespace: string;
10
+ }
11
+
12
+ export interface ServicePrefixOptions {
13
+ prefix: string;
14
+ }
15
+
16
+ export class BaseService {
17
+ declare namespace: string;
18
+ declare servicePrefix: string;
19
+
20
+ request<T = unknown>(options: ServiceRequestConfig): Promise<ApiResponse<T>> {
21
+ return useRequest().request<T>({
22
+ ...options,
23
+ url: useRequest().resolveServiceUrl(this.namespace ?? "", options.url, this.servicePrefix ?? ""),
24
+ });
25
+ }
26
+
27
+ get<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
28
+ return this.request<T>({ url, method: "GET", data });
29
+ }
30
+
31
+ post<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
32
+ return this.request<T>({ url, method: "POST", data });
33
+ }
34
+
35
+ put<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
36
+ return this.request<T>({ url, method: "PUT", data });
37
+ }
38
+
39
+ del<T = unknown>(url: string, data?: unknown): Promise<ApiResponse<T>> {
40
+ return this.request<T>({ url, method: "DELETE", data });
41
+ }
42
+ }
43
+
44
+ export function ServiceNamespace(value: string | ServiceNamespaceOptions) {
45
+ return function (target: { prototype: { namespace?: string } }) {
46
+ target.prototype.namespace = typeof value === "string" ? value : value.namespace;
47
+ };
48
+ }
49
+
50
+ export function ServicePrefix(value: string | ServicePrefixOptions) {
51
+ return function (target: { prototype: { servicePrefix?: string } }) {
52
+ target.prototype.servicePrefix = typeof value === "string" ? value : value.prefix;
53
+ };
54
+ }
@@ -1,7 +1,3 @@
1
- /**
2
- * HTTP 类型定义
3
- */
4
-
5
1
  /** API 统一响应格式 */
6
2
  export interface ApiResponse<T = unknown> {
7
3
  code: number;
@@ -0,0 +1,53 @@
1
+ # share 调用文档
2
+
3
+ `useShare` 注册微信小程序分享给好友和分享到朋友圈,并尝试打开分享菜单。
4
+
5
+ ## 引入
6
+
7
+ ```ts
8
+ import { useShare } from "@hlw-uni/mp-vue";
9
+ ```
10
+
11
+ ## 基础用法
12
+
13
+ ```ts
14
+ useShare({
15
+ title: "好用的小程序",
16
+ path: "/pages/index/index?from=share",
17
+ imageUrl: "https://example.com/share.png",
18
+ });
19
+ ```
20
+
21
+ ## 动态分享内容
22
+
23
+ ```ts
24
+ const share = useShare(() => ({
25
+ title: detail.value.title,
26
+ path: `/pages/detail/index?id=${detail.value.id}`,
27
+ imageUrl: detail.value.cover,
28
+ }));
29
+
30
+ share.onShareAppMessage({
31
+ title: "覆盖好友分享标题",
32
+ });
33
+ ```
34
+
35
+ ## API
36
+
37
+ | 方法 | 说明 |
38
+ | --- | --- |
39
+ | `onShareAppMessage(config?)` | 注册好友分享 |
40
+ | `onShareTimeline(config?)` | 注册朋友圈分享 |
41
+ | `showShareMenu()` | 主动显示分享菜单 |
42
+
43
+ 同一个 `useShare` 实例中,好友分享和朋友圈分享各只注册一次。
44
+
45
+ ## ShareConfig
46
+
47
+ ```ts
48
+ interface ShareConfig {
49
+ title?: string;
50
+ path?: string;
51
+ imageUrl?: string;
52
+ }
53
+ ```