uview-pro 0.5.14 → 0.5.16
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.
- package/changelog.md +53 -8
- package/components/u-action-sheet/types.ts +10 -2
- package/components/u-action-sheet-item/types.ts +10 -2
- package/components/u-alert-tips/types.ts +10 -2
- package/components/u-avatar/types.ts +10 -2
- package/components/u-back-top/types.ts +10 -2
- package/components/u-badge/types.ts +10 -2
- package/components/u-button/types.ts +11 -3
- package/components/u-button/u-button.vue +17 -0
- package/components/u-calendar/types.ts +10 -2
- package/components/u-car-keyboard/types.ts +11 -3
- package/components/u-card/types.ts +10 -2
- package/components/u-cell-group/types.ts +10 -2
- package/components/u-cell-item/types.ts +10 -2
- package/components/u-checkbox/types.ts +12 -4
- package/components/u-checkbox/u-checkbox.vue +73 -9
- package/components/u-checkbox-group/types.ts +14 -6
- package/components/u-checkbox-group/u-checkbox-group.vue +1 -1
- package/components/u-circle-progress/types.ts +10 -2
- package/components/u-city-select/types.ts +10 -2
- package/components/u-col/types.ts +10 -2
- package/components/u-collapse/types.ts +10 -2
- package/components/u-collapse-item/types.ts +10 -2
- package/components/u-column-notice/types.ts +10 -2
- package/components/u-config-provider/types.ts +10 -2
- package/components/u-count-down/types.ts +10 -2
- package/components/u-count-to/types.ts +10 -2
- package/components/u-divider/types.ts +10 -2
- package/components/u-dropdown/types.ts +10 -2
- package/components/u-dropdown-item/types.ts +10 -2
- package/components/u-empty/types.ts +10 -2
- package/components/u-fab/types.ts +10 -2
- package/components/u-field/types.ts +10 -2
- package/components/u-form/types.ts +14 -4
- package/components/u-form-item/types.ts +16 -3
- package/components/u-form-item/u-form-item.vue +73 -9
- package/components/u-full-screen/types.ts +10 -2
- package/components/u-gap/types.ts +10 -2
- package/components/u-grid/types.ts +10 -2
- package/components/u-grid-item/types.ts +10 -2
- package/components/u-icon/types.ts +10 -2
- package/components/u-image/types.ts +10 -2
- package/components/u-index-anchor/types.ts +10 -2
- package/components/u-input/types.ts +16 -3
- package/components/u-input/u-input.vue +100 -22
- package/components/u-loading/types.ts +10 -2
- package/components/u-loadmore/types.ts +10 -2
- package/components/u-mask/types.ts +10 -2
- package/components/u-message-input/types.ts +10 -2
- package/components/u-modal/types.ts +10 -2
- package/components/u-pagination/types.ts +11 -2
- package/components/u-picker/types.ts +10 -2
- package/components/u-popup/types.ts +10 -2
- package/components/u-radio/types.ts +14 -4
- package/components/u-radio/u-radio.vue +78 -10
- package/components/u-radio-group/types.ts +12 -4
- package/components/u-rate/types.ts +10 -2
- package/components/u-read-more/types.ts +10 -2
- package/components/u-row/types.ts +10 -2
- package/components/u-row-notice/types.ts +10 -2
- package/components/u-safe-bottom/types.ts +19 -0
- package/components/u-safe-bottom/u-safe-bottom.vue +1 -1
- package/components/u-search/types.ts +10 -2
- package/components/u-section/types.ts +10 -2
- package/components/u-select/types.ts +10 -2
- package/components/u-skeleton/types.ts +10 -2
- package/components/u-slider/types.ts +10 -2
- package/components/u-status-bar/types.ts +21 -0
- package/components/u-status-bar/u-status-bar.vue +1 -1
- package/components/u-step/types.ts +10 -2
- package/components/u-steps/types.ts +10 -2
- package/components/u-sticky/types.ts +10 -2
- package/components/u-subsection/types.ts +10 -2
- package/components/u-swipe-action/types.ts +10 -2
- package/components/u-swiper/types.ts +10 -2
- package/components/u-switch/types.ts +12 -4
- package/components/u-switch/u-switch.vue +60 -5
- package/components/u-tabbar/types.ts +10 -2
- package/components/u-table/types.ts +10 -2
- package/components/u-tabs/types.ts +10 -2
- package/components/u-tabs-swiper/types.ts +10 -2
- package/components/u-tag/types.ts +10 -2
- package/components/u-tag/u-tag.vue +5 -0
- package/components/u-td/types.ts +10 -2
- package/components/u-text/types.ts +10 -2
- package/components/u-textarea/types.ts +16 -5
- package/components/u-textarea/u-textarea.vue +87 -6
- package/components/u-th/types.ts +10 -2
- package/components/u-time-line/u-time-line.vue +13 -2
- package/components/u-time-line-item/types.ts +10 -2
- package/components/u-toast/types.ts +10 -2
- package/components/u-top-tips/types.ts +10 -2
- package/components/u-tr/types.ts +11 -3
- package/components/u-transition/types.ts +10 -2
- package/components/u-upload/types.ts +10 -2
- package/components/u-verification-code/types.ts +10 -2
- package/components/u-waterfall/types.ts +10 -2
- package/index.ts +4 -5
- package/libs/config/config.ts +27 -4
- package/libs/css/common.scss +5 -0
- package/libs/hooks/useCompRelation.ts +37 -34
- package/libs/index.ts +0 -1
- package/libs/util/config-provider.ts +24 -25
- package/package.json +3 -2
- package/types/global.d.ts +8 -9
- package/components/common/props.ts +0 -22
- package/components/u-safe-bottom/props.ts +0 -11
- package/components/u-status-bar/props.ts +0 -13
- package/libs/util/logger.ts +0 -364
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { ExtractPropTypes, PropType } from 'vue';
|
|
2
2
|
import type { ImgMode, UploadSizeType, UploadSourceType } from '../../types/global';
|
|
3
|
-
import { baseProps } from '../common/props';
|
|
4
3
|
import { useLocale } from '../../';
|
|
5
4
|
|
|
6
5
|
const { t } = useLocale();
|
|
@@ -10,7 +9,16 @@ const { t } = useLocale();
|
|
|
10
9
|
* @description 文件上传组件,支持多种自定义参数
|
|
11
10
|
*/
|
|
12
11
|
export const UploadProps = {
|
|
13
|
-
|
|
12
|
+
/** 自定义根节点样式 */
|
|
13
|
+
customStyle: {
|
|
14
|
+
type: [String, Object] as PropType<string | Record<string, any>>,
|
|
15
|
+
default: () => ({})
|
|
16
|
+
},
|
|
17
|
+
/** 自定义根节点样式类 */
|
|
18
|
+
customClass: {
|
|
19
|
+
type: String as unknown as PropType<string>,
|
|
20
|
+
default: ''
|
|
21
|
+
},
|
|
14
22
|
/** 选择器宽度,单位rpx */
|
|
15
23
|
width: { type: [Number, String] as PropType<number | string>, default: 200 },
|
|
16
24
|
/** 选择器高度,单位rpx */
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ExtractPropTypes, PropType } from 'vue';
|
|
2
|
-
import { baseProps } from '../common/props';
|
|
3
2
|
import { useLocale } from '../../';
|
|
4
3
|
|
|
5
4
|
const { t } = useLocale();
|
|
@@ -9,7 +8,16 @@ const { t } = useLocale();
|
|
|
9
8
|
* @description 验证码输入倒计时组件
|
|
10
9
|
*/
|
|
11
10
|
export const VerificationCodeProps = {
|
|
12
|
-
|
|
11
|
+
/** 自定义根节点样式 */
|
|
12
|
+
customStyle: {
|
|
13
|
+
type: [String, Object] as PropType<string | Record<string, any>>,
|
|
14
|
+
default: () => ({})
|
|
15
|
+
},
|
|
16
|
+
/** 自定义根节点样式类 */
|
|
17
|
+
customClass: {
|
|
18
|
+
type: String as unknown as PropType<string>,
|
|
19
|
+
default: ''
|
|
20
|
+
},
|
|
13
21
|
/** 倒计时时长,单位秒 */
|
|
14
22
|
seconds: { type: [String, Number] as PropType<string | number>, default: 60 },
|
|
15
23
|
/** 开始时按钮文字 */
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import type { ExtractPropTypes, PropType } from 'vue';
|
|
2
|
-
import { baseProps } from '../common/props';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* WaterfallProps waterfall props 类型定义
|
|
6
5
|
* @description 瀑布流组件,支持数据、间隔、idKey
|
|
7
6
|
*/
|
|
8
7
|
export const WaterfallProps = {
|
|
9
|
-
|
|
8
|
+
/** 自定义根节点样式 */
|
|
9
|
+
customStyle: {
|
|
10
|
+
type: [String, Object] as PropType<string | Record<string, any>>,
|
|
11
|
+
default: () => ({})
|
|
12
|
+
},
|
|
13
|
+
/** 自定义根节点样式类 */
|
|
14
|
+
customClass: {
|
|
15
|
+
type: String as unknown as PropType<string>,
|
|
16
|
+
default: ''
|
|
17
|
+
},
|
|
10
18
|
/** 瀑布流数据数组,必填 */
|
|
11
19
|
modelValue: { type: Array as PropType<any[]>, required: true, default: () => [] },
|
|
12
20
|
/** 新增数据的动画间隔,单位ms */
|
package/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { $u, type RequestOptions, initTheme, configProvider } from './libs';
|
|
2
2
|
import type { UViewProOptions, Theme } from './types/global';
|
|
3
|
-
import { logger } from './libs/util/logger';
|
|
4
3
|
import { defaultThemes } from './libs/config/theme-tokens';
|
|
4
|
+
import { setConfig } from './libs/config/config';
|
|
5
5
|
|
|
6
6
|
declare const uni: {
|
|
7
7
|
[key: string]: any;
|
|
@@ -74,10 +74,9 @@ const install = (app: any, options?: UViewProOptions): void => {
|
|
|
74
74
|
console.error('[install locales] Error:', e);
|
|
75
75
|
}
|
|
76
76
|
// 设置调试模式
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
.setShowCallerInfo(options?.log?.showCallerInfo ?? true);
|
|
77
|
+
setConfig({
|
|
78
|
+
debugMode: options?.debugMode ?? false
|
|
79
|
+
});
|
|
81
80
|
} else {
|
|
82
81
|
// 默认初始化系统主题
|
|
83
82
|
initTheme();
|
package/libs/config/config.ts
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { reactive } from 'vue';
|
|
5
5
|
import { version } from '../../package.json';
|
|
6
|
-
import type { DarkMode } from '../../types/global';
|
|
6
|
+
import type { DarkMode, DebugMode } from '../../types/global';
|
|
7
7
|
|
|
8
|
-
export
|
|
8
|
+
export type AppConfig = {
|
|
9
9
|
/** 版本号 */
|
|
10
10
|
v: string;
|
|
11
11
|
/** 版本号(冗余字段) */
|
|
@@ -18,7 +18,9 @@ export interface AppConfig {
|
|
|
18
18
|
defaultDarkMode: DarkMode;
|
|
19
19
|
/** 默认语言 */
|
|
20
20
|
defaultLocale: string;
|
|
21
|
-
|
|
21
|
+
/** 是否开启调试模式 */
|
|
22
|
+
debugMode?: boolean | DebugMode | DebugMode[];
|
|
23
|
+
};
|
|
22
24
|
|
|
23
25
|
export const config = reactive<AppConfig>({
|
|
24
26
|
v: version,
|
|
@@ -30,7 +32,28 @@ export const config = reactive<AppConfig>({
|
|
|
30
32
|
// 默认为亮色模式
|
|
31
33
|
defaultDarkMode: 'light',
|
|
32
34
|
// 默认为中文
|
|
33
|
-
defaultLocale: 'zh-CN'
|
|
35
|
+
defaultLocale: 'zh-CN',
|
|
36
|
+
// 默认不开启调试模式
|
|
37
|
+
debugMode: false
|
|
34
38
|
});
|
|
35
39
|
|
|
40
|
+
export const isDebugMode = (debug: DebugMode = 'log'): boolean => {
|
|
41
|
+
if (config.debugMode === false) return false;
|
|
42
|
+
if (config.debugMode === true) return true;
|
|
43
|
+
if (Array.isArray(config.debugMode)) return config.debugMode.includes(debug);
|
|
44
|
+
return config.debugMode === debug;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const setConfig = (options: Partial<AppConfig>) => {
|
|
48
|
+
try {
|
|
49
|
+
Object.keys(options).forEach(key => {
|
|
50
|
+
if (key in config) {
|
|
51
|
+
(config as any)[key] = options[key as keyof AppConfig];
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
} catch (e) {
|
|
55
|
+
if (isDebugMode('error')) console.error('Failed to set config:', e);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
36
59
|
export default config;
|
package/libs/css/common.scss
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
reactive,
|
|
4
|
-
getCurrentInstance,
|
|
5
|
-
onUnmounted,
|
|
6
|
-
nextTick,
|
|
7
|
-
computed,
|
|
8
|
-
onMounted,
|
|
9
|
-
type ComponentInternalInstance
|
|
10
|
-
} from 'vue';
|
|
11
|
-
import { logger } from '../util/logger';
|
|
1
|
+
import { ref, reactive, getCurrentInstance, onUnmounted, nextTick, computed, onMounted } from 'vue';
|
|
2
|
+
import { isDebugMode } from '../config/config';
|
|
12
3
|
|
|
13
4
|
// 类型定义
|
|
14
5
|
interface ParentContext {
|
|
@@ -36,6 +27,8 @@ interface ChildContext {
|
|
|
36
27
|
|
|
37
28
|
// 符号定义
|
|
38
29
|
const PARENT_CONTEXT_SYMBOL = Symbol('parent_context');
|
|
30
|
+
// 每个组件实例的 child id 缓存,避免同个组件中多次调用 useChildren 时生成不同 id
|
|
31
|
+
const CHILD_ID_SYMBOL = Symbol('child_id');
|
|
39
32
|
|
|
40
33
|
/**
|
|
41
34
|
* 生成实例唯一ID
|
|
@@ -94,7 +87,7 @@ function findAllChildComponents(componentName: string, instance: any): any[] {
|
|
|
94
87
|
}
|
|
95
88
|
|
|
96
89
|
traverse(instance);
|
|
97
|
-
|
|
90
|
+
if (isDebugMode()) console.log(`Found ${components.length} ${componentName} components`);
|
|
98
91
|
return components;
|
|
99
92
|
}
|
|
100
93
|
|
|
@@ -122,7 +115,8 @@ export function useParent(componentName?: string) {
|
|
|
122
115
|
.filter(Boolean) as ChildContext[])
|
|
123
116
|
: Array.from(childrenMap.values());
|
|
124
117
|
|
|
125
|
-
|
|
118
|
+
if (isDebugMode())
|
|
119
|
+
console.log(`Parent ${name} broadcasting event: ${event} to ${targetChildren.length} children`);
|
|
126
120
|
|
|
127
121
|
targetChildren.forEach(child => {
|
|
128
122
|
const exposed = child.getExposed();
|
|
@@ -130,14 +124,15 @@ export function useParent(componentName?: string) {
|
|
|
130
124
|
try {
|
|
131
125
|
exposed[event](data);
|
|
132
126
|
} catch (error) {
|
|
133
|
-
|
|
127
|
+
if (isDebugMode('error')) console.error(`Error calling child method ${event}:`, error);
|
|
134
128
|
}
|
|
135
129
|
}
|
|
136
130
|
});
|
|
137
131
|
};
|
|
138
132
|
|
|
139
133
|
const broadcastToChildren = (componentName: string, event: string, data?: any) => {
|
|
140
|
-
|
|
134
|
+
if (isDebugMode())
|
|
135
|
+
console.log(`Parent ${name} broadcasting event: ${event} to all ${componentName} components`);
|
|
141
136
|
|
|
142
137
|
const childComponents = findAllChildComponents(componentName, instance);
|
|
143
138
|
let successCount = 0;
|
|
@@ -149,14 +144,15 @@ export function useParent(componentName?: string) {
|
|
|
149
144
|
exposed[event](data);
|
|
150
145
|
successCount++;
|
|
151
146
|
} catch (error) {
|
|
152
|
-
|
|
147
|
+
if (isDebugMode('error')) console.error(`Error calling ${componentName} method ${event}:`, error);
|
|
153
148
|
}
|
|
154
149
|
}
|
|
155
150
|
});
|
|
156
151
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
152
|
+
if (isDebugMode())
|
|
153
|
+
console.log(
|
|
154
|
+
`Parent ${name} successfully called ${successCount} of ${childComponents.length} ${componentName} components`
|
|
155
|
+
);
|
|
160
156
|
};
|
|
161
157
|
|
|
162
158
|
const parentContext: ParentContext = {
|
|
@@ -165,7 +161,7 @@ export function useParent(componentName?: string) {
|
|
|
165
161
|
if (!childrenMap.has(child.id)) {
|
|
166
162
|
childrenMap.set(child.id, child);
|
|
167
163
|
children.push(child);
|
|
168
|
-
|
|
164
|
+
if (isDebugMode()) console.log(`Parent ${name} added child: ${child.name}`);
|
|
169
165
|
}
|
|
170
166
|
},
|
|
171
167
|
removeChild(childId: string) {
|
|
@@ -174,7 +170,7 @@ export function useParent(componentName?: string) {
|
|
|
174
170
|
childrenMap.delete(childId);
|
|
175
171
|
const index = children.findIndex(c => c.id === childId);
|
|
176
172
|
if (index > -1) children.splice(index, 1);
|
|
177
|
-
|
|
173
|
+
if (isDebugMode()) console.log(`Parent ${name} removed child: ${childId}`);
|
|
178
174
|
}
|
|
179
175
|
},
|
|
180
176
|
broadcast,
|
|
@@ -207,7 +203,7 @@ export function useParent(componentName?: string) {
|
|
|
207
203
|
if (instance.proxy) {
|
|
208
204
|
delete (instance.proxy as any)[PARENT_CONTEXT_SYMBOL];
|
|
209
205
|
}
|
|
210
|
-
|
|
206
|
+
if (isDebugMode()) console.log(`Parent ${name} unmounted and cleaned up`);
|
|
211
207
|
});
|
|
212
208
|
|
|
213
209
|
return {
|
|
@@ -233,16 +229,23 @@ export function useChildren(componentName?: string, parentName?: string) {
|
|
|
233
229
|
}
|
|
234
230
|
|
|
235
231
|
const name = componentName || instance.type.name || instance.type.__name;
|
|
236
|
-
|
|
232
|
+
// 生成实例ID,同组件多次使用useChildren会重复创建
|
|
233
|
+
// const instanceId = generateInstanceId(name || 'anonymous');
|
|
234
|
+
// 尝试从实例上复用已有的 child id,避免同个组件内多次调用 useChildren 导致重复注册
|
|
235
|
+
let instanceId: string | undefined = (instance.proxy as any)?.[CHILD_ID_SYMBOL];
|
|
236
|
+
if (!instanceId) {
|
|
237
|
+
instanceId = generateInstanceId(name || 'anonymous');
|
|
238
|
+
if (instance.proxy) (instance.proxy as any)[CHILD_ID_SYMBOL] = instanceId;
|
|
239
|
+
}
|
|
237
240
|
const parentRef = ref<any | null>(null);
|
|
238
241
|
const parentExposed = ref<Record<string, any>>({});
|
|
239
242
|
|
|
240
243
|
const createSimulatedParentContext = (parentInstance: any): ParentContext => ({
|
|
241
244
|
name: parentInstance?.type?.name || parentInstance?.type?.__name || 'unknown',
|
|
242
|
-
addChild: () =>
|
|
243
|
-
removeChild: () =>
|
|
244
|
-
broadcast: () =>
|
|
245
|
-
broadcastToChildren: () =>
|
|
245
|
+
addChild: () => isDebugMode() && console.log('Simulated parent added child'),
|
|
246
|
+
removeChild: () => isDebugMode() && console.log('Simulated parent removed child'),
|
|
247
|
+
broadcast: () => isDebugMode() && console.log('Simulated parent broadcasting'),
|
|
248
|
+
broadcastToChildren: () => isDebugMode() && console.log('Simulated parent broadcasting to children'),
|
|
246
249
|
getChildren: () => [],
|
|
247
250
|
getExposed: () => parentInstance?.exposed || {},
|
|
248
251
|
getChildExposed: () => ({}),
|
|
@@ -300,10 +303,10 @@ export function useChildren(componentName?: string, parentName?: string) {
|
|
|
300
303
|
parent.addChild(childContext);
|
|
301
304
|
}
|
|
302
305
|
getParentExposed();
|
|
303
|
-
|
|
306
|
+
if (isDebugMode()) console.log(`Child ${name || 'anonymous'} linked to parent ${parent.name}`);
|
|
304
307
|
return true;
|
|
305
308
|
}
|
|
306
|
-
|
|
309
|
+
if (isDebugMode()) console.log(`Child ${name || 'anonymous'} no parent found, working in standalone mode`);
|
|
307
310
|
return false;
|
|
308
311
|
};
|
|
309
312
|
|
|
@@ -314,7 +317,7 @@ export function useChildren(componentName?: string, parentName?: string) {
|
|
|
314
317
|
try {
|
|
315
318
|
exposed[event](data, instanceId, name);
|
|
316
319
|
} catch (error) {
|
|
317
|
-
|
|
320
|
+
if (isDebugMode('error')) console.error(`Error calling parent method ${event}:`, error);
|
|
318
321
|
}
|
|
319
322
|
}
|
|
320
323
|
}
|
|
@@ -340,7 +343,7 @@ export function useChildren(componentName?: string, parentName?: string) {
|
|
|
340
343
|
getExposed
|
|
341
344
|
};
|
|
342
345
|
|
|
343
|
-
|
|
346
|
+
if (isDebugMode()) console.log(`Child ${name || 'anonymous'} registered, looking for parent`);
|
|
344
347
|
|
|
345
348
|
onMounted(() => {
|
|
346
349
|
let connected = linkParent();
|
|
@@ -356,7 +359,7 @@ export function useChildren(componentName?: string, parentName?: string) {
|
|
|
356
359
|
if (parentRef.value?.removeChild) {
|
|
357
360
|
parentRef.value.removeChild(instanceId);
|
|
358
361
|
}
|
|
359
|
-
|
|
362
|
+
if (isDebugMode()) console.log(`Child ${name || 'anonymous'} unmounted`);
|
|
360
363
|
});
|
|
361
364
|
|
|
362
365
|
return {
|
|
@@ -402,13 +405,13 @@ export function getParentContextByName(parentName: string): ParentContext | null
|
|
|
402
405
|
* 热更新清理函数
|
|
403
406
|
*/
|
|
404
407
|
export function cleanupComponentRelations(): void {
|
|
405
|
-
|
|
408
|
+
if (isDebugMode()) console.log('Cleaning up component relations for hot reload');
|
|
406
409
|
}
|
|
407
410
|
|
|
408
411
|
// 热更新处理
|
|
409
412
|
if (import.meta.hot) {
|
|
410
413
|
import.meta.hot.accept(() => {
|
|
411
|
-
|
|
414
|
+
if (isDebugMode()) console.log('Hot reload detected, relations will be automatically reconnected');
|
|
412
415
|
});
|
|
413
416
|
}
|
|
414
417
|
|
package/libs/index.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { ref } from 'vue';
|
|
6
6
|
import type { DarkMode, Theme, ThemeColor } from '../../types/global';
|
|
7
|
-
import config from '../config/config';
|
|
7
|
+
import config, { isDebugMode } from '../config/config';
|
|
8
8
|
import { defaultThemes } from '../config/theme-tokens';
|
|
9
9
|
import { color as reactiveColor } from '../config/color';
|
|
10
10
|
import { getSystemDarkMode as getNativeSystemDarkMode } from './system-theme';
|
|
@@ -64,7 +64,6 @@ export class ConfigProvider {
|
|
|
64
64
|
public currentLocaleRef = ref<any | null>(null);
|
|
65
65
|
private baseColorTokens: Partial<ThemeColor> = DEFAULT_LIGHT_TOKENS;
|
|
66
66
|
private baseDarkColorTokens: Partial<ThemeColor> = DEFAULT_DARK_TOKENS;
|
|
67
|
-
private debug: boolean = false;
|
|
68
67
|
private systemDarkModeMediaQuery: MediaQueryList | null = null;
|
|
69
68
|
private lastAppliedCssKeys: string[] = [];
|
|
70
69
|
private interval: ReturnType<typeof setInterval> | number = 0;
|
|
@@ -95,7 +94,7 @@ export class ConfigProvider {
|
|
|
95
94
|
}
|
|
96
95
|
}
|
|
97
96
|
} catch (e) {
|
|
98
|
-
if (
|
|
97
|
+
if (isDebugMode('error')) console.error('[ConfigProvider] H5 system dark mode listener failed', e);
|
|
99
98
|
}
|
|
100
99
|
|
|
101
100
|
// uni-app 平台:使用 uni.onThemeChange API
|
|
@@ -110,7 +109,7 @@ export class ConfigProvider {
|
|
|
110
109
|
});
|
|
111
110
|
}
|
|
112
111
|
} catch (e) {
|
|
113
|
-
if (
|
|
112
|
+
if (isDebugMode('error')) console.error('[ConfigProvider] uni-app system dark mode listener failed', e);
|
|
114
113
|
}
|
|
115
114
|
this.initAppEvent();
|
|
116
115
|
}
|
|
@@ -131,7 +130,7 @@ export class ConfigProvider {
|
|
|
131
130
|
}
|
|
132
131
|
}, 5000);
|
|
133
132
|
} catch (e) {
|
|
134
|
-
if (
|
|
133
|
+
if (isDebugMode('error')) console.error('[ConfigProvider] setInterval failed', e);
|
|
135
134
|
}
|
|
136
135
|
// #endif
|
|
137
136
|
}
|
|
@@ -144,12 +143,12 @@ export class ConfigProvider {
|
|
|
144
143
|
return this.systemDarkModeMediaQuery.matches;
|
|
145
144
|
}
|
|
146
145
|
} catch (e) {
|
|
147
|
-
if (
|
|
146
|
+
if (isDebugMode('error')) console.error('[ConfigProvider] matchMedia check failed', e);
|
|
148
147
|
}
|
|
149
148
|
try {
|
|
150
149
|
return getNativeSystemDarkMode() === 'dark';
|
|
151
150
|
} catch (e) {
|
|
152
|
-
if (
|
|
151
|
+
if (isDebugMode('error')) console.error('[ConfigProvider] native system theme check failed', e);
|
|
153
152
|
return false;
|
|
154
153
|
}
|
|
155
154
|
}
|
|
@@ -162,7 +161,7 @@ export class ConfigProvider {
|
|
|
162
161
|
initTheme(themes?: Theme[], defaultConfig?: string | DefaultThemeConfig, isForce?: boolean) {
|
|
163
162
|
const normalizedThemes = this.normalizeThemes(themes);
|
|
164
163
|
if (!normalizedThemes.length) {
|
|
165
|
-
console.warn('[ConfigProvider] init called with empty themes');
|
|
164
|
+
if (isDebugMode('warn')) console.warn('[ConfigProvider] init called with empty themes');
|
|
166
165
|
return;
|
|
167
166
|
}
|
|
168
167
|
|
|
@@ -197,7 +196,7 @@ export class ConfigProvider {
|
|
|
197
196
|
// 应用主题
|
|
198
197
|
this.applyTheme(found);
|
|
199
198
|
|
|
200
|
-
if (
|
|
199
|
+
if (isDebugMode())
|
|
201
200
|
console.log('[ConfigProvider] initialized, theme=', found.name, 'darkMode=', this.darkModeRef.value);
|
|
202
201
|
|
|
203
202
|
return this;
|
|
@@ -223,7 +222,7 @@ export class ConfigProvider {
|
|
|
223
222
|
initLocales(locales?: any[], defaultLocaleName?: string, isForce?: boolean) {
|
|
224
223
|
const normalized = this.normalizeLocales(locales);
|
|
225
224
|
if (!normalized.length) {
|
|
226
|
-
if (
|
|
225
|
+
if (isDebugMode('warn')) console.warn('[ConfigProvider] initLocales called with empty locales');
|
|
227
226
|
return;
|
|
228
227
|
}
|
|
229
228
|
|
|
@@ -241,7 +240,7 @@ export class ConfigProvider {
|
|
|
241
240
|
|
|
242
241
|
this.currentLocaleRef.value = found;
|
|
243
242
|
|
|
244
|
-
if (
|
|
243
|
+
if (isDebugMode()) console.log('[ConfigProvider] locales initialized, locale=', found?.name);
|
|
245
244
|
|
|
246
245
|
return this;
|
|
247
246
|
}
|
|
@@ -255,7 +254,7 @@ export class ConfigProvider {
|
|
|
255
254
|
try {
|
|
256
255
|
builtinList = Object.values(localePack || {}).filter(v => v && typeof v === 'object');
|
|
257
256
|
} catch (e) {
|
|
258
|
-
if (
|
|
257
|
+
if (isDebugMode('error')) console.error('[ConfigProvider] normalizeLocales read builtin failed', e);
|
|
259
258
|
}
|
|
260
259
|
|
|
261
260
|
// 如果没有传入自定义 locales,直接返回内置列表
|
|
@@ -315,17 +314,17 @@ export class ConfigProvider {
|
|
|
315
314
|
*/
|
|
316
315
|
setLocale(localeName: string) {
|
|
317
316
|
if (!this.localesRef.value || this.localesRef.value.length === 0) {
|
|
318
|
-
console.warn('[ConfigProvider] setLocale called but locales list empty');
|
|
317
|
+
if (isDebugMode('warn')) console.warn('[ConfigProvider] setLocale called but locales list empty');
|
|
319
318
|
return;
|
|
320
319
|
}
|
|
321
320
|
const locale = this.localesRef.value.find(l => l.name === localeName);
|
|
322
321
|
if (!locale) {
|
|
323
|
-
console.warn('[ConfigProvider] locale not found:', localeName);
|
|
322
|
+
if (isDebugMode('warn')) console.warn('[ConfigProvider] locale not found:', localeName);
|
|
324
323
|
return;
|
|
325
324
|
}
|
|
326
325
|
this.currentLocaleRef.value = locale;
|
|
327
326
|
this.writeStorage(LOCALE_STORAGE_KEY, localeName);
|
|
328
|
-
if (
|
|
327
|
+
if (isDebugMode()) console.log('[ConfigProvider] setLocale ->', localeName);
|
|
329
328
|
}
|
|
330
329
|
|
|
331
330
|
/**
|
|
@@ -340,7 +339,7 @@ export class ConfigProvider {
|
|
|
340
339
|
this.initLocales();
|
|
341
340
|
}
|
|
342
341
|
} catch (e) {
|
|
343
|
-
if (
|
|
342
|
+
if (isDebugMode('error')) console.error('[ConfigProvider] lazy initLocales failed', e);
|
|
344
343
|
}
|
|
345
344
|
|
|
346
345
|
const localeObj =
|
|
@@ -386,13 +385,13 @@ export class ConfigProvider {
|
|
|
386
385
|
*/
|
|
387
386
|
setTheme(themeName: string) {
|
|
388
387
|
if (!this.themesRef.value || this.themesRef.value.length === 0) {
|
|
389
|
-
console.warn('[ConfigProvider] setTheme called but themes list empty');
|
|
388
|
+
if (isDebugMode('warn')) console.warn('[ConfigProvider] setTheme called but themes list empty');
|
|
390
389
|
return;
|
|
391
390
|
}
|
|
392
391
|
|
|
393
392
|
const theme = this.themesRef.value.find(t => t.name === themeName);
|
|
394
393
|
if (!theme) {
|
|
395
|
-
console.warn('[ConfigProvider] theme not found:', themeName);
|
|
394
|
+
if (isDebugMode('warn')) console.warn('[ConfigProvider] theme not found:', themeName);
|
|
396
395
|
return;
|
|
397
396
|
}
|
|
398
397
|
|
|
@@ -404,7 +403,7 @@ export class ConfigProvider {
|
|
|
404
403
|
// 持久化
|
|
405
404
|
this.writeStorage(THEME_STORAGE_KEY, themeName);
|
|
406
405
|
|
|
407
|
-
if (
|
|
406
|
+
if (isDebugMode()) console.log('[ConfigProvider] setTheme ->', themeName);
|
|
408
407
|
}
|
|
409
408
|
|
|
410
409
|
/**
|
|
@@ -414,7 +413,7 @@ export class ConfigProvider {
|
|
|
414
413
|
public setThemeColor(colors: Partial<ThemeColor>) {
|
|
415
414
|
if (!colors || Object.keys(colors).length === 0) return;
|
|
416
415
|
if (!this.currentThemeRef.value) {
|
|
417
|
-
console.warn('[ConfigProvider] setThemeColor called but no current theme');
|
|
416
|
+
if (isDebugMode('warn')) console.warn('[ConfigProvider] setThemeColor called but no current theme');
|
|
418
417
|
return;
|
|
419
418
|
}
|
|
420
419
|
|
|
@@ -437,7 +436,7 @@ export class ConfigProvider {
|
|
|
437
436
|
// 重新应用当前主题以同步运行时 color、CSS 变量等
|
|
438
437
|
this.applyTheme(this.currentThemeRef.value);
|
|
439
438
|
|
|
440
|
-
if (
|
|
439
|
+
if (isDebugMode()) console.log('[ConfigProvider] setThemeColor ->', colors);
|
|
441
440
|
}
|
|
442
441
|
|
|
443
442
|
/**
|
|
@@ -459,7 +458,7 @@ export class ConfigProvider {
|
|
|
459
458
|
// 重新应用主题
|
|
460
459
|
this.applyTheme(this.currentThemeRef.value);
|
|
461
460
|
|
|
462
|
-
if (
|
|
461
|
+
if (isDebugMode()) console.log('[ConfigProvider] setDarkMode ->', mode);
|
|
463
462
|
}
|
|
464
463
|
|
|
465
464
|
/**
|
|
@@ -637,7 +636,7 @@ export class ConfigProvider {
|
|
|
637
636
|
uni.$u.color = reactiveColor;
|
|
638
637
|
}
|
|
639
638
|
} catch (e) {
|
|
640
|
-
if (
|
|
639
|
+
if (isDebugMode('error')) console.error('[ConfigProvider] sync runtime theme failed', e);
|
|
641
640
|
}
|
|
642
641
|
}
|
|
643
642
|
|
|
@@ -677,7 +676,7 @@ export class ConfigProvider {
|
|
|
677
676
|
const value = uni.getStorageSync(key);
|
|
678
677
|
return (value ?? null) as T | null;
|
|
679
678
|
} catch (e) {
|
|
680
|
-
if (
|
|
679
|
+
if (isDebugMode('error')) console.error('[ConfigProvider] failed to read storage', e);
|
|
681
680
|
return null;
|
|
682
681
|
}
|
|
683
682
|
}
|
|
@@ -690,7 +689,7 @@ export class ConfigProvider {
|
|
|
690
689
|
if (typeof uni === 'undefined' || typeof uni.setStorageSync !== 'function') return;
|
|
691
690
|
uni.setStorageSync(key, value);
|
|
692
691
|
} catch (e) {
|
|
693
|
-
if (
|
|
692
|
+
if (isDebugMode('error')) console.error('[ConfigProvider] failed to write storage', e);
|
|
694
693
|
}
|
|
695
694
|
}
|
|
696
695
|
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "uview-pro",
|
|
3
3
|
"name": "uview-pro",
|
|
4
4
|
"displayName": "【支持鸿蒙】uView Pro|基于Vue3+TS的高质量UI组件库,支持多主题、暗黑模式、多语言",
|
|
5
|
-
"version": "0.5.
|
|
5
|
+
"version": "0.5.16",
|
|
6
6
|
"description": "uView Pro是基于Vue3+TS的多平台UI框架,提供80+高质量组件、便捷工具和常用模板,支持多主题、暗黑模式、多语言,支持H5/APP/鸿蒙/小程序多端开发。已在鸿蒙应用商店上架,欢迎体验!",
|
|
7
7
|
"main": "index.ts",
|
|
8
8
|
"module": "index.ts",
|
|
@@ -80,7 +80,8 @@
|
|
|
80
80
|
"jd": "-",
|
|
81
81
|
"harmony": "√",
|
|
82
82
|
"qq": "√",
|
|
83
|
-
"lark": "-"
|
|
83
|
+
"lark": "-",
|
|
84
|
+
"xhs": "-"
|
|
84
85
|
},
|
|
85
86
|
"quickapp": {
|
|
86
87
|
"huawei": "-",
|
package/types/global.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export type ThemeType = 'primary' | 'info' | 'error' | 'warning' | 'success' | 'default';
|
|
2
2
|
|
|
3
|
+
export type SizeType = 'default' | 'small' | 'large';
|
|
4
|
+
|
|
3
5
|
export type ImgMode = 'aspectFit' | 'aspectFill' | 'widthFix' | 'top' | 'bottom' | 'center' | 'scaleToFill';
|
|
4
6
|
|
|
5
7
|
export type Direction = 'horizontal' | 'vertical';
|
|
@@ -43,7 +45,7 @@ export type BadgeSize = 'default' | 'mini';
|
|
|
43
45
|
// button 按钮类型
|
|
44
46
|
export type ButtonType = 'primary' | 'info' | 'error' | 'warning' | 'success' | 'default';
|
|
45
47
|
// button 按钮尺寸
|
|
46
|
-
export type ButtonSize = 'default' | 'medium' | 'mini';
|
|
48
|
+
export type ButtonSize = SizeType | 'default' | 'medium' | 'mini';
|
|
47
49
|
// button 按钮 form-type
|
|
48
50
|
export type ButtonFormType = '' | 'submit' | 'reset';
|
|
49
51
|
// button 按钮 scope
|
|
@@ -150,6 +152,7 @@ export type InputType =
|
|
|
150
152
|
| 'email'
|
|
151
153
|
| 'safe-password'
|
|
152
154
|
| 'name'
|
|
155
|
+
| 'nickname'
|
|
153
156
|
| 'bank-card'
|
|
154
157
|
| 'tel'
|
|
155
158
|
| 'select';
|
|
@@ -290,7 +293,7 @@ export type TagMode = 'light' | 'dark' | 'plain';
|
|
|
290
293
|
// tag 组件 shape
|
|
291
294
|
export type TagShape = 'square' | 'circle' | 'circleLeft' | 'circleRight';
|
|
292
295
|
// tag 组件 size
|
|
293
|
-
export type TagSize = 'default' | 'mini'
|
|
296
|
+
export type TagSize = 'default' | 'mini';
|
|
294
297
|
// toast 组件 position
|
|
295
298
|
export type ToastPosition = 'top' | 'center' | 'bottom';
|
|
296
299
|
export type UploadSizeType = 'original' | 'compressed';
|
|
@@ -395,12 +398,6 @@ export type Themes = {
|
|
|
395
398
|
isForce?: boolean;
|
|
396
399
|
};
|
|
397
400
|
|
|
398
|
-
export type LogConfig = Partial<{
|
|
399
|
-
debug?: boolean;
|
|
400
|
-
prefix?: string;
|
|
401
|
-
showCallerInfo?: boolean;
|
|
402
|
-
}>;
|
|
403
|
-
|
|
404
401
|
export type Locales = {
|
|
405
402
|
locales: Locale[];
|
|
406
403
|
defaultLocale?: string;
|
|
@@ -412,10 +409,12 @@ export type Locale = {
|
|
|
412
409
|
[key: string]: any;
|
|
413
410
|
};
|
|
414
411
|
|
|
412
|
+
export type DebugMode = 'log' | 'warn' | 'error' | 'info';
|
|
413
|
+
|
|
415
414
|
export interface UViewProOptions {
|
|
416
415
|
theme?: ThemeColor | Theme[] | Themes;
|
|
417
|
-
log?: LogConfig;
|
|
418
416
|
locale?: string | Locale[] | Locales;
|
|
417
|
+
debugMode?: boolean | DebugMode | DebugMode[];
|
|
419
418
|
// 可扩展更多配置项
|
|
420
419
|
}
|
|
421
420
|
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { PropType } from 'vue';
|
|
2
|
-
|
|
3
|
-
export const stringProp = <T>(defaultVal: T) => ({
|
|
4
|
-
type: String as unknown as PropType<T>,
|
|
5
|
-
default: defaultVal
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
export const stringOrObjectProp = <T>(defaultVal: T) => ({
|
|
9
|
-
type: [String, Object] as PropType<string | Record<string, any>>,
|
|
10
|
-
default: defaultVal
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
export const baseProps = {
|
|
14
|
-
/**
|
|
15
|
-
* 自定义根节点样式
|
|
16
|
-
*/
|
|
17
|
-
customStyle: stringOrObjectProp(''),
|
|
18
|
-
/**
|
|
19
|
-
* 自定义根节点样式类
|
|
20
|
-
*/
|
|
21
|
-
customClass: stringProp('')
|
|
22
|
-
};
|