@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.
Files changed (93) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/LICENSE +21 -0
  3. package/README.md +127 -3
  4. package/components/uv-badge/props.ts +83 -0
  5. package/components/uv-badge/uv-badge.vue +186 -0
  6. package/components/uv-button/props.ts +148 -0
  7. package/components/uv-button/uv-button.vue +565 -0
  8. package/components/uv-checkbox/props.ts +83 -0
  9. package/components/uv-checkbox/uv-checkbox.vue +403 -0
  10. package/components/uv-checkbox-group/props.ts +97 -0
  11. package/components/uv-checkbox-group/uv-checkbox-group.vue +163 -0
  12. package/components/uv-code/props.ts +48 -0
  13. package/components/uv-code/uv-code.vue +156 -0
  14. package/components/uv-dialog/props.ts +56 -0
  15. package/components/uv-dialog/uv-dialog.vue +492 -0
  16. package/components/uv-form/props.ts +59 -0
  17. package/components/uv-form/uv-form.vue +256 -0
  18. package/components/uv-form/valid.ts +1344 -0
  19. package/components/uv-form-item/props.ts +62 -0
  20. package/components/uv-form-item/uv-form-item.vue +335 -0
  21. package/components/uv-icon/icons.ts +161 -0
  22. package/components/uv-icon/props.ts +91 -0
  23. package/components/uv-icon/uv-icon.vue +208 -0
  24. package/components/uv-icon/uvicons.ttf +0 -0
  25. package/components/uv-input/props.ts +185 -0
  26. package/components/uv-input/uv-input.vue +431 -0
  27. package/components/uv-line/props.ts +42 -0
  28. package/components/uv-line/uv-line.vue +75 -0
  29. package/components/uv-line-progress/props.ts +43 -0
  30. package/components/uv-line-progress/uv-line-progress.vue +166 -0
  31. package/components/uv-loading-icon/props.ts +78 -0
  32. package/components/uv-loading-icon/uv-loading-icon.vue +226 -0
  33. package/components/uv-overlay/props.ts +38 -0
  34. package/components/uv-overlay/uv-overlay.vue +120 -0
  35. package/components/uv-popup/props.ts +101 -0
  36. package/components/uv-popup/uv-popup.vue +371 -0
  37. package/components/uv-safe-bottom/props.ts +18 -0
  38. package/components/uv-safe-bottom/uv-safe-bottom.vue +120 -0
  39. package/components/uv-status-bar/props.ts +22 -0
  40. package/components/uv-status-bar/uv-status-bar.vue +121 -0
  41. package/components/uv-tabs/props.ts +84 -0
  42. package/components/uv-tabs/uv-tabs.vue +432 -0
  43. package/components/uv-transition/props.ts +38 -0
  44. package/components/uv-transition/uv-transition.vue +170 -0
  45. package/hooks/index.ts +5 -0
  46. package/hooks/useDebounce.ts +35 -0
  47. package/hooks/useI18n.ts +95 -0
  48. package/hooks/useThrottle.ts +38 -0
  49. package/index.ts +23 -0
  50. package/libs/dayjs/index.ts +217 -0
  51. package/libs/index.ts +4 -0
  52. package/libs/luch-request/adapters/index.ts +133 -0
  53. package/libs/luch-request/core/InterceptorManager.ts +52 -0
  54. package/libs/luch-request/core/Request.ts +202 -0
  55. package/libs/luch-request/core/buildFullPath.ts +21 -0
  56. package/libs/luch-request/core/defaults.ts +34 -0
  57. package/libs/luch-request/core/dispatchRequest.ts +7 -0
  58. package/libs/luch-request/core/mergeConfig.ts +127 -0
  59. package/libs/luch-request/core/settle.ts +17 -0
  60. package/libs/luch-request/helpers/buildURL.ts +65 -0
  61. package/libs/luch-request/helpers/combineURLs.ts +15 -0
  62. package/libs/luch-request/helpers/isAbsoluteURL.ts +15 -0
  63. package/libs/luch-request/index.d.ts +197 -0
  64. package/libs/luch-request/index.ts +3 -0
  65. package/libs/luch-request/utils/clone.ts +265 -0
  66. package/libs/luch-request/utils.ts +136 -0
  67. package/locales/en.ts +78 -0
  68. package/locales/index.ts +169 -0
  69. package/locales/zh-Hans.ts +78 -0
  70. package/package.json +42 -4
  71. package/styles/color.scss +33 -0
  72. package/styles/common.scss +134 -0
  73. package/styles/components.scss +19 -0
  74. package/styles/index.scss +7 -0
  75. package/styles/theme.scss +44 -0
  76. package/styles/var.module.scss +32 -0
  77. package/styles/vue.scss +39 -0
  78. package/theme.scss +2 -0
  79. package/types/index.d.ts +66 -0
  80. package/utils/colorGradient.ts +139 -0
  81. package/utils/compat.ts +165 -0
  82. package/utils/compress.ts +34 -0
  83. package/utils/config.ts +95 -0
  84. package/utils/debounce.ts +7 -0
  85. package/utils/digit.ts +157 -0
  86. package/utils/function.ts +771 -0
  87. package/utils/http.ts +5 -0
  88. package/utils/index.ts +57 -0
  89. package/utils/locale.ts +296 -0
  90. package/utils/platform.ts +71 -0
  91. package/utils/route.ts +142 -0
  92. package/utils/test.ts +256 -0
  93. package/utils/throttle.ts +7 -0
