uview-ultra 4.5.71 → 4.5.74
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 +1679 -1635
- package/components/up-cropper/up-cropper.vue +1426 -1392
- package/components/up-form/up-form.uvue +281 -276
- package/components/up-form/up-form.vue +14 -6
- package/components/up-form-item/up-form-item.uvue +14 -1
- package/components/up-form-item/up-form-item.vue +14 -2
- package/components/up-input/up-input.uvue +4 -0
- package/components/up-input/up-input.vue +6 -1
- package/components/up-number-keyboard/up-number-keyboard.uvue +7 -1
- package/components/up-number-keyboard/up-number-keyboard.vue +8 -1
- package/components/up-root/root.js +1 -1
- package/components/up-select/up-select.uvue +328 -314
- package/components/up-select/up-select.vue +19 -2
- package/components/up-sticky/up-sticky.vue +4 -1
- package/components/up-upload/props.js +5 -0
- package/components/up-upload/props.uts +5 -0
- package/components/up-upload/types.uts +1 -0
- package/components/up-upload/up-upload.uvue +9 -0
- package/components/up-upload/up-upload.vue +1 -0
- package/components/up-upload/upload.js +2 -0
- package/components/up-upload/upload.uts +2 -0
- package/components/up-upload/utils.js +23 -12
- package/components/up-upload/utils.uts +4 -0
- package/libs/vite/app-icon-font.js +9 -5
- package/package.json +3 -2
- package/types/comps/upload.d.ts +5 -0
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<view class="up-form">
|
|
3
|
-
<slot />
|
|
4
|
-
</view>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script setup lang="uts">
|
|
1
|
+
<template>
|
|
2
|
+
<view class="up-form">
|
|
3
|
+
<slot />
|
|
4
|
+
</view>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup lang="uts">
|
|
8
8
|
import type { PropType } from 'vue'
|
|
9
9
|
import { getCurrentInstance, provide } from 'vue'
|
|
10
10
|
import { ref, reactive, computed, watch } from 'vue'
|
|
11
11
|
import defProps from './form.uts'
|
|
12
12
|
import Schema from "../../libs/util/async-validator.uts";
|
|
13
13
|
import { toast, getProperty, setProperty, deepClone } from '../../libs/function/index.uts';
|
|
14
|
-
import { useUltraUI } from '../../libs/composable/useUltraUI'
|
|
15
|
-
const { children, getChildren, addChild } = useUltraUI()
|
|
16
|
-
const instance = getCurrentInstance()!.proxy!
|
|
17
|
-
import { UPFormRuleItem } from '../../components/up-form/types.uts'
|
|
18
|
-
|
|
19
|
-
type UPFormRules = {
|
|
20
|
-
key: UPFormRuleItem | UPFormRuleItem[];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// 定义组件选项
|
|
24
|
-
defineOptions({
|
|
14
|
+
import { useUltraUI } from '../../libs/composable/useUltraUI'
|
|
15
|
+
const { children, getChildren, addChild } = useUltraUI()
|
|
16
|
+
const instance = getCurrentInstance()!.proxy!
|
|
17
|
+
import { UPFormRuleItem } from '../../components/up-form/types.uts'
|
|
18
|
+
|
|
19
|
+
type UPFormRules = {
|
|
20
|
+
key: UPFormRuleItem | UPFormRuleItem[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 定义组件选项
|
|
24
|
+
defineOptions({
|
|
25
25
|
styleIsolation: 'app-and-page',
|
|
26
|
-
name: "up-form"
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
// 定义props
|
|
26
|
+
name: "up-form"
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// 定义props
|
|
30
30
|
const props = defineProps({
|
|
31
|
-
customStyle: {
|
|
32
|
-
type: [Object, String],
|
|
33
|
-
default: () => ({})
|
|
34
|
-
},
|
|
35
|
-
customClass: {
|
|
36
|
-
type: String,
|
|
37
|
-
default: ''
|
|
38
|
-
},
|
|
39
|
-
url: {
|
|
40
|
-
type: String,
|
|
41
|
-
default: ''
|
|
42
|
-
},
|
|
43
|
-
linkType: {
|
|
44
|
-
type: String,
|
|
45
|
-
default: 'navigateTo'
|
|
46
|
-
},
|
|
31
|
+
customStyle: {
|
|
32
|
+
type: [Object, String],
|
|
33
|
+
default: () => ({})
|
|
34
|
+
},
|
|
35
|
+
customClass: {
|
|
36
|
+
type: String,
|
|
37
|
+
default: ''
|
|
38
|
+
},
|
|
39
|
+
url: {
|
|
40
|
+
type: String,
|
|
41
|
+
default: ''
|
|
42
|
+
},
|
|
43
|
+
linkType: {
|
|
44
|
+
type: String,
|
|
45
|
+
default: 'navigateTo'
|
|
46
|
+
},
|
|
47
47
|
// 当前form的需要验证字段的集合
|
|
48
48
|
model: {
|
|
49
49
|
type: Object as PropType<any>,
|
|
@@ -54,62 +54,62 @@
|
|
|
54
54
|
type: Object as PropType<UTSJSONObject>,
|
|
55
55
|
default: defProps.getArray('form.rules')
|
|
56
56
|
},
|
|
57
|
-
// 有错误时的提示方式,message-提示信息,toast-进行toast提示
|
|
58
|
-
// border-bottom-下边框呈现红色,none-无提示
|
|
59
|
-
errorType: {
|
|
60
|
-
type: String,
|
|
61
|
-
default: defProps.getString('form.errorType')
|
|
62
|
-
},
|
|
63
|
-
// 是否显示表单域的下划线边框
|
|
64
|
-
borderBottom: {
|
|
65
|
-
type: Boolean,
|
|
66
|
-
default: defProps.getBoolean('form.borderBottom')
|
|
67
|
-
},
|
|
68
|
-
// label的位置,left-左边,top-上边
|
|
69
|
-
labelPosition: {
|
|
70
|
-
type: String,
|
|
71
|
-
default: defProps.getString('form.labelPosition')
|
|
72
|
-
},
|
|
73
|
-
// label的宽度,单位px
|
|
74
|
-
labelWidth: {
|
|
75
|
-
type: [String, Number],
|
|
76
|
-
default: defProps.getNumber('form.labelWidth')
|
|
77
|
-
},
|
|
78
|
-
// lable字体的对齐方式
|
|
79
|
-
labelAlign: {
|
|
80
|
-
type: String,
|
|
81
|
-
default: defProps.getString('form.labelAlign')
|
|
82
|
-
},
|
|
83
|
-
// lable的样式,对象形式
|
|
84
|
-
labelStyle: {
|
|
85
|
-
type: Object as PropType<UTSJSONObject>,
|
|
86
|
-
default: defProps.getArray('form.labelStyle')
|
|
87
|
-
}
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
// 定义emits
|
|
91
|
-
const emit = defineEmits([])
|
|
92
|
-
|
|
93
|
-
// 响应式数据
|
|
94
|
-
const formRules = ref<UTSJSONObject>({})
|
|
95
|
-
// 规则校验器
|
|
96
|
-
const validator = ref<Schema>(new Schema({}))
|
|
97
|
-
// 原始的model快照,用于resetFields方法重置表单时使用
|
|
98
|
-
const originalModel = ref<UTSJSONObject|null>(null)
|
|
99
|
-
|
|
100
|
-
// props变化计算属性
|
|
101
|
-
const propsChange = computed(() => {
|
|
102
|
-
return [
|
|
103
|
-
props.errorType,
|
|
104
|
-
props.borderBottom,
|
|
105
|
-
props.labelPosition,
|
|
106
|
-
props.labelWidth,
|
|
107
|
-
props.labelAlign,
|
|
108
|
-
props.labelStyle,
|
|
109
|
-
]
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
// 手动设置校验的规则,如果规则中有函数的话,微信小程序中会过滤掉,所以只能手动调用设置规则
|
|
57
|
+
// 有错误时的提示方式,message-提示信息,toast-进行toast提示
|
|
58
|
+
// border-bottom-下边框呈现红色,none-无提示
|
|
59
|
+
errorType: {
|
|
60
|
+
type: String,
|
|
61
|
+
default: defProps.getString('form.errorType')
|
|
62
|
+
},
|
|
63
|
+
// 是否显示表单域的下划线边框
|
|
64
|
+
borderBottom: {
|
|
65
|
+
type: Boolean,
|
|
66
|
+
default: defProps.getBoolean('form.borderBottom')
|
|
67
|
+
},
|
|
68
|
+
// label的位置,left-左边,top-上边
|
|
69
|
+
labelPosition: {
|
|
70
|
+
type: String,
|
|
71
|
+
default: defProps.getString('form.labelPosition')
|
|
72
|
+
},
|
|
73
|
+
// label的宽度,单位px
|
|
74
|
+
labelWidth: {
|
|
75
|
+
type: [String, Number],
|
|
76
|
+
default: defProps.getNumber('form.labelWidth')
|
|
77
|
+
},
|
|
78
|
+
// lable字体的对齐方式
|
|
79
|
+
labelAlign: {
|
|
80
|
+
type: String,
|
|
81
|
+
default: defProps.getString('form.labelAlign')
|
|
82
|
+
},
|
|
83
|
+
// lable的样式,对象形式
|
|
84
|
+
labelStyle: {
|
|
85
|
+
type: Object as PropType<UTSJSONObject>,
|
|
86
|
+
default: defProps.getArray('form.labelStyle')
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
// 定义emits
|
|
91
|
+
const emit = defineEmits([])
|
|
92
|
+
|
|
93
|
+
// 响应式数据
|
|
94
|
+
const formRules = ref<UTSJSONObject>({})
|
|
95
|
+
// 规则校验器
|
|
96
|
+
const validator = ref<Schema>(new Schema({}))
|
|
97
|
+
// 原始的model快照,用于resetFields方法重置表单时使用
|
|
98
|
+
const originalModel = ref<UTSJSONObject|null>(null)
|
|
99
|
+
|
|
100
|
+
// props变化计算属性
|
|
101
|
+
const propsChange = computed(() => {
|
|
102
|
+
return [
|
|
103
|
+
props.errorType,
|
|
104
|
+
props.borderBottom,
|
|
105
|
+
props.labelPosition,
|
|
106
|
+
props.labelWidth,
|
|
107
|
+
props.labelAlign,
|
|
108
|
+
props.labelStyle,
|
|
109
|
+
]
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
// 手动设置校验的规则,如果规则中有函数的话,微信小程序中会过滤掉,所以只能手动调用设置规则
|
|
113
113
|
const setRules = (rules: UTSJSONObject) => {
|
|
114
114
|
// 判断是否有规则
|
|
115
115
|
if (rules == null) return;
|
|
@@ -118,8 +118,8 @@
|
|
|
118
118
|
// 重新将规则赋予Validator
|
|
119
119
|
validator.value = new Schema(formRules.value);
|
|
120
120
|
}
|
|
121
|
-
|
|
122
|
-
// 重置model为初始值的快照
|
|
121
|
+
|
|
122
|
+
// 重置model为初始值的快照
|
|
123
123
|
function resetModel(obj: any|null = null) {
|
|
124
124
|
// 历遍所有up-form-item,根据其prop属性,还原model的原始快照
|
|
125
125
|
children.value.map((child: ComponentPublicInstance) => {
|
|
@@ -132,8 +132,8 @@
|
|
|
132
132
|
}
|
|
133
133
|
});
|
|
134
134
|
}
|
|
135
|
-
|
|
136
|
-
// 清空所有up-form-item组件的内容,本质上是调用了up-form-item组件中的resetField()方法
|
|
135
|
+
|
|
136
|
+
// 清空所有up-form-item组件的内容,本质上是调用了up-form-item组件中的resetField()方法
|
|
137
137
|
const resetFields = () => {
|
|
138
138
|
resetModel()
|
|
139
139
|
}
|
|
@@ -149,12 +149,12 @@
|
|
|
149
149
|
}
|
|
150
150
|
});
|
|
151
151
|
}
|
|
152
|
-
|
|
153
|
-
// 对部分表单字段进行校验
|
|
154
|
-
function validateField(value: Array<string>|string,
|
|
155
|
-
callback: ((errors: UTSJSONObject[]) => void)|null = null, event: string|null = null) {
|
|
156
|
-
return new Promise((resolve, reject) => {
|
|
157
|
-
// 校验错误信息,返回给回调方法,用于存放所有form-item的错误信息
|
|
152
|
+
|
|
153
|
+
// 对部分表单字段进行校验
|
|
154
|
+
function validateField(value: Array<string>|string,
|
|
155
|
+
callback: ((errors: UTSJSONObject[]) => void)|null = null, event: string|null = null) {
|
|
156
|
+
return new Promise((resolve, reject) => {
|
|
157
|
+
// 校验错误信息,返回给回调方法,用于存放所有form-item的错误信息
|
|
158
158
|
const errorsRes: UTSJSONObject[] = [];
|
|
159
159
|
const validateProps: string[] = []
|
|
160
160
|
const modelSnapshot = JSON.parse(JSON.stringify(props.model)) as UTSJSONObject
|
|
@@ -166,12 +166,12 @@
|
|
|
166
166
|
} else {
|
|
167
167
|
validateProps.push(value)
|
|
168
168
|
}
|
|
169
|
-
// 历遍children所有子form-item
|
|
170
|
-
let promises: Promise<UTSJSONObject[]>[] = children.value.map((child: ComponentPublicInstance) => {
|
|
171
|
-
return new Promise((resolveChild) => {
|
|
172
|
-
// 用于存放form-item的错误信息
|
|
173
|
-
const childErrors: UTSJSONObject[] = [];
|
|
174
|
-
let childProps: UTSJSONObject = child.$callMethod('getProps')! as UTSJSONObject
|
|
169
|
+
// 历遍children所有子form-item
|
|
170
|
+
let promises: Promise<UTSJSONObject[]>[] = children.value.map((child: ComponentPublicInstance) => {
|
|
171
|
+
return new Promise((resolveChild) => {
|
|
172
|
+
// 用于存放form-item的错误信息
|
|
173
|
+
const childErrors: UTSJSONObject[] = [];
|
|
174
|
+
let childProps: UTSJSONObject = child.$callMethod('getProps')! as UTSJSONObject
|
|
175
175
|
let childRefs: UTSJSONObject = child.$callMethod('getRefs')! as UTSJSONObject
|
|
176
176
|
if (validateProps.includes(childProps['prop']!.toString())) {
|
|
177
177
|
// 获取对应的属性,通过类似'a.b.c'的形式
|
|
@@ -179,54 +179,54 @@
|
|
|
179
179
|
modelSnapshot,
|
|
180
180
|
childProps['prop']!.toString()
|
|
181
181
|
);
|
|
182
|
-
// 属性链数组
|
|
183
|
-
const propertyChain = childProps['prop']!.toString().split(".");
|
|
184
|
-
const propertyName =
|
|
185
|
-
propertyChain[propertyChain.length - 1];
|
|
186
|
-
|
|
187
|
-
let rule:UTSJSONObject[] = []
|
|
188
|
-
// todo
|
|
189
|
-
// if (childRefs['itemRules'] != null) {
|
|
190
|
-
// rule = childRefs['itemRules']
|
|
191
|
-
// } else {
|
|
192
|
-
let tmp = formRules.value[childProps['prop']!.toString()];
|
|
193
|
-
if (tmp == null && props.rules != null) {
|
|
194
|
-
tmp = props.rules[childProps['prop']!.toString()]
|
|
195
|
-
}
|
|
196
|
-
if (Array.isArray(tmp)) {
|
|
197
|
-
rule = tmp as UTSJSONObject[]
|
|
198
|
-
} else {
|
|
199
|
-
if (tmp != null) {
|
|
200
|
-
rule.push(tmp as UTSJSONObject)
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
// }
|
|
204
|
-
// 如果不存在对应的规则,直接返回,否则校验会报错
|
|
205
|
-
if (rule == null || rule.length == 0) {
|
|
206
|
-
console.log('rule-miss', childProps['prop']!.toString(), UTSJSONObject.keys(formRules.value))
|
|
207
|
-
resolveChild([])
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
// rule规则可为数组形式,也可为对象形式,此处拼接成为数组
|
|
211
|
-
let rules: UTSJSONObject[] = []
|
|
212
|
-
rules = rule
|
|
213
|
-
// console.log('rules', JSON.stringify(rules))
|
|
214
|
-
let executeRuleCount = 0
|
|
215
|
-
let completeRuleCount = 0
|
|
216
|
-
let childResolved = false
|
|
217
|
-
const finishChild = () => {
|
|
218
|
-
if (childResolved) return
|
|
219
|
-
if (completeRuleCount < executeRuleCount) return
|
|
220
|
-
if (childErrors.length > 0) {
|
|
221
|
-
const msg = childErrors[0]['message']
|
|
222
|
-
const childMsg = msg == null ? '' : msg.toString()
|
|
223
|
-
child.$callMethod('setMessage', childMsg)
|
|
224
|
-
} else {
|
|
225
|
-
child.$callMethod('setMessage', '')
|
|
226
|
-
}
|
|
227
|
-
childResolved = true
|
|
228
|
-
resolveChild(errorsRes)
|
|
229
|
-
}
|
|
182
|
+
// 属性链数组
|
|
183
|
+
const propertyChain = childProps['prop']!.toString().split(".");
|
|
184
|
+
const propertyName =
|
|
185
|
+
propertyChain[propertyChain.length - 1];
|
|
186
|
+
|
|
187
|
+
let rule:UTSJSONObject[] = []
|
|
188
|
+
// todo
|
|
189
|
+
// if (childRefs['itemRules'] != null) {
|
|
190
|
+
// rule = childRefs['itemRules']
|
|
191
|
+
// } else {
|
|
192
|
+
let tmp = formRules.value[childProps['prop']!.toString()];
|
|
193
|
+
if (tmp == null && props.rules != null) {
|
|
194
|
+
tmp = props.rules[childProps['prop']!.toString()]
|
|
195
|
+
}
|
|
196
|
+
if (Array.isArray(tmp)) {
|
|
197
|
+
rule = tmp as UTSJSONObject[]
|
|
198
|
+
} else {
|
|
199
|
+
if (tmp != null) {
|
|
200
|
+
rule.push(tmp as UTSJSONObject)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// }
|
|
204
|
+
// 如果不存在对应的规则,直接返回,否则校验会报错
|
|
205
|
+
if (rule == null || rule.length == 0) {
|
|
206
|
+
console.log('rule-miss', childProps['prop']!.toString(), UTSJSONObject.keys(formRules.value))
|
|
207
|
+
resolveChild([])
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
// rule规则可为数组形式,也可为对象形式,此处拼接成为数组
|
|
211
|
+
let rules: UTSJSONObject[] = []
|
|
212
|
+
rules = rule
|
|
213
|
+
// console.log('rules', JSON.stringify(rules))
|
|
214
|
+
let executeRuleCount = 0
|
|
215
|
+
let completeRuleCount = 0
|
|
216
|
+
let childResolved = false
|
|
217
|
+
const finishChild = () => {
|
|
218
|
+
if (childResolved) return
|
|
219
|
+
if (completeRuleCount < executeRuleCount) return
|
|
220
|
+
if (childErrors.length > 0) {
|
|
221
|
+
const msg = childErrors[0]['message']
|
|
222
|
+
const childMsg = msg == null ? '' : msg.toString()
|
|
223
|
+
child.$callMethod('setMessage', childMsg)
|
|
224
|
+
} else {
|
|
225
|
+
child.$callMethod('setMessage', '')
|
|
226
|
+
}
|
|
227
|
+
childResolved = true
|
|
228
|
+
resolveChild(errorsRes)
|
|
229
|
+
}
|
|
230
230
|
// 对rules数组进行校验
|
|
231
231
|
for (let i = 0; i < rules.length; i++) {
|
|
232
232
|
const ruleItem = rules[i];
|
|
@@ -348,133 +348,138 @@
|
|
|
348
348
|
// console.log(e)
|
|
349
349
|
completeRuleCount += 1
|
|
350
350
|
finishChild()
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
if (executeRuleCount == 0) {
|
|
354
|
-
child.$callMethod('setMessage', '')
|
|
355
|
-
resolveChild([])
|
|
356
|
-
}
|
|
357
|
-
} else {
|
|
358
|
-
resolveChild([])
|
|
359
|
-
}
|
|
360
|
-
});
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
// 使用Promise.all来等待所有Promise完成
|
|
364
|
-
Promise.all(promises)
|
|
365
|
-
.then((results: any) => {
|
|
366
|
-
// 执行回调函数
|
|
367
|
-
console.log('errors', errorsRes.length)
|
|
368
|
-
if (callback != null) {
|
|
369
|
-
callback(errorsRes)
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
if (executeRuleCount == 0) {
|
|
354
|
+
child.$callMethod('setMessage', '')
|
|
355
|
+
resolveChild([])
|
|
356
|
+
}
|
|
357
|
+
} else {
|
|
358
|
+
resolveChild([])
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
// 使用Promise.all来等待所有Promise完成
|
|
364
|
+
Promise.all(promises)
|
|
365
|
+
.then((results: any) => {
|
|
366
|
+
// 执行回调函数
|
|
367
|
+
console.log('errors', errorsRes.length)
|
|
368
|
+
if (callback != null) {
|
|
369
|
+
callback(errorsRes)
|
|
370
|
+
}
|
|
371
|
+
// toast提示统一放在validateField里:输入、失焦等自动触发的校验同样能弹出提示
|
|
372
|
+
// (此前只有validate()会提示);每次校验只提示第一条错误,避免多字段连续弹toast
|
|
373
|
+
if (errorsRes.length > 0 && props.errorType == 'toast'
|
|
374
|
+
&& errorsRes[0] != null && errorsRes[0]['message'] != null) {
|
|
375
|
+
toast(errorsRes[0]['message'].toString())
|
|
376
|
+
}
|
|
377
|
+
resolve(errorsRes)
|
|
378
|
+
})
|
|
379
|
+
// .catch((error: any) => {
|
|
380
|
+
// console.error('An error occurred:', error);
|
|
381
|
+
// reject(error)
|
|
382
|
+
// });
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// 校验全部数据
|
|
387
|
+
const validate = (): Promise<any> => {
|
|
388
|
+
// 开发环境才提示,生产环境不会提示
|
|
389
|
+
if (process.env.NODE_ENV == 'development'
|
|
390
|
+
&& UTSJSONObject.keys(formRules.value).length == 0) {
|
|
391
|
+
console.error('未设置rules,请看文档说明!如果已经设置,请刷新页面。');
|
|
392
|
+
return new Promise((resolve, reject) => {
|
|
393
|
+
reject({})
|
|
394
|
+
})
|
|
395
|
+
return Promise.reject({});
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return new Promise((resolve, reject) => {
|
|
399
|
+
// 获取所有form-item的prop,交给validateField方法进行校验
|
|
394
400
|
const formItemProps: string[] = children.value.map(
|
|
395
401
|
(item: ComponentPublicInstance): string => {
|
|
396
402
|
const itemProps = item.$callMethod('getProps') as UTSJSONObject | null
|
|
397
403
|
return itemProps != null && itemProps['prop'] != null ? itemProps['prop'].toString() : ''
|
|
398
404
|
}
|
|
399
405
|
).filter((prop: string): boolean => prop != '');
|
|
400
|
-
console.log('formItemProps', formItemProps)
|
|
401
|
-
let func = function(errors: UTSJSONObject[]): void {
|
|
402
|
-
if(errors.length > 0) {
|
|
403
|
-
//
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
// 监听规则的变化
|
|
406
|
+
console.log('formItemProps', formItemProps)
|
|
407
|
+
let func = function(errors: UTSJSONObject[]): void {
|
|
408
|
+
if(errors.length > 0) {
|
|
409
|
+
// toast提示已统一在validateField中处理,此处只需拒绝Promise
|
|
410
|
+
console.log('errors', errors.length)
|
|
411
|
+
reject(errors)
|
|
412
|
+
} else {
|
|
413
|
+
resolve(true)
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
validateField(formItemProps, func);
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// 监听规则的变化
|
|
416
421
|
watch((): UTSJSONObject => props.rules != null ? props.rules : {} as UTSJSONObject, (newVal: UTSJSONObject) => {
|
|
417
|
-
setRules(newVal);
|
|
418
|
-
}, { immediate: true })
|
|
419
|
-
|
|
420
|
-
// 监听属性的变化,通知子组件up-form-item重新获取信息
|
|
421
|
-
watch(
|
|
422
|
-
(): any => propsChange.value,
|
|
423
|
-
(): void => {
|
|
424
|
-
if (children.value.length > 0) {
|
|
425
|
-
// 修改点:将 map 改为 forEach
|
|
426
|
-
// forEach 的返回值是 void,符合 watch 回调的预期
|
|
427
|
-
children.value.forEach((child: ComponentPublicInstance) => {
|
|
428
|
-
// 判断子组件(up-form-item)如果有updateParentData方法的话,就执行
|
|
429
|
-
child.$callMethod('updateParentData')
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
)
|
|
434
|
-
|
|
435
|
-
// 监听model的初始值作为重置表单的快照
|
|
422
|
+
setRules(newVal);
|
|
423
|
+
}, { immediate: true })
|
|
424
|
+
|
|
425
|
+
// 监听属性的变化,通知子组件up-form-item重新获取信息
|
|
426
|
+
watch(
|
|
427
|
+
(): any => propsChange.value,
|
|
428
|
+
(): void => {
|
|
429
|
+
if (children.value.length > 0) {
|
|
430
|
+
// 修改点:将 map 改为 forEach
|
|
431
|
+
// forEach 的返回值是 void,符合 watch 回调的预期
|
|
432
|
+
children.value.forEach((child: ComponentPublicInstance) => {
|
|
433
|
+
// 判断子组件(up-form-item)如果有updateParentData方法的话,就执行
|
|
434
|
+
child.$callMethod('updateParentData')
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
// 监听model的初始值作为重置表单的快照
|
|
436
441
|
watch((): any => props.model, (newVal: any): void => {
|
|
437
442
|
if (originalModel.value == null) {
|
|
438
443
|
originalModel.value = deepClone(newVal) as UTSJSONObject;
|
|
439
444
|
}
|
|
440
445
|
}, { immediate: true })
|
|
441
|
-
|
|
442
|
-
const getProps = function(): UTSJSONObject {
|
|
443
|
-
return {
|
|
444
|
-
labelPosition: props.labelPosition,
|
|
445
|
-
labelAlign: props.labelAlign,
|
|
446
|
-
labelStyle: props.labelStyle,
|
|
447
|
-
labelWidth: props.labelWidth,
|
|
448
|
-
errorType: props.errorType
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
const getRefs = function() {
|
|
452
|
-
return {
|
|
453
|
-
originalModel: originalModel.value == null ? {} : originalModel.value
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
const setOriginalModel = function(prop: string, value: any|null) {
|
|
458
|
-
if (originalModel.value == null) {
|
|
459
|
-
originalModel.value = {}
|
|
460
|
-
}
|
|
461
|
-
originalModel.value[prop] = value
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// 暴露方法给子组件
|
|
465
|
-
defineExpose({
|
|
466
|
-
setOriginalModel,
|
|
467
|
-
getChildren,
|
|
468
|
-
addChild,
|
|
469
|
-
getProps,
|
|
470
|
-
getRefs,
|
|
471
|
-
validate,
|
|
472
|
-
clearValidate,
|
|
473
|
-
validateField,
|
|
474
|
-
resetFields,
|
|
475
|
-
setRules
|
|
476
|
-
})
|
|
477
|
-
</script>
|
|
478
|
-
|
|
479
|
-
<style lang="scss" scoped>
|
|
480
|
-
</style>
|
|
446
|
+
|
|
447
|
+
const getProps = function(): UTSJSONObject {
|
|
448
|
+
return {
|
|
449
|
+
labelPosition: props.labelPosition,
|
|
450
|
+
labelAlign: props.labelAlign,
|
|
451
|
+
labelStyle: props.labelStyle,
|
|
452
|
+
labelWidth: props.labelWidth,
|
|
453
|
+
errorType: props.errorType
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
const getRefs = function() {
|
|
457
|
+
return {
|
|
458
|
+
originalModel: originalModel.value == null ? {} : originalModel.value
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const setOriginalModel = function(prop: string, value: any|null) {
|
|
463
|
+
if (originalModel.value == null) {
|
|
464
|
+
originalModel.value = {}
|
|
465
|
+
}
|
|
466
|
+
originalModel.value[prop] = value
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// 暴露方法给子组件
|
|
470
|
+
defineExpose({
|
|
471
|
+
setOriginalModel,
|
|
472
|
+
getChildren,
|
|
473
|
+
addChild,
|
|
474
|
+
getProps,
|
|
475
|
+
getRefs,
|
|
476
|
+
validate,
|
|
477
|
+
clearValidate,
|
|
478
|
+
validateField,
|
|
479
|
+
resetFields,
|
|
480
|
+
setRules
|
|
481
|
+
})
|
|
482
|
+
</script>
|
|
483
|
+
|
|
484
|
+
<style lang="scss" scoped>
|
|
485
|
+
</style>
|
|
@@ -160,10 +160,13 @@
|
|
|
160
160
|
}
|
|
161
161
|
for (let i = 0; i < rules.length; i++) {
|
|
162
162
|
const ruleItem = rules[i]
|
|
163
|
-
// 将up-form-item
|
|
164
|
-
|
|
165
|
-
//
|
|
166
|
-
|
|
163
|
+
// 将up-form-item的触发器转为数组形式;
|
|
164
|
+
// 未配置trigger(undefined/null/空字符串)的规则视为任何触发方式都执行,
|
|
165
|
+
// 与async-validator等库的惯例一致,避免被静默跳过导致验证永远不触发
|
|
166
|
+
const ruleTrigger = ruleItem?.trigger
|
|
167
|
+
const trigger = (ruleTrigger == null || ruleTrigger === '') ? null : [].concat(ruleTrigger)
|
|
168
|
+
// 如果是有传入触发事件,且此规则配置了触发器但不包含当前事件,则不执行校验操作
|
|
169
|
+
if (event && trigger && !trigger.includes(event)) {
|
|
167
170
|
resolve()
|
|
168
171
|
continue
|
|
169
172
|
}
|
|
@@ -202,6 +205,12 @@
|
|
|
202
205
|
.then(results => {
|
|
203
206
|
// 执行回调函数
|
|
204
207
|
typeof callback === 'function' && callback(errorsRes)
|
|
208
|
+
// 如果错误提示方式为toast,则进行提示。放在validateField里,
|
|
209
|
+
// 输入、失焦等自动触发的校验同样能弹出提示(此前只有validate()会提示);
|
|
210
|
+
// 每次校验只提示第一条错误,避免多字段同时失败时连续弹出多个toast
|
|
211
|
+
if (errorsRes.length && props.errorType === 'toast') {
|
|
212
|
+
toast(errorsRes[0].message)
|
|
213
|
+
}
|
|
205
214
|
})
|
|
206
215
|
.catch(error => {
|
|
207
216
|
console.error('An error occurred:', error)
|
|
@@ -225,8 +234,7 @@
|
|
|
225
234
|
)
|
|
226
235
|
validateField(formItemProps, (errors) => {
|
|
227
236
|
if (errors.length) {
|
|
228
|
-
//
|
|
229
|
-
props.errorType === 'toast' && toast(errors[0].message)
|
|
237
|
+
// toast提示已统一在validateField中处理,此处只需拒绝Promise
|
|
230
238
|
reject(errors)
|
|
231
239
|
} else {
|
|
232
240
|
resolve(true)
|