hy-app 0.3.14 → 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,
@@ -113,27 +117,44 @@ watch(
113
117
  () => props.checked,
114
118
  (newValue) => {
115
119
  isChecked.value = newValue;
116
- if (props.checked) {
117
- checkboxGroup?.setCheckedStatus(props.value);
120
+ if (props.checked) checkboxGroup?.setCheckedStatus(props.value);
121
+ },
122
+ { immediate: true },
123
+ );
124
+
125
+ watch(
126
+ () => checkboxGroup?.modelValue.value,
127
+ (newVal) => {
128
+ if (newVal?.length) {
129
+ isChecked.value = newVal.includes(props.value);
130
+ } else {
131
+ isChecked.value = false;
118
132
  }
119
133
  },
120
134
  { immediate: true },
121
135
  );
122
136
 
123
- const isDisabled = (): boolean => checkboxGroup?.disabled || props.disabled;
137
+ const isDisabled = (): boolean =>
138
+ checkboxGroup?.disabled?.value || props.disabled;
124
139
 
125
140
  const checkboxStyle = computed(() => {
126
141
  const style: CSSProperties = {};
127
- if (checkboxGroup?.borderBottom && checkboxGroup?.placement === "row") {
142
+ if (
143
+ checkboxGroup?.borderBottom?.value &&
144
+ checkboxGroup?.placement?.value === "row"
145
+ ) {
128
146
  error(
129
147
  "检测到您将borderBottom设置为true,需要同时将hy-checkbox-group的placement设置为column才有效",
130
148
  );
131
149
  }
132
150
  // 当父组件设置了显示下边框并且排列形式为纵向时,给内容和边框之间加上一定间隔
133
- if (checkboxGroup?.borderBottom && checkboxGroup?.placement === "column") {
151
+ if (
152
+ checkboxGroup?.borderBottom?.value &&
153
+ checkboxGroup?.placement?.value === "column"
154
+ ) {
134
155
  style.paddingBottom = "8px";
135
156
  }
136
- return Object.assign(style, checkboxGroup?.customStyle);
157
+ return Object.assign(style, checkboxGroup?.customStyle?.value);
137
158
  });
138
159
  /**
139
160
  * @description 定义icon的Class类名
@@ -141,7 +162,7 @@ const checkboxStyle = computed(() => {
141
162
  const iconClasses = computed(() => {
142
163
  let classes: string[] = [];
143
164
  // 组件的形状
144
- classes.push("hy-checkbox--icon-wrap--" + checkboxGroup?.shape);
165
+ classes.push("hy-checkbox--icon-wrap--" + checkboxGroup?.shape?.value);
145
166
  if (isDisabled()) {
146
167
  classes.push("hy-checkbox--icon-wrap--disabled");
147
168
  }
@@ -163,18 +184,20 @@ const iconWrapStyle = computed(() => {
163
184
  const style: CSSProperties = {};
164
185
  style.backgroundColor =
165
186
  isChecked.value && !isDisabled()
166
- ? checkboxGroup?.activeColor
187
+ ? checkboxGroup?.activeColor?.value
167
188
  : !isDisabled()
168
189
  ? "#ffffff"
169
190
  : "";
170
191
  style.borderColor =
171
192
  isChecked.value && !isDisabled()
172
- ? checkboxGroup?.activeColor
173
- : checkboxGroup?.inactiveColor;
174
- if (checkboxGroup?.size) {
175
- 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
+ );
176
199
  style.height = addUnit(
177
- sizeType[checkboxGroup.size] ?? checkboxGroup.size,
200
+ sizeType[checkboxGroup.size.value] ?? checkboxGroup.size.value,
178
201
  );
179
202
  }
180
203
  return style;
@@ -195,7 +218,7 @@ const iconClickHandler = (e: Event) => {
195
218
  * */
196
219
  const wrapperClickHandler = (e: Event) => {
197
220
  e.stopPropagation();
198
- if (checkboxGroup?.labelDisabled || isDisabled()) return;
221
+ if (checkboxGroup?.labelDisabled?.value || isDisabled()) return;
199
222
  setCheckedStatus();
200
223
  };
201
224
  /**
@@ -203,7 +226,7 @@ const wrapperClickHandler = (e: Event) => {
203
226
  * */
204
227
  const labelClickHandler = (e: Event) => {
205
228
  e.stopPropagation();
206
- if (checkboxGroup?.labelDisabled || isDisabled()) return;
229
+ if (checkboxGroup?.labelDisabled?.value || isDisabled()) return;
207
230
  setCheckedStatus();
208
231
  };
209
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.14",
4
- "description": "修改小问题,新增复选框分开组件",
3
+ "version": "0.3.16",
4
+ "description": "fix: 修复复选框父子传递provide/inject传递,更新不响应问题",
5
5
  "main": "./index.ts",
6
6
  "private": false,
7
7
  "scripts": {},