@@ -0,0 +1,59 @@
1
+ // @ts-nocheck
2
+
3
+ import config from '../../utils/config';
4
+
5
+ const props = {
6
+ // 当前form的需要验证字段的集合
7
+ model: {
8
+ type: Object,
9
+ default: () => ({}),
10
+ },
11
+ // 验证规则
12
+ rules: {
13
+ type: [Object, Function, Array],
14
+ default: () => ({}),
15
+ },
16
+ // 有错误时的提示方式,message-提示信息,toast-进行toast提示
17
+ // border-bottom-下边框呈现红色,none-无提示
18
+ errorType: {
19
+ type: String,
20
+ default: 'message',
21
+ },
22
+ // 是否显示表单域的下划线边框
23
+ borderBottom: {
24
+ type: Boolean,
25
+ default: true,
26
+ },
27
+ // label的位置,left-左边,top-上边
28
+ labelPosition: {
29
+ type: String,
30
+ default: 'left',
31
+ },
32
+ // label的宽度,单位px
33
+ labelWidth: {
34
+ type: [String, Number],
35
+ default: 45,
36
+ },
37
+ // lable字体的对齐方式
38
+ labelAlign: {
39
+ type: String,
40
+ default: 'left',
41
+ },
42
+ // lable的样式,对象形式
43
+ labelStyle: {
44
+ type: Object,
45
+ default: () => ({}),
46
+ },
47
+ customStyle: {
48
+ type: [Object, String],
49
+ default: () => ({}),
50
+ },
51
+ customClass: {
52
+ type: String,
53
+ default: '',
54
+ },
55
+
56
+ ...config.props.form,
57
+ };
58
+
59
+ export default props;
@@ -0,0 +1,256 @@
1
+ <template>
2
+ <view
3
+ class="uv-form"
4
+ :class="[p.customClass]"
5
+ :style="[$uv.addStyle(p.customStyle)]"
6
+ >
7
+ <slot />
8
+ </view>
9
+ </template>
10
+
11
+ <script setup lang="ts">
12
+ import { nextTick, provide, reactive, watch } from 'vue'
13
+ import { $uv } from '../../utils'
14
+ import props from './props'
15
+ import { useI18n } from '../../hooks'
16
+ import { buildFormValidationMessages } from '../../locales'
17
+
18
+ import Schema from './valid.ts'
19
+
20
+ // 去除警告信息
21
+ Schema.warning = function () {}
22
+
23
+ // 内置校验文案(locales/ 的 uv.form.*),用户 rules[].message 仍优先
24
+ const { t } = useI18n({ useScope: 'global' })
25
+
26
+ defineOptions({
27
+ name: 'uv-form',
28
+ // #ifdef UNI-APP-X
29
+ styleIsolation: 'app-and-page',
30
+ // #endif
31
+ virtualHost: true,
32
+ })
33
+
34
+ /**
35
+ * Form 表单
36
+ * @description 此组件一般用于表单场景,可以配置Input输入框,Select弹出框,进行表单验证等。
37
+ * @tutorial https://www.uvui.cn/components/form.html
38
+ * @property {Object} model 当前form的需要验证字段的集合
39
+ * @property {Object | Function | Array} rules 验证规则
40
+ * @property {String} errorType 错误的提示方式,见上方说明 ( 默认 message )
41
+ * @property {Boolean} borderBottom 是否显示表单域的下划线边框 ( 默认 true )
42
+ * @property {String} labelPosition 表单域提示文字的位置,left-左侧,top-上方 ( 默认 'left' )
43
+ * @property {String | Number} labelWidth 提示文字的宽度,单位px ( 默认 45 )
44
+ * @property {String} labelAlign lable字体的对齐方式 ( 默认 'left' )
45
+ * @property {Object} labelStyle lable的样式,对象形式
46
+ * @property {Object} customStyle 定义需要用到的外部样式
47
+ * @example <uv-form labelPosition="left" :model="model1" :rules="rules" ref="form1"></uv-form>
48
+ */
49
+ const p = defineProps(props)
50
+
51
+ // 原始model快照,用于resetFields方法重置表单时使用
52
+ let originalModel: any = null
53
+ // 校验规则(函数形式的规则由 setRules 手动赋值,避免小程序过滤函数)
54
+ let formRules: any = {}
55
+
56
+ // 表单上下文:provide/inject 替代 $parent/children 链
57
+ // 表单上下文 key(与 uv-form-item/uv-input 内 inject 的字符串保持一致)
58
+ const formContext: any = reactive({
59
+ model: p.model,
60
+ originalModel: null,
61
+ errorType: p.errorType,
62
+ borderBottom: p.borderBottom,
63
+ labelPosition: p.labelPosition,
64
+ labelWidth: p.labelWidth,
65
+ labelAlign: p.labelAlign,
66
+ labelStyle: p.labelStyle,
67
+ // 已注册的 uv-form-item 句柄
68
+ items: []
69
+ })
70
+
71
+ // 手动设置校验的规则,如果规则中有函数的话,微信小程序中会过滤掉,所以只能手动调用设置规则
72
+ const setRules = (rules: any) => {
73
+ // 判断是否有规则
74
+ if (!rules || Object.keys(rules).length === 0) return
75
+ if (process.env.NODE_ENV === 'development' && Object.keys(formContext.model || {}).length === 0) {
76
+ $uv.error('设置rules,model必须设置!如果已经设置,请刷新页面。')
77
+ return
78
+ }
79
+ formRules = rules
80
+ }
81
+
82
+ // 注册/注销表单子项
83
+ const register = (handle: any) => {
84
+ formContext.items.push(handle)
85
+ }
86
+ const unregister = (handle: any) => {
87
+ const index = formContext.items.indexOf(handle)
88
+ if (index > -1) formContext.items.splice(index, 1)
89
+ }
90
+
91
+ // 重置model为初始值的快照
92
+ const resetModel = () => {
93
+ // 历遍所有uv-form-item,根据其prop属性,还原model的原始快照
94
+ formContext.items.forEach((child: any) => {
95
+ const prop = child.prop
96
+ const value = $uv.getProperty(originalModel, prop)
97
+ $uv.setProperty(formContext.model, prop, value)
98
+ })
99
+ }
100
+
101
+ // 清空所有uv-form-item组件的内容,本质上是调用了uv-form-item组件中的resetField()方法
102
+ const resetFields = () => {
103
+ resetModel()
104
+ }
105
+
106
+ // 清空校验结果
107
+ const clearValidate = (props?: any) => {
108
+ const propsArr = ([] as any[]).concat(props)
109
+ formContext.items.forEach((child: any) => {
110
+ // 如果uv-form-item的prop在props数组中,则清除对应的校验结果信息
111
+ if (propsArr[0] === undefined || propsArr.includes(child.prop)) {
112
+ child.setMessage(null)
113
+ }
114
+ })
115
+ }
116
+
117
+ // 对部分表单字段进行校验
118
+ const validateField = (value: any, callback?: any, event: string | null = null) => {
119
+ // nextTick是必须的,否则model的变更,可能会延后于此方法的执行
120
+ nextTick(() => {
121
+ // 校验错误信息,返回给回调方法,用于存放所有form-item的错误信息
122
+ const errorsRes: any[] = []
123
+ // 如果为字符串,转为数组
124
+ const values = ([] as any[]).concat(value)
125
+ // 历遍所有子form-item
126
+ formContext.items.forEach((child: any) => {
127
+ // 用于存放form-item的错误信息
128
+ const childErrors: any[] = []
129
+ if (!values.includes(child.prop)) return
130
+ // 获取对应的属性,通过类似'a.b.c'的形式
131
+ const propertyVal = $uv.getProperty(formContext.model, child.prop)
132
+ // 属性链数组
133
+ const propertyChain = String(child.prop).split('.')
134
+ const propertyName = propertyChain[propertyChain.length - 1]
135
+ const rule = formRules[child.prop]
136
+ // 如果不存在对应的规则,直接返回,否则校验器会报错
137
+ if (!rule) return
138
+ // rule规则可为数组形式,也可为对象形式,此处拼接成为数组
139
+ const rules = ([] as any[]).concat(rule)
140
+ // 对rules数组进行校验
141
+ for (let i = 0; i < rules.length; i++) {
142
+ const ruleItem = rules[i]
143
+ // 将uv-form-item的触发器转为数组形式
144
+ const trigger = ([] as any[]).concat(ruleItem && ruleItem.trigger)
145
+ // 如果是有传入触发事件,但是此form-item却没有配置此触发器的话,不执行校验操作
146
+ if (event && !trigger.includes(event)) continue
147
+ // 实例化校验对象,传入构造规则
148
+ const validator = new Schema({
149
+ [propertyName]: ruleItem
150
+ })
151
+ // 使用内置 i18n 校验文案(显式 ruleItem.message 仍优先)
152
+ validator.messages(buildFormValidationMessages((key: string) => String(t(key))))
153
+ validator.validate(
154
+ {
155
+ [propertyName]: propertyVal
156
+ },
157
+ (errors: any) => {
158
+ if ($uv.test.array(errors)) {
159
+ errorsRes.push(...errors)
160
+ childErrors.push(...errors)
161
+ }
162
+ nextTick(() => {
163
+ child.setMessage(childErrors[0] && childErrors[0].message ? childErrors[0].message : null)
164
+ })
165
+ }
166
+ )
167
+ }
168
+ })
169
+ // 执行回调函数
170
+ if (typeof callback === 'function') callback(errorsRes)
171
+ })
172
+ }
173
+
174
+ // 校验全部数据
175
+ const validate = () => {
176
+ return new Promise((resolve, reject) => {
177
+ nextTick(() => {
178
+ // 获取所有form-item的prop,交给validateField方法进行校验
179
+ const formItemProps = formContext.items.map((item: any) => item.prop)
180
+ validateField(formItemProps, (errors: any[]) => {
181
+ if (errors.length) {
182
+ // 如果错误提示方式为toast,则进行提示
183
+ if (formContext.errorType === 'toast') $uv.toast(errors[0].message)
184
+ reject(errors)
185
+ } else {
186
+ resolve(true)
187
+ }
188
+ })
189
+ })
190
+ })
191
+ }
192
+
193
+ formContext.register = register
194
+ formContext.unregister = unregister
195
+ formContext.setRules = setRules
196
+ formContext.resetFields = resetFields
197
+ formContext.resetModel = resetModel
198
+ formContext.clearValidate = clearValidate
199
+ formContext.validateField = validateField
200
+ formContext.validate = validate
201
+
202
+ provide('uv-form-context', formContext)
203
+
204
+ // 监听规则的变化
205
+ watch(
206
+ () => p.rules,
207
+ (rules: any) => {
208
+ setRules(rules)
209
+ },
210
+ { immediate: true }
211
+ )
212
+
213
+ // 监听model的初始值作为重置表单的快照
214
+ watch(
215
+ () => p.model,
216
+ (model: any) => {
217
+ formContext.model = model
218
+ if (!originalModel) {
219
+ originalModel = $uv.deepClone(model)
220
+ formContext.originalModel = originalModel
221
+ }
222
+ },
223
+ { immediate: true }
224
+ )
225
+
226
+ // 监听属性的变化,供 uv-form-item 响应式读取
227
+ watch(
228
+ () => [p.errorType, p.borderBottom, p.labelPosition, p.labelWidth, p.labelAlign, p.labelStyle],
229
+ () => {
230
+ formContext.errorType = p.errorType
231
+ formContext.borderBottom = p.borderBottom
232
+ formContext.labelPosition = p.labelPosition
233
+ formContext.labelWidth = p.labelWidth
234
+ formContext.labelAlign = p.labelAlign
235
+ formContext.labelStyle = p.labelStyle
236
+ }
237
+ )
238
+
239
+ defineExpose({
240
+ setRules,
241
+ resetFields,
242
+ resetModel,
243
+ clearValidate,
244
+ validateField,
245
+ validate
246
+ })
247
+ </script>
248
+
249
+ <style lang="scss">
250
+ @import '../../styles/components.scss';
251
+
252
+ .uv-form {
253
+ display: flex;
254
+ flex-direction: column;
255
+ }
256
+ </style>