@zfqh/uview-x 0.0.0-stage → 0.0.2
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 +16 -0
- package/LICENSE +21 -0
- package/README.md +127 -3
- package/components/uv-badge/props.ts +83 -0
- package/components/uv-badge/uv-badge.vue +186 -0
- package/components/uv-button/props.ts +148 -0
- package/components/uv-button/uv-button.vue +565 -0
- package/components/uv-checkbox/props.ts +83 -0
- package/components/uv-checkbox/uv-checkbox.vue +403 -0
- package/components/uv-checkbox-group/props.ts +97 -0
- package/components/uv-checkbox-group/uv-checkbox-group.vue +163 -0
- package/components/uv-code/props.ts +48 -0
- package/components/uv-code/uv-code.vue +156 -0
- package/components/uv-dialog/props.ts +56 -0
- package/components/uv-dialog/uv-dialog.vue +492 -0
- package/components/uv-form/props.ts +59 -0
- package/components/uv-form/uv-form.vue +256 -0
- package/components/uv-form/valid.ts +1344 -0
- package/components/uv-form-item/props.ts +62 -0
- package/components/uv-form-item/uv-form-item.vue +335 -0
- package/components/uv-icon/icons.ts +161 -0
- package/components/uv-icon/props.ts +91 -0
- package/components/uv-icon/uv-icon.vue +208 -0
- package/components/uv-icon/uvicons.ttf +0 -0
- package/components/uv-input/props.ts +185 -0
- package/components/uv-input/uv-input.vue +431 -0
- package/components/uv-line/props.ts +42 -0
- package/components/uv-line/uv-line.vue +75 -0
- package/components/uv-line-progress/props.ts +43 -0
- package/components/uv-line-progress/uv-line-progress.vue +166 -0
- package/components/uv-loading-icon/props.ts +78 -0
- package/components/uv-loading-icon/uv-loading-icon.vue +226 -0
- package/components/uv-overlay/props.ts +38 -0
- package/components/uv-overlay/uv-overlay.vue +120 -0
- package/components/uv-popup/props.ts +101 -0
- package/components/uv-popup/uv-popup.vue +371 -0
- package/components/uv-safe-bottom/props.ts +18 -0
- package/components/uv-safe-bottom/uv-safe-bottom.vue +120 -0
- package/components/uv-status-bar/props.ts +22 -0
- package/components/uv-status-bar/uv-status-bar.vue +121 -0
- package/components/uv-tabs/props.ts +84 -0
- package/components/uv-tabs/uv-tabs.vue +432 -0
- package/components/uv-transition/props.ts +38 -0
- package/components/uv-transition/uv-transition.vue +170 -0
- package/hooks/index.ts +5 -0
- package/hooks/useDebounce.ts +35 -0
- package/hooks/useI18n.ts +95 -0
- package/hooks/useThrottle.ts +38 -0
- package/index.ts +23 -0
- package/libs/dayjs/index.ts +217 -0
- package/libs/index.ts +4 -0
- package/libs/luch-request/adapters/index.ts +133 -0
- package/libs/luch-request/core/InterceptorManager.ts +52 -0
- package/libs/luch-request/core/Request.ts +202 -0
- package/libs/luch-request/core/buildFullPath.ts +21 -0
- package/libs/luch-request/core/defaults.ts +34 -0
- package/libs/luch-request/core/dispatchRequest.ts +7 -0
- package/libs/luch-request/core/mergeConfig.ts +127 -0
- package/libs/luch-request/core/settle.ts +17 -0
- package/libs/luch-request/helpers/buildURL.ts +65 -0
- package/libs/luch-request/helpers/combineURLs.ts +15 -0
- package/libs/luch-request/helpers/isAbsoluteURL.ts +15 -0
- package/libs/luch-request/index.d.ts +197 -0
- package/libs/luch-request/index.ts +3 -0
- package/libs/luch-request/utils/clone.ts +265 -0
- package/libs/luch-request/utils.ts +136 -0
- package/locales/en.ts +78 -0
- package/locales/index.ts +169 -0
- package/locales/zh-Hans.ts +78 -0
- package/package.json +42 -4
- package/styles/color.scss +33 -0
- package/styles/common.scss +134 -0
- package/styles/components.scss +19 -0
- package/styles/index.scss +7 -0
- package/styles/theme.scss +44 -0
- package/styles/var.module.scss +32 -0
- package/styles/vue.scss +39 -0
- package/theme.scss +2 -0
- package/types/index.d.ts +66 -0
- package/utils/colorGradient.ts +139 -0
- package/utils/compat.ts +165 -0
- package/utils/compress.ts +34 -0
- package/utils/config.ts +95 -0
- package/utils/debounce.ts +7 -0
- package/utils/digit.ts +157 -0
- package/utils/function.ts +771 -0
- package/utils/http.ts +5 -0
- package/utils/index.ts +57 -0
- package/utils/locale.ts +296 -0
- package/utils/platform.ts +71 -0
- package/utils/route.ts +142 -0
- package/utils/test.ts +256 -0
- package/utils/throttle.ts +7 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 求两个颜色之间的渐变值
|
|
3
|
+
* @param {string} startColor 开始的颜色
|
|
4
|
+
* @param {string} endColor 结束的颜色
|
|
5
|
+
* @param {number} step 颜色等分的份额
|
|
6
|
+
* */
|
|
7
|
+
export function colorGradient(
|
|
8
|
+
startColor = 'rgb(0, 0, 0)',
|
|
9
|
+
endColor = 'rgb(255, 255, 255)',
|
|
10
|
+
step = 10
|
|
11
|
+
): string[] {
|
|
12
|
+
const startRGB = hexToRgb(startColor, false) as number[] // 转换为rgb数组模式
|
|
13
|
+
const startR = startRGB[0]
|
|
14
|
+
const startG = startRGB[1]
|
|
15
|
+
const startB = startRGB[2]
|
|
16
|
+
|
|
17
|
+
const endRGB = hexToRgb(endColor, false) as number[]
|
|
18
|
+
const endR = endRGB[0]
|
|
19
|
+
const endG = endRGB[1]
|
|
20
|
+
const endB = endRGB[2]
|
|
21
|
+
|
|
22
|
+
const sR = (endR - startR) / step // 总差值
|
|
23
|
+
const sG = (endG - startG) / step
|
|
24
|
+
const sB = (endB - startB) / step
|
|
25
|
+
const colorArr = []
|
|
26
|
+
for (let i = 0; i < step; i++) {
|
|
27
|
+
// 计算每一步的hex值
|
|
28
|
+
let hex = rgbToHex(`rgb(${Math.round((sR * i + startR))},${Math.round((sG * i + startG))},${Math.round((sB
|
|
29
|
+
* i + startB))})`)
|
|
30
|
+
// 确保第一个颜色值为startColor的值
|
|
31
|
+
if (i === 0) hex = rgbToHex(startColor)
|
|
32
|
+
// 确保最后一个颜色值为endColor的值
|
|
33
|
+
if (i === step - 1) hex = rgbToHex(endColor)
|
|
34
|
+
colorArr.push(hex)
|
|
35
|
+
}
|
|
36
|
+
return colorArr
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 将颜色转换为 RGB。
|
|
41
|
+
*
|
|
42
|
+
* @param sColor 颜色字符串,支持 `#rgb`、`#rrggbb`、`rgb(...)`。
|
|
43
|
+
* @param str 为 `true`(默认)时返回 `rgb(r,g,b)` 字符串;为 `false` 时返回 `[r,g,b]` 数组。
|
|
44
|
+
* @returns `str=false` 时返回 RGB 数组;否则返回 rgb 字符串;无法识别的颜色原样返回。
|
|
45
|
+
*/
|
|
46
|
+
export function hexToRgb(sColor: string, str = true): string | number[] {
|
|
47
|
+
const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
|
|
48
|
+
sColor = String(sColor).toLowerCase()
|
|
49
|
+
if (sColor && reg.test(sColor)) {
|
|
50
|
+
if (sColor.length === 4) {
|
|
51
|
+
let sColorNew = '#'
|
|
52
|
+
for (let i = 1; i < 4; i += 1) {
|
|
53
|
+
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
|
|
54
|
+
}
|
|
55
|
+
sColor = sColorNew
|
|
56
|
+
}
|
|
57
|
+
// 处理六位的颜色值
|
|
58
|
+
const sColorChange = []
|
|
59
|
+
for (let i = 1; i < 7; i += 2) {
|
|
60
|
+
sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`))
|
|
61
|
+
}
|
|
62
|
+
if (!str) {
|
|
63
|
+
return sColorChange
|
|
64
|
+
}
|
|
65
|
+
return `rgb(${sColorChange[0]},${sColorChange[1]},${sColorChange[2]})`
|
|
66
|
+
} if (/^(rgb|RGB)/.test(sColor)) {
|
|
67
|
+
const arr = sColor.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')
|
|
68
|
+
return arr.map((val) => Number(val))
|
|
69
|
+
}
|
|
70
|
+
return sColor
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 将rgb表示方式转换为hex表示方式
|
|
74
|
+
export function rgbToHex(rgb: string): string {
|
|
75
|
+
const _this = rgb
|
|
76
|
+
const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
|
|
77
|
+
if (/^(rgb|RGB)/.test(_this)) {
|
|
78
|
+
const aColor = _this.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')
|
|
79
|
+
let strHex = '#'
|
|
80
|
+
for (let i = 0; i < aColor.length; i++) {
|
|
81
|
+
let hex = Number(aColor[i]).toString(16)
|
|
82
|
+
hex = String(hex).length == 1 ? `${0}${hex}` : hex // 保证每个rgb的值为2位
|
|
83
|
+
if (hex === '0') {
|
|
84
|
+
hex += hex
|
|
85
|
+
}
|
|
86
|
+
strHex += hex
|
|
87
|
+
}
|
|
88
|
+
if (strHex.length !== 7) {
|
|
89
|
+
strHex = _this
|
|
90
|
+
}
|
|
91
|
+
return strHex
|
|
92
|
+
} if (reg.test(_this)) {
|
|
93
|
+
const aNum = _this.replace(/#/, '').split('')
|
|
94
|
+
if (aNum.length === 6) {
|
|
95
|
+
return _this
|
|
96
|
+
} if (aNum.length === 3) {
|
|
97
|
+
let numHex = '#'
|
|
98
|
+
for (let i = 0; i < aNum.length; i += 1) {
|
|
99
|
+
numHex += (aNum[i] + aNum[i])
|
|
100
|
+
}
|
|
101
|
+
return numHex
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
return _this
|
|
105
|
+
}
|
|
106
|
+
// 合法 hex 但长度不是 3/6 时保持原值返回,保证返回类型为 string
|
|
107
|
+
return _this
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* JS颜色十六进制转换为rgb或rgba,返回的格式为 rgba(255,255,255,0.5)字符串
|
|
112
|
+
* sHex为传入的十六进制的色值
|
|
113
|
+
* alpha为rgba的透明度
|
|
114
|
+
*/
|
|
115
|
+
export function colorToRgba(color: string, alpha: number): string {
|
|
116
|
+
color = rgbToHex(color)
|
|
117
|
+
// 十六进制颜色值的正则表达式
|
|
118
|
+
const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
|
|
119
|
+
/* 16进制颜色转为RGB格式 */
|
|
120
|
+
let sColor = String(color).toLowerCase()
|
|
121
|
+
if (sColor && reg.test(sColor)) {
|
|
122
|
+
if (sColor.length === 4) {
|
|
123
|
+
let sColorNew = '#'
|
|
124
|
+
for (let i = 1; i < 4; i += 1) {
|
|
125
|
+
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
|
|
126
|
+
}
|
|
127
|
+
sColor = sColorNew
|
|
128
|
+
}
|
|
129
|
+
// 处理六位的颜色值
|
|
130
|
+
const sColorChange = []
|
|
131
|
+
for (let i = 1; i < 7; i += 2) {
|
|
132
|
+
sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`))
|
|
133
|
+
}
|
|
134
|
+
// return sColorChange.join(',')
|
|
135
|
+
return `rgba(${sColorChange.join(',')},${alpha})`
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return sColor
|
|
139
|
+
}
|
package/utils/compat.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uv-ui 选项式 mixin 能力的组合式替代。
|
|
3
|
+
*
|
|
4
|
+
* 这些方法不依赖 Vue 运行时 API,可在 `.vue` 的 `<script setup>` 中直接使用,
|
|
5
|
+
* 也可在普通 `.ts` 模块中调用,避免 uni-app x Vapor 下的 mixin 限制。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
type ValueGetter = (key: string) => any;
|
|
9
|
+
|
|
10
|
+
/** nvue 原生 dom 插件返回的节点尺寸 */
|
|
11
|
+
export interface DomRectSize {
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
top?: number;
|
|
15
|
+
right?: number;
|
|
16
|
+
bottom?: number;
|
|
17
|
+
left?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** `uni.requireNativePlugin('dom')` 的返回类型(nvue 专属) */
|
|
21
|
+
export interface DomPlugin {
|
|
22
|
+
addRule(name: string, rule: string | Record<string, unknown>): void;
|
|
23
|
+
getComponentRect(component: unknown, callback: (res: { size?: DomRectSize }) => void): void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** `uni.requireNativePlugin('animation')` 的返回类型(nvue 专属) */
|
|
27
|
+
export interface AnimationPlugin {
|
|
28
|
+
transition(node: unknown, options: Record<string, unknown>, callback?: () => void): void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 生成 BEM 类名数组(替代 mixin 中的 `bem()`)。
|
|
33
|
+
*
|
|
34
|
+
* 仅返回扁平类名,符合 Vapor 只支持 class 选择器的约束。
|
|
35
|
+
*
|
|
36
|
+
* @param name 组件名(不含 `uv-` 前缀),如 `button`
|
|
37
|
+
* @param getValue 读取属性值的函数,通常为 `(key) => props[key]`
|
|
38
|
+
* @param fixed 固定拼接到类名上的属性名,如 `['type', 'size']`
|
|
39
|
+
* @param change 仅在值为真时拼接的属性名,如 `['plain', 'disabled']`
|
|
40
|
+
*/
|
|
41
|
+
export function createBem(name: string, getValue: ValueGetter, fixed: string[] = [], change: string[] = []): string[] {
|
|
42
|
+
const prefix = `uv-${name}--`;
|
|
43
|
+
const classes: string[] = [];
|
|
44
|
+
fixed.forEach((item) => {
|
|
45
|
+
const value = getValue(item);
|
|
46
|
+
if (value !== undefined && value !== null && value !== '') {
|
|
47
|
+
classes.push(prefix + value);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
change.forEach((item) => {
|
|
51
|
+
if (getValue(item)) {
|
|
52
|
+
classes.push(prefix + item);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return classes;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 查询组件内节点尺寸/位置(替代 mixin 的 `$uvGetRect`)。
|
|
60
|
+
*
|
|
61
|
+
* @param instance 组件实例(`getCurrentInstance()!.proxy` 或 `.proxy`)
|
|
62
|
+
* @param selector 仅支持 `#id` / `.class`
|
|
63
|
+
* @param all 是否查询全部匹配节点
|
|
64
|
+
*/
|
|
65
|
+
export function getRect(instance: any, selector: string, all = false): Promise<any> {
|
|
66
|
+
return new Promise((resolve) => {
|
|
67
|
+
let settled = false;
|
|
68
|
+
const done = (value: any) => {
|
|
69
|
+
if (settled) return;
|
|
70
|
+
settled = true;
|
|
71
|
+
resolve(value);
|
|
72
|
+
};
|
|
73
|
+
const timer = setTimeout(() => done(null), 600);
|
|
74
|
+
const query = uni.createSelectorQuery().in(instance);
|
|
75
|
+
const nodes = all ? query.selectAll(selector) : query.select(selector);
|
|
76
|
+
nodes
|
|
77
|
+
.boundingClientRect((rect: any) => {
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
if (all && Array.isArray(rect) && rect.length) {
|
|
80
|
+
done(rect);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!all && rect) {
|
|
84
|
+
done(rect);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
done(null);
|
|
88
|
+
})
|
|
89
|
+
.exec();
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* nvue 节点测量:nvue 不支持 uni.createSelectorQuery,使用原生 dom 模块。
|
|
95
|
+
* 非 nvue 环境返回 null,调用方自行回退。
|
|
96
|
+
*/
|
|
97
|
+
export function getRectNvue(ref: any): Promise<any> {
|
|
98
|
+
const requireNativePlugin = uni.requireNativePlugin;
|
|
99
|
+
if (typeof requireNativePlugin !== 'function' || !ref) {
|
|
100
|
+
return Promise.resolve(null);
|
|
101
|
+
}
|
|
102
|
+
const dom = requireNativePlugin('dom') as DomPlugin | undefined;
|
|
103
|
+
if (!dom || typeof dom.getComponentRect !== 'function') {
|
|
104
|
+
return Promise.resolve(null);
|
|
105
|
+
}
|
|
106
|
+
return new Promise((resolve) => {
|
|
107
|
+
let settled = false;
|
|
108
|
+
const done = (value: any) => {
|
|
109
|
+
if (settled) return;
|
|
110
|
+
settled = true;
|
|
111
|
+
resolve(value);
|
|
112
|
+
};
|
|
113
|
+
const timer = setTimeout(() => done(null), 600);
|
|
114
|
+
dom.getComponentRect(ref, (res: any) => {
|
|
115
|
+
clearTimeout(timer);
|
|
116
|
+
done(res && res.size ? res.size : null);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** 页面跳转(替代 mixin 的 `openPage`)。 */
|
|
122
|
+
export function openPage(url: string, linkType = 'navigateTo'): void {
|
|
123
|
+
if (!url) return;
|
|
124
|
+
switch (linkType) {
|
|
125
|
+
case 'navigateTo':
|
|
126
|
+
case 'to':
|
|
127
|
+
uni.navigateTo({ url });
|
|
128
|
+
break;
|
|
129
|
+
case 'redirectTo':
|
|
130
|
+
case 'redirect':
|
|
131
|
+
uni.redirectTo({ url });
|
|
132
|
+
break;
|
|
133
|
+
case 'switchTab':
|
|
134
|
+
case 'tab':
|
|
135
|
+
uni.switchTab({ url });
|
|
136
|
+
break;
|
|
137
|
+
case 'reLaunch':
|
|
138
|
+
case 'launch':
|
|
139
|
+
uni.reLaunch({ url });
|
|
140
|
+
break;
|
|
141
|
+
case 'navigateBack':
|
|
142
|
+
case 'back':
|
|
143
|
+
uni.navigateBack({});
|
|
144
|
+
break;
|
|
145
|
+
default:
|
|
146
|
+
uni.navigateTo({ url });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** 阻止事件冒泡。 */
|
|
151
|
+
export function preventEvent(e: any): void {
|
|
152
|
+
if (e && typeof e.stopPropagation === 'function') {
|
|
153
|
+
e.stopPropagation();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** 空操作,仅阻止冒泡。 */
|
|
158
|
+
export function noop(e: any): void {
|
|
159
|
+
preventEvent(e);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** 判断是否为有效的 rpx/rpx 数值字符串(供选区/尺寸计算复用)。 */
|
|
163
|
+
export function isNumberLike(value: any): boolean {
|
|
164
|
+
return /^-?\d+(\.\d+)?$/.test(String(value));
|
|
165
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface CompressOptions {
|
|
2
|
+
width?: number | string
|
|
3
|
+
height?: number | string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function image(url: string, style?: CompressOptions): string {
|
|
7
|
+
url = String(url || '')
|
|
8
|
+
if (/^https?:\/\//.test(url)) {
|
|
9
|
+
const { width, height } = style || {}
|
|
10
|
+
let params = ''
|
|
11
|
+
if (/\d+(r?px)?$/.test(String(width))) {
|
|
12
|
+
const size = Number.parseFloat(String(width))
|
|
13
|
+
params = `imageMogr2/thumbnail/${size}x/format/webp`
|
|
14
|
+
} else if (/\d+(r?px)?$/.test(String(height))) {
|
|
15
|
+
const size = Number.parseFloat(String(height))
|
|
16
|
+
params = `imageMogr2/thumbnail/x${size}/format/webp`
|
|
17
|
+
}
|
|
18
|
+
if (params) {
|
|
19
|
+
if (url.lastIndexOf('?') === -1) {
|
|
20
|
+
return `${url}?${params}`
|
|
21
|
+
}
|
|
22
|
+
if (url.lastIndexOf('imageMogr2/') === -1) {
|
|
23
|
+
return `${url}&${params}`
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return url
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const compress: { image: typeof image } = {
|
|
31
|
+
image
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default compress
|
package/utils/config.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// #ifndef APP-NVUE
|
|
2
|
+
import vars from '../styles/var.module.scss';
|
|
3
|
+
// #endif
|
|
4
|
+
|
|
5
|
+
export interface UviewXColor {
|
|
6
|
+
primary: string;
|
|
7
|
+
primaryDark: string;
|
|
8
|
+
primaryDisabled: string;
|
|
9
|
+
primaryLight: string;
|
|
10
|
+
success: string;
|
|
11
|
+
successDark: string;
|
|
12
|
+
successDisabled: string;
|
|
13
|
+
successLight: string;
|
|
14
|
+
warning: string;
|
|
15
|
+
warningDark: string;
|
|
16
|
+
warningDisabled: string;
|
|
17
|
+
warningLight: string;
|
|
18
|
+
error: string;
|
|
19
|
+
errorDark: string;
|
|
20
|
+
errorDisabled: string;
|
|
21
|
+
errorLight: string;
|
|
22
|
+
info: string;
|
|
23
|
+
infoDark: string;
|
|
24
|
+
infoDisabled: string;
|
|
25
|
+
infoLight: string;
|
|
26
|
+
bgColor: string;
|
|
27
|
+
bgLightColor: string;
|
|
28
|
+
mainColor: string;
|
|
29
|
+
contentColor: string;
|
|
30
|
+
tipsColor: string;
|
|
31
|
+
lightColor: string;
|
|
32
|
+
disabledColor: string;
|
|
33
|
+
borderColor: string;
|
|
34
|
+
[key: string]: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type UviewXProps = Record<string, Record<string, unknown>>;
|
|
38
|
+
|
|
39
|
+
export interface UviewXConfig {
|
|
40
|
+
// 主题名称
|
|
41
|
+
type: string[];
|
|
42
|
+
// 颜色部分,本来可以通过 scss 的 :export 导出供 js 使用,但是 nvue 不支持
|
|
43
|
+
color: UviewXColor;
|
|
44
|
+
// 组件默认 props,一次性合并进各组件的 props 定义
|
|
45
|
+
props: UviewXProps;
|
|
46
|
+
// 默认单位,可以通过配置为 rpx,那么在用于传入组件大小参数为数值时,就默认为 rpx
|
|
47
|
+
unit: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type UviewXColorConfig = Partial<UviewXColor>;
|
|
51
|
+
|
|
52
|
+
// 兜底色板与 styles/color.scss 保持一致;非 nvue 端会由 var.module.scss 覆盖为实际主题色
|
|
53
|
+
const color: UviewXColor = {
|
|
54
|
+
primary: '#00b4c3',
|
|
55
|
+
primaryDark: '#157572',
|
|
56
|
+
primaryDisabled: '#b4e3d9',
|
|
57
|
+
primaryLight: '#dff3f9',
|
|
58
|
+
success: '#5ac725',
|
|
59
|
+
successDark: '#53c21d',
|
|
60
|
+
successDisabled: '#a9e08f',
|
|
61
|
+
successLight: '#f5fff0',
|
|
62
|
+
warning: '#ff9a05',
|
|
63
|
+
warningDark: '#ed6c04',
|
|
64
|
+
warningDisabled: '#f9d39b',
|
|
65
|
+
warningLight: '#fdf6ec',
|
|
66
|
+
error: '#ff4d4f',
|
|
67
|
+
errorDark: '#e45656',
|
|
68
|
+
errorDisabled: '#f7b2b2',
|
|
69
|
+
errorLight: '#fef0f0',
|
|
70
|
+
info: '#909399',
|
|
71
|
+
infoDark: '#767a82',
|
|
72
|
+
infoDisabled: '#c4c6c9',
|
|
73
|
+
infoLight: '#f4f4f5',
|
|
74
|
+
bgColor: '#f5f5f5',
|
|
75
|
+
bgLightColor: '#fffbf4',
|
|
76
|
+
mainColor: '#333333',
|
|
77
|
+
contentColor: '#7a7a7a',
|
|
78
|
+
tipsColor: '#9a9a9a',
|
|
79
|
+
lightColor: '#c0c4cc',
|
|
80
|
+
disabledColor: '#c8c9cc',
|
|
81
|
+
borderColor: '#eeeeee',
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// #ifndef APP-NVUE
|
|
85
|
+
Object.assign(color, vars);
|
|
86
|
+
// #endif
|
|
87
|
+
|
|
88
|
+
const config: UviewXConfig = {
|
|
89
|
+
type: ['primary', 'success', 'info', 'error', 'warning'],
|
|
90
|
+
color,
|
|
91
|
+
props: {},
|
|
92
|
+
unit: 'px',
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export default config;
|
package/utils/digit.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
let _boundaryCheckingState = true; // 是否进行越界检查的全局开关
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 把错误的数据转正
|
|
5
|
+
* @private
|
|
6
|
+
* @example strip(0.09999999999999998)=0.1
|
|
7
|
+
*/
|
|
8
|
+
function strip(num: number, precision = 15): number {
|
|
9
|
+
return +parseFloat(Number(num).toPrecision(precision));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Return digits length of a number
|
|
14
|
+
* @private
|
|
15
|
+
* @param {*number} num Input number
|
|
16
|
+
*/
|
|
17
|
+
function digitLength(num: number): number {
|
|
18
|
+
// Get digit length of e
|
|
19
|
+
const eSplit = num.toString().split(/[eE]/);
|
|
20
|
+
const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0);
|
|
21
|
+
return len > 0 ? len : 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 把小数转成整数,如果是小数则放大成整数
|
|
26
|
+
* @private
|
|
27
|
+
* @param {*number} num 输入数
|
|
28
|
+
*/
|
|
29
|
+
function float2Fixed(num: number): number {
|
|
30
|
+
if (num.toString().indexOf('e') === -1) {
|
|
31
|
+
return Number(num.toString().replace('.', ''));
|
|
32
|
+
}
|
|
33
|
+
const dLen = digitLength(num);
|
|
34
|
+
return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 检测数字是否越界,如果越界给出提示
|
|
39
|
+
* @private
|
|
40
|
+
* @param {*number} num 输入数
|
|
41
|
+
*/
|
|
42
|
+
function checkBoundary(num: number): void {
|
|
43
|
+
if (_boundaryCheckingState) {
|
|
44
|
+
if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
|
|
45
|
+
console.warn(`${num} 超出了精度限制,结果可能不正确`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 把递归操作扁平迭代化
|
|
52
|
+
* @param {number[]} arr 要操作的数字数组
|
|
53
|
+
* @param {function} operation 迭代操作
|
|
54
|
+
* @private
|
|
55
|
+
*/
|
|
56
|
+
function iteratorOperation(arr: number[], operation: (a: number, b: number) => number): number {
|
|
57
|
+
const [num1, num2, ...others] = arr;
|
|
58
|
+
let res = operation(num1, num2);
|
|
59
|
+
|
|
60
|
+
others.forEach((num) => {
|
|
61
|
+
res = operation(res, num);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
return res;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 高精度乘法
|
|
69
|
+
* @export
|
|
70
|
+
*/
|
|
71
|
+
export function times(...nums: number[]): number {
|
|
72
|
+
if (nums.length > 2) {
|
|
73
|
+
return iteratorOperation(nums, times);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const [num1, num2] = nums;
|
|
77
|
+
const num1Changed = float2Fixed(num1);
|
|
78
|
+
const num2Changed = float2Fixed(num2);
|
|
79
|
+
const baseNum = digitLength(num1) + digitLength(num2);
|
|
80
|
+
const leftValue = num1Changed * num2Changed;
|
|
81
|
+
|
|
82
|
+
checkBoundary(leftValue);
|
|
83
|
+
|
|
84
|
+
return leftValue / Math.pow(10, baseNum);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* 高精度加法
|
|
89
|
+
* @export
|
|
90
|
+
*/
|
|
91
|
+
export function plus(...nums: number[]): number {
|
|
92
|
+
if (nums.length > 2) {
|
|
93
|
+
return iteratorOperation(nums, plus);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const [num1, num2] = nums;
|
|
97
|
+
// 取最大的小数位
|
|
98
|
+
const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
|
|
99
|
+
// 把小数都转为整数然后再计算
|
|
100
|
+
return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 高精度减法
|
|
105
|
+
* @export
|
|
106
|
+
*/
|
|
107
|
+
export function minus(...nums: number[]): number {
|
|
108
|
+
if (nums.length > 2) {
|
|
109
|
+
return iteratorOperation(nums, minus);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const [num1, num2] = nums;
|
|
113
|
+
const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
|
|
114
|
+
return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* 高精度除法
|
|
119
|
+
* @export
|
|
120
|
+
*/
|
|
121
|
+
export function divide(...nums: number[]): number {
|
|
122
|
+
if (nums.length > 2) {
|
|
123
|
+
return iteratorOperation(nums, divide);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const [num1, num2] = nums;
|
|
127
|
+
const num1Changed = float2Fixed(num1);
|
|
128
|
+
const num2Changed = float2Fixed(num2);
|
|
129
|
+
checkBoundary(num1Changed);
|
|
130
|
+
checkBoundary(num2Changed);
|
|
131
|
+
// 重要,这里必须用strip进行修正
|
|
132
|
+
return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* 四舍五入
|
|
137
|
+
* @export
|
|
138
|
+
*/
|
|
139
|
+
export function round(num: number, ratio: number): number {
|
|
140
|
+
const base = Math.pow(10, ratio);
|
|
141
|
+
let result = divide(Math.round(Math.abs(times(num, base))), base);
|
|
142
|
+
if (num < 0 && result !== 0) {
|
|
143
|
+
result = times(result, -1);
|
|
144
|
+
}
|
|
145
|
+
// 位数不足则补0
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* 是否进行边界检查,默认开启
|
|
151
|
+
* @param flag 标记开关,true 为开启,false 为关闭,默认为 true
|
|
152
|
+
* @export
|
|
153
|
+
*/
|
|
154
|
+
export function enableBoundaryChecking(flag = true): void {
|
|
155
|
+
_boundaryCheckingState = flag;
|
|
156
|
+
}
|
|
157
|
+
|