hy-app 0.3.15 → 0.3.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/components/hy-checkbox-group/hy-checkbox-group.vue +6 -4
- package/components/hy-checkbox-item/hy-checkbox-item.vue +41 -24
- package/components/hy-checkbox-item/typing.d.ts +3 -2
- package/components/hy-form/hy-form.vue +2 -7
- package/components/hy-form-item/hy-form-item.vue +204 -201
- package/components/hy-form-item/typing.d.ts +20 -14
- package/package.json +2 -2
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
|
-
import { computed, provide } from "vue";
|
|
8
|
+
import { computed, provide, toRefs } from "vue";
|
|
9
9
|
import type { CSSProperties, PropType } from "vue";
|
|
10
10
|
import { bem } from "../../utils";
|
|
11
11
|
import type { ICheckBoxGroupEmits } from "./typing";
|
|
@@ -98,8 +98,8 @@ const bemClass = computed(() => {
|
|
|
98
98
|
return bem("checkbox-group", props, ["placement"]);
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
...props,
|
|
101
|
+
const context = {
|
|
102
|
+
...toRefs(props),
|
|
103
103
|
setCheckedStatus(value: string | number) {
|
|
104
104
|
let arr = [...props.modelValue];
|
|
105
105
|
if (props.modelValue?.includes(value)) {
|
|
@@ -110,7 +110,9 @@ provide("hy-checkbox-group", {
|
|
|
110
110
|
emit("update:modelValue", arr);
|
|
111
111
|
emit("change", arr);
|
|
112
112
|
},
|
|
113
|
-
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
provide("hy-checkbox-group", context);
|
|
114
116
|
</script>
|
|
115
117
|
|
|
116
118
|
<style lang="scss" scoped>
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
@tap.stop="wrapperClickHandler"
|
|
5
5
|
:style="checkboxStyle"
|
|
6
6
|
:class="[
|
|
7
|
-
`hy-checkbox--label__${checkboxGroup?.iconPlacement}`,
|
|
8
|
-
checkboxGroup?.borderBottom &&
|
|
9
|
-
checkboxGroup?.placement === 'column' &&
|
|
7
|
+
`hy-checkbox--label__${checkboxGroup?.iconPlacement?.value}`,
|
|
8
|
+
checkboxGroup?.borderBottom?.value &&
|
|
9
|
+
checkboxGroup?.placement?.value === 'column' &&
|
|
10
10
|
'hy-border__bottom',
|
|
11
11
|
]"
|
|
12
12
|
>
|
|
@@ -21,9 +21,12 @@
|
|
|
21
21
|
class="hy-checkbox--icon-wrap__icon"
|
|
22
22
|
:name="IconConfig.CHECK_MASK"
|
|
23
23
|
:size="
|
|
24
|
-
addUnit(
|
|
24
|
+
addUnit(
|
|
25
|
+
sizeType[checkboxGroup?.size?.value] ??
|
|
26
|
+
checkboxGroup?.iconSize?.value,
|
|
27
|
+
)
|
|
25
28
|
"
|
|
26
|
-
:color="checkboxGroup?.iconColor || '#ffffff'"
|
|
29
|
+
:color="checkboxGroup?.iconColor?.value || '#ffffff'"
|
|
27
30
|
/>
|
|
28
31
|
</slot>
|
|
29
32
|
</view>
|
|
@@ -38,9 +41,10 @@
|
|
|
38
41
|
<slot name="label">
|
|
39
42
|
<text
|
|
40
43
|
:style="{
|
|
41
|
-
color: checkboxGroup?.labelColor,
|
|
44
|
+
color: checkboxGroup?.labelColor?.value,
|
|
42
45
|
fontSize: addUnit(
|
|
43
|
-
sizeType[checkboxGroup?.size] ??
|
|
46
|
+
sizeType[checkboxGroup?.size?.value] ??
|
|
47
|
+
checkboxGroup?.labelSize?.value,
|
|
44
48
|
),
|
|
45
49
|
}"
|
|
46
50
|
>
|
|
@@ -67,7 +71,7 @@ import { computed, watch, ref, reactive, inject } from "vue";
|
|
|
67
71
|
import type { CSSProperties } from "vue";
|
|
68
72
|
import { addUnit, error } from "../../utils";
|
|
69
73
|
import { IconConfig } from "../../config";
|
|
70
|
-
import type {
|
|
74
|
+
import type { ICheckboxGroupContext } from "./typing";
|
|
71
75
|
// 组件
|
|
72
76
|
import HyIcon from "../hy-icon/hy-icon.vue";
|
|
73
77
|
|
|
@@ -101,7 +105,7 @@ const props = defineProps({
|
|
|
101
105
|
});
|
|
102
106
|
|
|
103
107
|
// 注入表单上下文
|
|
104
|
-
const checkboxGroup = inject<
|
|
108
|
+
const checkboxGroup = inject<ICheckboxGroupContext>("hy-checkbox-group");
|
|
105
109
|
const isChecked = ref(false);
|
|
106
110
|
const sizeType: AnyObject = reactive({
|
|
107
111
|
small: 14,
|
|
@@ -119,27 +123,38 @@ watch(
|
|
|
119
123
|
);
|
|
120
124
|
|
|
121
125
|
watch(
|
|
122
|
-
() => checkboxGroup?.modelValue,
|
|
126
|
+
() => checkboxGroup?.modelValue.value,
|
|
123
127
|
(newVal) => {
|
|
124
|
-
if (newVal?.length)
|
|
128
|
+
if (newVal?.length) {
|
|
129
|
+
isChecked.value = newVal.includes(props.value);
|
|
130
|
+
} else {
|
|
131
|
+
isChecked.value = false;
|
|
132
|
+
}
|
|
125
133
|
},
|
|
126
134
|
{ immediate: true },
|
|
127
135
|
);
|
|
128
136
|
|
|
129
|
-
const isDisabled = (): boolean =>
|
|
137
|
+
const isDisabled = (): boolean =>
|
|
138
|
+
checkboxGroup?.disabled?.value || props.disabled;
|
|
130
139
|
|
|
131
140
|
const checkboxStyle = computed(() => {
|
|
132
141
|
const style: CSSProperties = {};
|
|
133
|
-
if (
|
|
142
|
+
if (
|
|
143
|
+
checkboxGroup?.borderBottom?.value &&
|
|
144
|
+
checkboxGroup?.placement?.value === "row"
|
|
145
|
+
) {
|
|
134
146
|
error(
|
|
135
147
|
"检测到您将borderBottom设置为true,需要同时将hy-checkbox-group的placement设置为column才有效",
|
|
136
148
|
);
|
|
137
149
|
}
|
|
138
150
|
// 当父组件设置了显示下边框并且排列形式为纵向时,给内容和边框之间加上一定间隔
|
|
139
|
-
if (
|
|
151
|
+
if (
|
|
152
|
+
checkboxGroup?.borderBottom?.value &&
|
|
153
|
+
checkboxGroup?.placement?.value === "column"
|
|
154
|
+
) {
|
|
140
155
|
style.paddingBottom = "8px";
|
|
141
156
|
}
|
|
142
|
-
return Object.assign(style, checkboxGroup?.customStyle);
|
|
157
|
+
return Object.assign(style, checkboxGroup?.customStyle?.value);
|
|
143
158
|
});
|
|
144
159
|
/**
|
|
145
160
|
* @description 定义icon的Class类名
|
|
@@ -147,7 +162,7 @@ const checkboxStyle = computed(() => {
|
|
|
147
162
|
const iconClasses = computed(() => {
|
|
148
163
|
let classes: string[] = [];
|
|
149
164
|
// 组件的形状
|
|
150
|
-
classes.push("hy-checkbox--icon-wrap--" + checkboxGroup?.shape);
|
|
165
|
+
classes.push("hy-checkbox--icon-wrap--" + checkboxGroup?.shape?.value);
|
|
151
166
|
if (isDisabled()) {
|
|
152
167
|
classes.push("hy-checkbox--icon-wrap--disabled");
|
|
153
168
|
}
|
|
@@ -169,18 +184,20 @@ const iconWrapStyle = computed(() => {
|
|
|
169
184
|
const style: CSSProperties = {};
|
|
170
185
|
style.backgroundColor =
|
|
171
186
|
isChecked.value && !isDisabled()
|
|
172
|
-
? checkboxGroup?.activeColor
|
|
187
|
+
? checkboxGroup?.activeColor?.value
|
|
173
188
|
: !isDisabled()
|
|
174
189
|
? "#ffffff"
|
|
175
190
|
: "";
|
|
176
191
|
style.borderColor =
|
|
177
192
|
isChecked.value && !isDisabled()
|
|
178
|
-
? checkboxGroup?.activeColor
|
|
179
|
-
: checkboxGroup?.inactiveColor;
|
|
180
|
-
if (checkboxGroup?.size) {
|
|
181
|
-
style.width = addUnit(
|
|
193
|
+
? checkboxGroup?.activeColor?.value
|
|
194
|
+
: checkboxGroup?.inactiveColor?.value;
|
|
195
|
+
if (checkboxGroup?.size?.value) {
|
|
196
|
+
style.width = addUnit(
|
|
197
|
+
sizeType[checkboxGroup.size.value] ?? checkboxGroup.size.value,
|
|
198
|
+
);
|
|
182
199
|
style.height = addUnit(
|
|
183
|
-
sizeType[checkboxGroup.size] ?? checkboxGroup.size,
|
|
200
|
+
sizeType[checkboxGroup.size.value] ?? checkboxGroup.size.value,
|
|
184
201
|
);
|
|
185
202
|
}
|
|
186
203
|
return style;
|
|
@@ -201,7 +218,7 @@ const iconClickHandler = (e: Event) => {
|
|
|
201
218
|
* */
|
|
202
219
|
const wrapperClickHandler = (e: Event) => {
|
|
203
220
|
e.stopPropagation();
|
|
204
|
-
if (checkboxGroup?.labelDisabled || isDisabled()) return;
|
|
221
|
+
if (checkboxGroup?.labelDisabled?.value || isDisabled()) return;
|
|
205
222
|
setCheckedStatus();
|
|
206
223
|
};
|
|
207
224
|
/**
|
|
@@ -209,7 +226,7 @@ const wrapperClickHandler = (e: Event) => {
|
|
|
209
226
|
* */
|
|
210
227
|
const labelClickHandler = (e: Event) => {
|
|
211
228
|
e.stopPropagation();
|
|
212
|
-
if (checkboxGroup?.labelDisabled || isDisabled()) return;
|
|
229
|
+
if (checkboxGroup?.labelDisabled?.value || isDisabled()) return;
|
|
213
230
|
setCheckedStatus();
|
|
214
231
|
};
|
|
215
232
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type HyCheckboxGroupProps from "@/package/components/hy-checkbox-group/typing";
|
|
2
|
+
import type { ToRefs } from "vue";
|
|
2
3
|
|
|
3
|
-
export interface
|
|
4
|
-
setCheckedStatus: (name: string) => void;
|
|
4
|
+
export interface ICheckboxGroupContext extends ToRefs<HyCheckboxGroupProps> {
|
|
5
|
+
setCheckedStatus: (name: string | number) => void;
|
|
5
6
|
}
|
|
@@ -16,11 +16,10 @@ export default {
|
|
|
16
16
|
</script>
|
|
17
17
|
|
|
18
18
|
<script setup lang="ts">
|
|
19
|
-
import { provide, reactive, ref } from "vue";
|
|
19
|
+
import { provide, reactive, ref, toRefs } from "vue";
|
|
20
20
|
import type { PropType } from "vue";
|
|
21
21
|
import type { FormItemRule } from "./typing";
|
|
22
22
|
import { clearVal, isArray } from "../../utils";
|
|
23
|
-
import type { AppType } from "vite";
|
|
24
23
|
|
|
25
24
|
/**
|
|
26
25
|
* 表单组件父组件,需要搭配hy-form-item
|
|
@@ -73,13 +72,9 @@ const errors = reactive<Record<string, string>>({});
|
|
|
73
72
|
|
|
74
73
|
// 表单上下文
|
|
75
74
|
const formContext = {
|
|
75
|
+
...toRefs(props),
|
|
76
76
|
formData,
|
|
77
77
|
errors,
|
|
78
|
-
rules: props.rules,
|
|
79
|
-
border: props.border,
|
|
80
|
-
labelWidth: props.labelWidth,
|
|
81
|
-
labelPosition: props.labelPosition,
|
|
82
|
-
labelAlign: props.labelAlign,
|
|
83
78
|
addFormItem: (item: any) => {
|
|
84
79
|
formItems.value.push(item);
|
|
85
80
|
},
|
|
@@ -1,201 +1,204 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<view
|
|
3
|
-
class="hy-form-item"
|
|
4
|
-
:class="[
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
</
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
import {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
//
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (!
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
formContext
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<view
|
|
3
|
+
class="hy-form-item"
|
|
4
|
+
:class="[
|
|
5
|
+
`hy-form-item--${labelPosition}`,
|
|
6
|
+
formContext.border && 'hy-border__bottom',
|
|
7
|
+
]"
|
|
8
|
+
>
|
|
9
|
+
<view v-if="label" class="hy-form-item__label" :style="labelStyle">
|
|
10
|
+
<text v-if="isRequired" class="hy-form-item__label--required">*</text>
|
|
11
|
+
{{ label }}
|
|
12
|
+
</view>
|
|
13
|
+
<view class="hy-form-item__content">
|
|
14
|
+
<slot></slot>
|
|
15
|
+
<view v-if="errorMessage" class="hy-form-item__error">
|
|
16
|
+
{{ errorMessage }}
|
|
17
|
+
</view>
|
|
18
|
+
</view>
|
|
19
|
+
</view>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<script lang="ts">
|
|
23
|
+
export default {
|
|
24
|
+
name: "hy-form-item",
|
|
25
|
+
options: {
|
|
26
|
+
addGlobalClass: true,
|
|
27
|
+
virtualHost: true,
|
|
28
|
+
styleIsolation: "shared",
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<script setup lang="ts">
|
|
34
|
+
import { computed, inject, onMounted, onUnmounted, provide, ref } from "vue";
|
|
35
|
+
import type { PropType } from "vue";
|
|
36
|
+
import type { IFormContext } from "./typing";
|
|
37
|
+
import { addUnit } from "../../utils";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 表单组件子组件,需要搭配hy-form
|
|
41
|
+
* @displayName hy-form-item
|
|
42
|
+
*/
|
|
43
|
+
defineOptions({});
|
|
44
|
+
|
|
45
|
+
const props = defineProps({
|
|
46
|
+
/**
|
|
47
|
+
* 标签文本
|
|
48
|
+
*/
|
|
49
|
+
label: String,
|
|
50
|
+
/**
|
|
51
|
+
* 表单字段名
|
|
52
|
+
*/
|
|
53
|
+
prop: String,
|
|
54
|
+
/**
|
|
55
|
+
* 是否必填
|
|
56
|
+
*/
|
|
57
|
+
required: {
|
|
58
|
+
type: Boolean,
|
|
59
|
+
default: false,
|
|
60
|
+
},
|
|
61
|
+
/**
|
|
62
|
+
* 验证规则
|
|
63
|
+
*/
|
|
64
|
+
rules: Object as PropType<any>,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const emit = defineEmits<{
|
|
68
|
+
change: [value: any];
|
|
69
|
+
blur: [value: any];
|
|
70
|
+
}>();
|
|
71
|
+
|
|
72
|
+
// 注入表单上下文
|
|
73
|
+
const formContext = inject<IFormContext>("formContext");
|
|
74
|
+
const formItem = {
|
|
75
|
+
// 处理子组件事件
|
|
76
|
+
handleChange(value: any) {
|
|
77
|
+
if (props.prop && formContext) {
|
|
78
|
+
formContext.setFieldValue(props.prop, value);
|
|
79
|
+
validate("change");
|
|
80
|
+
}
|
|
81
|
+
emit("change", value);
|
|
82
|
+
},
|
|
83
|
+
handleBlur(value: any) {
|
|
84
|
+
if (props.prop && formContext) {
|
|
85
|
+
validate("blur");
|
|
86
|
+
}
|
|
87
|
+
emit("blur", value);
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
provide("formItem", formItem);
|
|
91
|
+
|
|
92
|
+
// 当前组件的引用
|
|
93
|
+
const formItemRef = ref();
|
|
94
|
+
|
|
95
|
+
// 错误信息
|
|
96
|
+
const errorMessage = computed(() => {
|
|
97
|
+
if (!formContext || !props.prop) return "";
|
|
98
|
+
return formContext.errors[props.prop] || "";
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// 是否必填
|
|
102
|
+
const isRequired = computed(() => {
|
|
103
|
+
if (props.required) return true;
|
|
104
|
+
if (!formContext || !props.prop) return false;
|
|
105
|
+
|
|
106
|
+
const fieldRules = formContext.rules?.value?.[props.prop];
|
|
107
|
+
if (!fieldRules) return false;
|
|
108
|
+
|
|
109
|
+
const rules = Array.isArray(fieldRules) ? fieldRules : [fieldRules];
|
|
110
|
+
return rules.some((rule) => rule.required);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// 标签样式
|
|
114
|
+
const labelStyle = computed(() => {
|
|
115
|
+
if (!formContext) return {};
|
|
116
|
+
|
|
117
|
+
const style: Record<string, any> = {};
|
|
118
|
+
|
|
119
|
+
if (formContext.labelWidth?.value !== "auto") {
|
|
120
|
+
style.width = addUnit(formContext.labelWidth?.value);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (formContext.labelAlign?.value) {
|
|
124
|
+
style.textAlign = formContext.labelAlign.value;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return style;
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// 标签位置
|
|
131
|
+
const labelPosition = computed(() => {
|
|
132
|
+
return formContext?.labelPosition?.value || "left";
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// 监听表单数据变化
|
|
136
|
+
// watch(
|
|
137
|
+
// () => formContext?.formData[props.prop],
|
|
138
|
+
// (newVal) => {
|
|
139
|
+
// if (props.prop && formContext) {
|
|
140
|
+
// formContext.setFieldValue(props.prop, newVal)
|
|
141
|
+
// validate('change')
|
|
142
|
+
// }
|
|
143
|
+
// },
|
|
144
|
+
// { immediate: true },
|
|
145
|
+
// )
|
|
146
|
+
|
|
147
|
+
// 验证字段
|
|
148
|
+
const validate = (trigger?: "blur" | "change") => {
|
|
149
|
+
if (!formContext || !props.prop) return true;
|
|
150
|
+
|
|
151
|
+
const value = formContext.getFieldValue(props.prop);
|
|
152
|
+
return formContext.validateField(props.prop, value, trigger);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// 重置字段
|
|
156
|
+
const resetField = () => {
|
|
157
|
+
if (!formContext || !props.prop) return;
|
|
158
|
+
|
|
159
|
+
formContext.setFieldValue(props.prop, undefined);
|
|
160
|
+
formContext.validateField(props.prop, undefined);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// 清除验证
|
|
164
|
+
const clearValidate = () => {
|
|
165
|
+
if (!formContext || !props.prop) return;
|
|
166
|
+
|
|
167
|
+
delete formContext.errors[props.prop];
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// 组件挂载时注册到表单
|
|
171
|
+
onMounted(() => {
|
|
172
|
+
if (formContext) {
|
|
173
|
+
formContext.addFormItem({
|
|
174
|
+
props: props,
|
|
175
|
+
validate,
|
|
176
|
+
resetField,
|
|
177
|
+
clearValidate,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// 组件卸载时从表单中移除
|
|
183
|
+
onUnmounted(() => {
|
|
184
|
+
if (formContext) {
|
|
185
|
+
formContext.removeFormItem({
|
|
186
|
+
props: props,
|
|
187
|
+
validate,
|
|
188
|
+
resetField,
|
|
189
|
+
clearValidate,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// 暴露方法给父组件
|
|
195
|
+
defineExpose({
|
|
196
|
+
validate,
|
|
197
|
+
resetField,
|
|
198
|
+
clearValidate,
|
|
199
|
+
});
|
|
200
|
+
</script>
|
|
201
|
+
|
|
202
|
+
<style lang="scss" scoped>
|
|
203
|
+
@import "./index.scss";
|
|
204
|
+
</style>
|
|
@@ -1,40 +1,46 @@
|
|
|
1
|
-
import HyFormSimpleProps from
|
|
1
|
+
import HyFormSimpleProps from "../hy-form/typing";
|
|
2
|
+
import type { ToRefs } from "vue";
|
|
2
3
|
|
|
3
|
-
export interface
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
export interface IFormContext extends ToRefs<HyFormSimpleProps> {
|
|
5
|
+
formData: AnyObject;
|
|
6
|
+
errors: Record<string, string>;
|
|
7
|
+
addFormItem: (item: any) => void;
|
|
8
|
+
removeFormItem: (item: any) => void;
|
|
9
|
+
validateField: (
|
|
10
|
+
field: string,
|
|
11
|
+
value: any,
|
|
12
|
+
trigger?: "blur" | "change",
|
|
13
|
+
) => boolean;
|
|
14
|
+
setFieldValue: (field: string, value: any) => void;
|
|
15
|
+
getFieldValue: (field: string) => any;
|
|
10
16
|
}
|
|
11
17
|
|
|
12
18
|
export interface FormItemContext {
|
|
13
19
|
/**
|
|
14
20
|
* 失去焦点触发表单校验
|
|
15
21
|
* */
|
|
16
|
-
handleBlur: (value: string | number) => void
|
|
22
|
+
handleBlur: (value: string | number) => void;
|
|
17
23
|
/**
|
|
18
24
|
* 值改变触发表单校验
|
|
19
25
|
* */
|
|
20
|
-
handleChange: (value: string | number) => void
|
|
26
|
+
handleChange: (value: string | number) => void;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
export default interface HyFormItemProps {
|
|
24
30
|
/**
|
|
25
31
|
* 标签文本
|
|
26
32
|
*/
|
|
27
|
-
label?: string
|
|
33
|
+
label?: string;
|
|
28
34
|
/**
|
|
29
35
|
* 表单字段名
|
|
30
36
|
*/
|
|
31
|
-
prop?: string
|
|
37
|
+
prop?: string;
|
|
32
38
|
/**
|
|
33
39
|
* 是否必填
|
|
34
40
|
*/
|
|
35
|
-
required?: boolean
|
|
41
|
+
required?: boolean;
|
|
36
42
|
/**
|
|
37
43
|
* 验证规则
|
|
38
44
|
*/
|
|
39
|
-
rules?: any
|
|
45
|
+
rules?: any;
|
|
40
46
|
}
|