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.
@@ -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
- provide("hy-checkbox-group", {
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(sizeType[checkboxGroup?.size] ?? checkboxGroup?.iconSize)
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] ?? checkboxGroup?.labelSize,
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 { ICheckboxGroupProps } from "./typing";
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<ICheckboxGroupProps>("hy-checkbox-group");
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) isChecked.value = newVal.includes(props.value);
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 => checkboxGroup?.disabled || props.disabled;
137
+ const isDisabled = (): boolean =>
138
+ checkboxGroup?.disabled?.value || props.disabled;
130
139
 
131
140
  const checkboxStyle = computed(() => {
132
141
  const style: CSSProperties = {};
133
- if (checkboxGroup?.borderBottom && checkboxGroup?.placement === "row") {
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 (checkboxGroup?.borderBottom && checkboxGroup?.placement === "column") {
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(sizeType[checkboxGroup.size] ?? checkboxGroup.size);
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 ICheckboxGroupProps extends HyCheckboxGroupProps {
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="[`hy-form-item--${labelPosition}`, formContext.border && 'hy-border__bottom']"
5
- >
6
- <view v-if="label" class="hy-form-item__label" :style="labelStyle">
7
- <text v-if="isRequired" class="hy-form-item__label--required">*</text>
8
- {{ label }}
9
- </view>
10
- <view class="hy-form-item__content">
11
- <slot></slot>
12
- <view v-if="errorMessage" class="hy-form-item__error">
13
- {{ errorMessage }}
14
- </view>
15
- </view>
16
- </view>
17
- </template>
18
-
19
- <script lang="ts">
20
- export default {
21
- name: 'hy-form-item',
22
- options: {
23
- addGlobalClass: true,
24
- virtualHost: true,
25
- styleIsolation: 'shared',
26
- },
27
- }
28
- </script>
29
-
30
- <script setup lang="ts">
31
- import { computed, inject, onMounted, onUnmounted, provide, ref } from 'vue'
32
- import type { PropType } from 'vue'
33
- import type { FormContext } from './typing'
34
- import { addUnit } from '../../utils'
35
-
36
- /**
37
- * 表单组件子组件,需要搭配hy-form
38
- * @displayName hy-form-item
39
- */
40
- defineOptions({})
41
-
42
- const props = defineProps({
43
- /**
44
- * 标签文本
45
- */
46
- label: String,
47
- /**
48
- * 表单字段名
49
- */
50
- prop: String,
51
- /**
52
- * 是否必填
53
- */
54
- required: {
55
- type: Boolean,
56
- default: false,
57
- },
58
- /**
59
- * 验证规则
60
- */
61
- rules: Object as PropType<any>,
62
- })
63
-
64
- const emit = defineEmits<{
65
- change: [value: any]
66
- blur: [value: any]
67
- }>()
68
-
69
- // 注入表单上下文
70
- const formContext = inject<FormContext>('formContext')
71
- const formItem = {
72
- // 处理子组件事件
73
- handleChange(value: any) {
74
- if (props.prop && formContext) {
75
- formContext.setFieldValue(props.prop, value)
76
- validate('change')
77
- }
78
- emit('change', value)
79
- },
80
- handleBlur(value: any) {
81
- if (props.prop && formContext) {
82
- validate('blur')
83
- }
84
- emit('blur', value)
85
- },
86
- }
87
- provide('formItem', formItem)
88
-
89
- // 当前组件的引用
90
- const formItemRef = ref()
91
-
92
- // 错误信息
93
- const errorMessage = computed(() => {
94
- if (!formContext || !props.prop) return ''
95
- return formContext.errors[props.prop] || ''
96
- })
97
-
98
- // 是否必填
99
- const isRequired = computed(() => {
100
- if (props.required) return true
101
- if (!formContext || !props.prop) return false
102
-
103
- const fieldRules = formContext.rules.value?.[props.prop]
104
- if (!fieldRules) return false
105
-
106
- const rules = Array.isArray(fieldRules) ? fieldRules : [fieldRules]
107
- return rules.some((rule) => rule.required)
108
- })
109
-
110
- // 标签样式
111
- const labelStyle = computed(() => {
112
- if (!formContext) return {}
113
-
114
- const style: Record<string, any> = {}
115
-
116
- if (formContext.labelWidth !== 'auto') {
117
- style.width = addUnit(formContext.labelWidth)
118
- }
119
-
120
- if (formContext.labelAlign) {
121
- style.textAlign = formContext.labelAlign
122
- }
123
-
124
- return style
125
- })
126
-
127
- // 标签位置
128
- const labelPosition = computed(() => {
129
- return formContext?.labelPosition || 'left'
130
- })
131
-
132
- // 监听表单数据变化
133
- // watch(
134
- // () => formContext?.formData[props.prop],
135
- // (newVal) => {
136
- // if (props.prop && formContext) {
137
- // formContext.setFieldValue(props.prop, newVal)
138
- // validate('change')
139
- // }
140
- // },
141
- // { immediate: true },
142
- // )
143
-
144
- // 验证字段
145
- const validate = (trigger?: 'blur' | 'change') => {
146
- if (!formContext || !props.prop) return true
147
-
148
- const value = formContext.getFieldValue(props.prop)
149
- return formContext.validateField(props.prop, value, trigger)
150
- }
151
-
152
- // 重置字段
153
- const resetField = () => {
154
- if (!formContext || !props.prop) return
155
-
156
- formContext.setFieldValue(props.prop, undefined)
157
- formContext.validateField(props.prop, undefined)
158
- }
159
-
160
- // 清除验证
161
- const clearValidate = () => {
162
- if (!formContext || !props.prop) return
163
-
164
- delete formContext.errors[props.prop]
165
- }
166
-
167
- // 组件挂载时注册到表单
168
- onMounted(() => {
169
- if (formContext) {
170
- formContext.addFormItem({
171
- props: props,
172
- validate,
173
- resetField,
174
- clearValidate,
175
- })
176
- }
177
- })
178
-
179
- // 组件卸载时从表单中移除
180
- onUnmounted(() => {
181
- if (formContext) {
182
- formContext.removeFormItem({
183
- props: props,
184
- validate,
185
- resetField,
186
- clearValidate,
187
- })
188
- }
189
- })
190
-
191
- // 暴露方法给父组件
192
- defineExpose({
193
- validate,
194
- resetField,
195
- clearValidate,
196
- })
197
- </script>
198
-
199
- <style lang="scss" scoped>
200
- @import './index.scss';
201
- </style>
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 '../hy-form/typing'
1
+ import HyFormSimpleProps from "../hy-form/typing";
2
+ import type { ToRefs } from "vue";
2
3
 
3
- export interface FormContext extends HyFormSimpleProps {
4
- errors: Record<string, string>
5
- addFormItem: (item: any) => void
6
- removeFormItem: (item: any) => void
7
- validateField: (field: string, value: any, trigger?: 'blur' | 'change') => boolean
8
- setFieldValue: (field: string, value: any) => void
9
- getFieldValue: (field: string) => any
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
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hy-app",
3
- "version": "0.3.15",
4
- "description": "fix: 修复复选框默认值没有选中bug",
3
+ "version": "0.3.16",
4
+ "description": "fix: 修复复选框父子传递provide/inject传递,更新不响应问题",
5
5
  "main": "./index.ts",
6
6
  "private": false,
7
7
  "scripts": {},