From 7c3a0fafbf441fff2c15864958b6abea39a0da00 Mon Sep 17 00:00:00 2001 From: AlanLee <1445654576@qq.com> Date: Mon, 23 Aug 2021 11:35:50 +0800 Subject: [PATCH 01/48] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E4=B8=80?= =?UTF-8?q?=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/index.ts | 16 ++ devui/form/src/form-control/form-control.scss | 5 + devui/form/src/form-control/form-control.tsx | 19 +++ devui/form/src/form-item/form-item.scss | 9 + devui/form/src/form-item/form-item.tsx | 37 ++++ devui/form/src/form-label/form-label.scss | 39 +++++ devui/form/src/form-label/form-label.tsx | 31 ++++ .../src/form-operation/form-operation.scss | 5 + .../src/form-operation/form-operation.tsx | 16 ++ devui/form/src/form-types.ts | 60 +++++++ devui/form/src/form.scss | 3 + devui/form/src/form.tsx | 54 ++++++ sites/components/form/index.md | 161 ++++++++++++++++++ 13 files changed, 455 insertions(+) create mode 100644 devui/form/index.ts create mode 100644 devui/form/src/form-control/form-control.scss create mode 100644 devui/form/src/form-control/form-control.tsx create mode 100644 devui/form/src/form-item/form-item.scss create mode 100644 devui/form/src/form-item/form-item.tsx create mode 100644 devui/form/src/form-label/form-label.scss create mode 100644 devui/form/src/form-label/form-label.tsx create mode 100644 devui/form/src/form-operation/form-operation.scss create mode 100644 devui/form/src/form-operation/form-operation.tsx create mode 100644 devui/form/src/form-types.ts create mode 100644 devui/form/src/form.scss create mode 100644 devui/form/src/form.tsx create mode 100644 sites/components/form/index.md diff --git a/devui/form/index.ts b/devui/form/index.ts new file mode 100644 index 00000000..08c2cdcc --- /dev/null +++ b/devui/form/index.ts @@ -0,0 +1,16 @@ +import type { App } from 'vue' +import Form from './src/form' + +Form.install = function(app: App) { + app.component(Form.name, Form) +} + +export { Form } + +export default { + title: 'Form 表单', + category: '数据录入', + install(app: App): void { + app.use(Form as any) + } +} diff --git a/devui/form/src/form-control/form-control.scss b/devui/form/src/form-control/form-control.scss new file mode 100644 index 00000000..78cbf5c0 --- /dev/null +++ b/devui/form/src/form-control/form-control.scss @@ -0,0 +1,5 @@ +.form-control { + .star { + color: red; + } +} diff --git a/devui/form/src/form-control/form-control.tsx b/devui/form/src/form-control/form-control.tsx new file mode 100644 index 00000000..d631a35f --- /dev/null +++ b/devui/form/src/form-control/form-control.tsx @@ -0,0 +1,19 @@ +import { defineComponent, inject } from 'vue'; +import './form-control.scss'; + +export default defineComponent({ + name: 'DFormControl', + props: { + + }, + setup(props, ctx) { + const dForm = inject('dForm', {}); + console.log('form-control dForm', dForm); + + return () => { + return
+ {ctx.slots.default?.()} +
+ } + } +}) \ No newline at end of file diff --git a/devui/form/src/form-item/form-item.scss b/devui/form/src/form-item/form-item.scss new file mode 100644 index 00000000..82f9410c --- /dev/null +++ b/devui/form/src/form-item/form-item.scss @@ -0,0 +1,9 @@ +.form-item { + display: flex; + // align-items: center; + margin-bottom: 20px; +} + +.form-item-vertical { + flex-direction: column; +} diff --git a/devui/form/src/form-item/form-item.tsx b/devui/form/src/form-item/form-item.tsx new file mode 100644 index 00000000..786b3a04 --- /dev/null +++ b/devui/form/src/form-item/form-item.tsx @@ -0,0 +1,37 @@ +import { defineComponent, reactive, inject, onMounted } from 'vue'; +import { dFormEvents, IForm } from '../form-types'; +import './form-item.scss'; + +export default defineComponent({ + name: 'DFormItem', + props: { + dHasFeedback: { + type: Boolean, + default: false + } + }, + setup(props, ctx) { + + const dForm = reactive(inject('dForm', {} as IForm)); + const labelData = reactive(dForm.labelData); + console.log('form-item labelData', labelData); + console.log('form-item labelData.layout', labelData.layout); + + const formItem = reactive({ + dHasFeedback: props.dHasFeedback + }) + + + const isHorizontal = labelData.layout === 'horizontal'; + const isVertical = labelData.layout === 'vertical'; + + onMounted(() => { + dForm.formMitt.emit(dFormEvents.addField, formItem); + }) + return () => { + return
+ {ctx.slots.default?.()} +
+ } + } +}) \ No newline at end of file diff --git a/devui/form/src/form-label/form-label.scss b/devui/form/src/form-label/form-label.scss new file mode 100644 index 00000000..f9b26e75 --- /dev/null +++ b/devui/form/src/form-label/form-label.scss @@ -0,0 +1,39 @@ +.form-label { + // flex: 1 1 auto; + -moz-box-flex: 1; + text-align: left; + padding-bottom: 8px; + justify-content: flex-start; + align-self: flex-start; + margin-right: 16px; + + .devui-required { + &::before { + content: '*'; + color: red; + display: inline-block; + margin-right: 8px; + margin-left: -12px; + } + } +} + +.form-label_sm { + width: 80px; +} + +.form-label_sd { + width: 100px; +} + +.form-label_lg { + width: 150px; +} + +.form-label_center { + text-align: center; +} + +.form-label_end { + text-align: end; +} diff --git a/devui/form/src/form-label/form-label.tsx b/devui/form/src/form-label/form-label.tsx new file mode 100644 index 00000000..27203865 --- /dev/null +++ b/devui/form/src/form-label/form-label.tsx @@ -0,0 +1,31 @@ +import { defineComponent, inject, reactive, computed } from 'vue'; +import { IForm, formLabelProps, FormLabelProps } from '../form-types'; +import './form-label.scss'; + +export default defineComponent({ + name: 'DFormLabel', + props: formLabelProps, + setup(props: FormLabelProps, ctx) { + const dForm: IForm = reactive(inject('dForm')); + const labelData = reactive(dForm.labelData); + + const isHorizontal = computed(() => labelData.layout === 'horizontal').value; + const isLg = computed(() => labelData.labelSize === 'lg').value; + const isSm = computed(() => labelData.labelSize === 'sm').value; + const isCenter = computed(() => labelData.labelAlign === 'center').value; + const isEnd = computed(() => labelData.labelAlign === 'end').value; + + const wrapperCls = `form-label${isHorizontal ? (isSm ? ' form-label_sm' : (isLg ? ' form-label_lg' : ' form-label_sd')) : ''}${isCenter ? ' form-label_center' : (isEnd ? ' form-label_end' : '')}`; + const className = `${props.required ? ' devui-required' : ''}`; + const style = {display: isHorizontal ? 'inline' : 'block'}; + + return () => { + return + + {ctx.slots.default?.()} + {props.hasHelp && {(props.hasHelp ? props.helpTips : '?')}} + + + } + } +}) \ No newline at end of file diff --git a/devui/form/src/form-operation/form-operation.scss b/devui/form/src/form-operation/form-operation.scss new file mode 100644 index 00000000..3e4154ca --- /dev/null +++ b/devui/form/src/form-operation/form-operation.scss @@ -0,0 +1,5 @@ +.form-operation { + .star { + color: red; + } +} diff --git a/devui/form/src/form-operation/form-operation.tsx b/devui/form/src/form-operation/form-operation.tsx new file mode 100644 index 00000000..643591cd --- /dev/null +++ b/devui/form/src/form-operation/form-operation.tsx @@ -0,0 +1,16 @@ +import { defineComponent } from 'vue'; +import './form-operation.scss'; + +export default defineComponent({ + name: 'DFormOperation', + props: { + + }, + setup(props, ctx) { + return () => { + return
+ {ctx.slots.default?.()} +
+ } + } +}) \ No newline at end of file diff --git a/devui/form/src/form-types.ts b/devui/form/src/form-types.ts new file mode 100644 index 00000000..f3e25b88 --- /dev/null +++ b/devui/form/src/form-types.ts @@ -0,0 +1,60 @@ +import type { PropType, ExtractPropTypes } from 'vue' + +export const formProps = { + /* test: { + type: Object as PropType<{ xxx: xxx }> + } */ + formData: { + type: Object as PropType<{ key: ''; }>, + default: null + }, + layout: { + type: String, + default: 'horizontal', // 'horizontal'|'vertical'|'columns' + }, + labelSize: { + type: String, + default: '', // 'sm' | '' | 'lg' + }, + labelAlign: { + type: String, + default: 'start', // 'start' | 'center' | 'end' + }, +} as const + +export const formLabelProps = { + required: { + type: Boolean, + default: false + }, + hasHelp: { + type: Boolean, + default: false + }, + helpTips: { + type: String, + default: '' + } +} as const + +export interface ILabel { + layout: string + labelSize: string + labelAlign: string +} +export interface IForm { + formData: any + labelData: ILabel +} + +export type FormProps = ExtractPropTypes +export type FormLabelProps = ExtractPropTypes + +export interface IFormItem { + dHasFeedback: boolean +} + +export const dFormEvents = { + addField: 'd.form.addField', + removeField: 'd.form.removeField', +} as const diff --git a/devui/form/src/form.scss b/devui/form/src/form.scss new file mode 100644 index 00000000..14f623b8 --- /dev/null +++ b/devui/form/src/form.scss @@ -0,0 +1,3 @@ +.d-form { + // +} diff --git a/devui/form/src/form.tsx b/devui/form/src/form.tsx new file mode 100644 index 00000000..8760afd0 --- /dev/null +++ b/devui/form/src/form.tsx @@ -0,0 +1,54 @@ +import './form.scss' + +import { defineComponent, provide } from 'vue' +import { formProps, FormProps, IFormItem, dFormEvents } from './form-types' +import mitt from 'mitt' + +export default defineComponent({ + name: 'DForm', + props: formProps, + emits: ['submit'], + setup(props: FormProps, ctx) { + const formMitt = mitt(); + + const fields: IFormItem[] = []; + + formMitt.on(dFormEvents.addField, (field: any) => { + console.log('dFormEvents.addField field', field); + + if(field) { + fields.push(field); + } + + console.log('dFormEvents.addField fields', fields); + + }) + + formMitt.on(dFormEvents.removeField, field => { + console.log('dFormEvents.removeField field', field); + + }) + + + provide('dForm', { + formData: props.formData, + formMitt, + labelData: { + layout: props.layout, + labelSize: props.labelSize, + labelAlign: props.labelAlign, + } + }); + + console.log('form props', props); + + return () => { + return ( +
+ {ctx.slots.default?.()} +
+ ); + } + }, + +}) diff --git a/sites/components/form/index.md b/sites/components/form/index.md new file mode 100644 index 00000000..202df8dd --- /dev/null +++ b/sites/components/form/index.md @@ -0,0 +1,161 @@ +# Form 表单 + +表单用于收集数据 + +### 何时使用 + +标记了一个(或封装一组)操作命令,响应用户点击行为,触发相应的业务逻辑。 + +### 基础用法 + +
+ + + 用户名 + + + + + + 密码 + + + + + + 确定 + + +
+ + + +```html +
+ + + 用户名 + + + + + + 密码 + + + + + + 确定 + + +
+``` + +### 横向排列 + +
+ + + 用户名 + + + + + + 密码 + + + + + + 确定 + + +
+ + +```html + +``` + -- Gitee From 66067aa38cbd995524f079c7312cabf5d1172d33 Mon Sep 17 00:00:00 2001 From: AlanLee <1445654576@qq.com> Date: Mon, 23 Aug 2021 20:53:19 +0800 Subject: [PATCH 02/48] =?UTF-8?q?fix:=20=E5=AE=8C=E6=88=90=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E9=87=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/src/form-item/form-item.tsx | 42 ++++-- devui/form/src/form-types.ts | 3 + devui/form/src/form.tsx | 28 ++-- sites/components/form/index.md | 174 +++++++++++++------------ 4 files changed, 144 insertions(+), 103 deletions(-) diff --git a/devui/form/src/form-item/form-item.tsx b/devui/form/src/form-item/form-item.tsx index 786b3a04..4c48ccc9 100644 --- a/devui/form/src/form-item/form-item.tsx +++ b/devui/form/src/form-item/form-item.tsx @@ -8,19 +8,33 @@ export default defineComponent({ dHasFeedback: { type: Boolean, default: false + }, + cname: { + type: String, + default: 'd-form-item' + }, + prop: { + type: String, + default: '' } }, setup(props, ctx) { - const dForm = reactive(inject('dForm', {} as IForm)); + const dForm: IForm = reactive(inject('dForm', {} as IForm)); + const formData = reactive(dForm.formData); const labelData = reactive(dForm.labelData); - console.log('form-item labelData', labelData); - console.log('form-item labelData.layout', labelData.layout); + + const resetField = () => { + formData[props.prop] = null; + console.log('form-item resetField formData', formData); + } const formItem = reactive({ - dHasFeedback: props.dHasFeedback + dHasFeedback: props.dHasFeedback, + cname: props.cname, + prop: props.prop, + resetField }) - const isHorizontal = labelData.layout === 'horizontal'; const isVertical = labelData.layout === 'vertical'; @@ -28,10 +42,20 @@ export default defineComponent({ onMounted(() => { dForm.formMitt.emit(dFormEvents.addField, formItem); }) - return () => { - return
- {ctx.slots.default?.()} -
+ return { + isHorizontal, + isVertical, + resetField } + }, + + render() { + const { + isHorizontal, + isVertical + } = this; + return
+ {this.$slots.default?.()} +
} }) \ No newline at end of file diff --git a/devui/form/src/form-types.ts b/devui/form/src/form-types.ts index f3e25b88..c9e1fcf1 100644 --- a/devui/form/src/form-types.ts +++ b/devui/form/src/form-types.ts @@ -1,3 +1,4 @@ +import { Emitter } from 'mitt' import type { PropType, ExtractPropTypes } from 'vue' export const formProps = { @@ -45,6 +46,7 @@ export interface ILabel { export interface IForm { formData: any labelData: ILabel + formMitt: Emitter } export type FormProps = ExtractPropTypes @@ -52,6 +54,7 @@ export type FormLabelProps = ExtractPropTypes export interface IFormItem { dHasFeedback: boolean + resetField(): void } export const dFormEvents = { diff --git a/devui/form/src/form.tsx b/devui/form/src/form.tsx index 8760afd0..0da2f36c 100644 --- a/devui/form/src/form.tsx +++ b/devui/form/src/form.tsx @@ -10,8 +10,14 @@ export default defineComponent({ emits: ['submit'], setup(props: FormProps, ctx) { const formMitt = mitt(); - const fields: IFormItem[] = []; + const resetFormFields = () => { + console.log('resetFormFields fields', fields); + fields.forEach((field: IFormItem) => { + console.log('resetFormFields field', field); + field.resetField(); + }) + } formMitt.on(dFormEvents.addField, (field: any) => { console.log('dFormEvents.addField field', field); @@ -28,8 +34,7 @@ export default defineComponent({ console.log('dFormEvents.removeField field', field); }) - - + provide('dForm', { formData: props.formData, formMitt, @@ -42,13 +47,18 @@ export default defineComponent({ console.log('form props', props); - return () => { - return ( -
- {ctx.slots.default?.()} -
- ); + return { + formMitt, + fields, + resetFormFields, } }, + render() { + return ( +
+ {this.$slots.default?.()} +
+ ); + } }) diff --git a/sites/components/form/index.md b/sites/components/form/index.md index 202df8dd..6e038c63 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -4,12 +4,34 @@ ### 何时使用 -标记了一个(或封装一组)操作命令,响应用户点击行为,触发相应的业务逻辑。 +需要进行数据收集、数据校验、数据提交功能时。 ### 基础用法
- + + + 用户名 + + + + + + 密码 + + + + + + 确定 + 重置 + + +
+ +```html +
+ 用户名 @@ -23,13 +45,41 @@ - 确定 + 确定
+``` + +### 横向排列 + +
+ + + 用户名 + + + + + + 密码 + + + + + + 确定 + + +
+ + +```html + +``` - -```html -
- - - 用户名 - - - - - - 密码 - - - - - - 确定 - - -
-``` - -### 横向排列 - -
- - - 用户名 - - - - - - 密码 - - - - - - 确定 - - -
- - -```html - -``` - + \ No newline at end of file -- Gitee From 5615c24cdd9e4aa739f7c4c62ceef14ba7612217 Mon Sep 17 00:00:00 2001 From: AlanLee <1445654576@qq.com> Date: Mon, 23 Aug 2021 20:54:04 +0800 Subject: [PATCH 03/48] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0mitt=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index c6f52108..a14f3728 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "@devui-design/icons": "^1.3.0", "@types/lodash-es": "^4.17.4", "lodash-es": "^4.17.20", + "mitt": "^3.0.0", "vue": "^3.1.1", "vue-router": "^4.0.3" }, -- Gitee From aa268f9560c10cdfc970e0dae169acb833b3cff2 Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Tue, 24 Aug 2021 00:22:57 +0800 Subject: [PATCH 04/48] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sites/components/form/index.md | 243 +++++++++++++++++++++++++++++++-- 1 file changed, 230 insertions(+), 13 deletions(-) diff --git a/sites/components/form/index.md b/sites/components/form/index.md index 6e038c63..4cd3bacc 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -10,16 +10,63 @@
- - 用户名 + + Name - + - - 密码 + + Description - + + + + + Select + + + + + + Multiple options + + + + + + Tags + + + + + + Radio + + + 男 + + + 女 + + + + + Switch + + + + + + Execution day + + @@ -31,21 +78,22 @@ ```html
- - + + 用户名 - + 密码 - + 确定 + 重置
@@ -75,7 +123,159 @@ ```html +
+ + + 用户名 + + + + + + 密码 + + + + + + 确定 + + +
+``` + +### 弹框表单 + +> todo + +弹框表单,弹框建议是400px,550px,700px,900px,建议宽高比是16: 9、3: 2。 + +
+ + + +
+ + +```html +
+
+``` + +### 多列表单 + +> todo + +多列表单。 + +
+ + + +
+ + +```html +
+ +
+``` + +### 模板驱动表单验证 + +> todo + +模板中绑定ngModel、ngGroupModel、ngForm的元素,可使用dValidateRules配置校验规则。 + +
+ + + +
+ + +```html +
+ +
+``` + +### 响应式表单验证 + +> todo + +模板中绑定formGroup、formControlName、formControl,使用dValidateRules配置校验规则。 + +
+ + + +
+ + +```html +
+ +
+``` + +### 指定表单Feedback状态 + +> todo + +你可通过对d-form-control设置feedbackStatus手动指定反馈状态。当前已支持状态:success、error、pending。 + +
+ + + +
+ + +```html +
+ +
+``` + +### 表单协同验证 + +> todo + +在一些场景下,你的多个表单组件互相依赖,需共同校验(如注册场景中的密码输入与确认密码),此时你需要用协同验证指令dValidateSyncKey来为需要系统校验的组件指定相同的keydValidateSyncKey指令支持模板驱动表单与响应式表单,以下示例以模板驱动表单为例:password与confirmPassword设置相同的dValidateSyncKey值,在其中一个组件值变更时,另一个组件也将进行校验。 + +
+ + + +
+ + +```html +
+ +
+``` + +### 跨组件验证 + +> todo + +当前Angular Form默认暂不支持跨组件共享表单校验状态,对于响应式表单,你可使用统一管理model,向下透传的方式进行组件组织。 +针对模板驱动表单,你可使用在子组件声明时进行容器注入的方式,将你需要的ngModelGroup或NgForm容器进行注入,以供模板中表单元素自动获取父容器。 + +
+ + + +
+ + +```html +
+ +
``` \ No newline at end of file + + + + -- Gitee From 422dc2605178162d97b781d70bec85a1fe9a6f96 Mon Sep 17 00:00:00 2001 From: AlanLee <1445654576@qq.com> Date: Wed, 25 Aug 2021 16:35:03 +0800 Subject: [PATCH 06/48] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/src/form-item/form-item.tsx | 26 ++++++++++---------------- devui/form/src/form-types.ts | 7 ++++--- devui/input/src/input.tsx | 8 +++++++- sites/components/form/index.md | 20 ++++++++++---------- 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/devui/form/src/form-item/form-item.tsx b/devui/form/src/form-item/form-item.tsx index 298c9f6c..109ee323 100644 --- a/devui/form/src/form-item/form-item.tsx +++ b/devui/form/src/form-item/form-item.tsx @@ -1,7 +1,8 @@ -import { defineComponent, reactive, inject, onMounted} from 'vue'; +import { defineComponent, reactive, inject, onMounted, provide} from 'vue'; import { dFormEvents, IForm } from '../form-types'; import './form-item.scss'; import AsyncValidator, { Rules } from 'async-validator'; +import mitt from 'mitt'; export default defineComponent({ name: 'DFormItem', @@ -10,23 +11,17 @@ export default defineComponent({ type: Boolean, default: false }, - cname: { - type: String, - default: 'd-form-item' - }, prop: { type: String, default: '' } }, setup(props, ctx) { - + const formItemMitt = mitt(); const dForm: IForm = reactive(inject('dForm', {} as IForm)); const formData = reactive(dForm.formData); const labelData = reactive(dForm.labelData); const rules = reactive(dForm.rules); - - const resetField = () => { switch(typeof formData[props.prop]) { @@ -51,16 +46,17 @@ export default defineComponent({ const formItem = reactive({ dHasFeedback: props.dHasFeedback, - cname: props.cname, prop: props.prop, + formItemMitt, resetField }) + provide('dFormItem', formItem); const isHorizontal = labelData.layout === 'horizontal'; const isVertical = labelData.layout === 'vertical'; const isColumns = labelData.layout === 'columns'; - const nameField = rules.name; + const nameField = rules ? rules.name : []; const descriptor: Rules = { name: { @@ -88,9 +84,10 @@ export default defineComponent({ onMounted(() => { dForm.formMitt.emit(dFormEvents.addField, formItem); - - - + dForm.formMitt.on('d.form.inputBlur', (e) => { + console.log('test-> form-item 监听输入框blur事件', e); + + }); validator.validate({ name: 'muji222'}).then(() => { // validation passed or without error message console.log('validator success'); @@ -99,8 +96,6 @@ export default defineComponent({ console.log('validator errors', errors); console.log('validator fields', fields); nameField && console.log('validator nameField', nameField[0].message); - - }); }) return { @@ -122,7 +117,6 @@ export default defineComponent({ return
{this.$slots.default?.()}
{rules.name && rules.name[0].message}
-
} }) \ No newline at end of file diff --git a/devui/form/src/form-types.ts b/devui/form/src/form-types.ts index 95c3767d..b345027f 100644 --- a/devui/form/src/form-types.ts +++ b/devui/form/src/form-types.ts @@ -7,7 +7,7 @@ export const formProps = { } */ formData: { type: Object as PropType<{ key: ''; }>, - default: null + default: {} }, layout: { type: String, @@ -22,8 +22,8 @@ export const formProps = { default: 'start', // 'start' | 'center' | 'end' }, rules: { - type: Object as PropType<{key: '';}>, - default: null, + type: Array, + default: [], }, } as const @@ -65,4 +65,5 @@ export interface IFormItem { export const dFormEvents = { addField: 'd.form.addField', removeField: 'd.form.removeField', + inputBlur: 'd.form.inputBlur', } as const diff --git a/devui/input/src/input.tsx b/devui/input/src/input.tsx index d1c2073d..80db73e2 100644 --- a/devui/input/src/input.tsx +++ b/devui/input/src/input.tsx @@ -1,6 +1,7 @@ -import { defineComponent, computed } from 'vue'; +import { defineComponent, computed, inject, reactive } from 'vue'; import { inputProps } from './use-input'; import './input.scss' +import mitt from 'mitt'; export default defineComponent({ name: 'DInput', @@ -14,6 +15,7 @@ export default defineComponent({ [sizeCls.value]: props.size !== '' } }); + const formItem: any = reactive(inject('dFormItem')); const inputType = computed(() => props.showPassword ? 'password' : 'text'); const onInput = ($event: Event) => { ctx.emit('update:value', ($event.target as HTMLInputElement).value); @@ -23,6 +25,10 @@ export default defineComponent({ }, onBlur = () => { ctx.emit('blur'); + formItem.formItemMitt.emit('d.form.inputBlur'); + // console.log('formItem', formItem); + + }, onChange = ($event: Event) => { ctx.emit('change', ($event.target as HTMLInputElement).value); diff --git a/sites/components/form/index.md b/sites/components/form/index.md index 5318a204..412992a2 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -12,31 +12,31 @@
- + Name - + Description - + Select - + Multiple options - + Tags - + Radio @@ -59,13 +59,13 @@ - + Switch - + Execution day @@ -81,13 +81,13 @@ ```html
- + 用户名 - + 密码 -- Gitee From 8e6e3b51c18d0ca761eb49ce9a81ffce5f7d4b4e Mon Sep 17 00:00:00 2001 From: AlanLee <1445654576@qq.com> Date: Wed, 25 Aug 2021 17:58:45 +0800 Subject: [PATCH 07/48] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E7=9B=91?= =?UTF-8?q?=E5=90=AC=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/src/form-item/form-item.tsx | 2 +- devui/input/src/input.tsx | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/devui/form/src/form-item/form-item.tsx b/devui/form/src/form-item/form-item.tsx index 109ee323..48a5b51b 100644 --- a/devui/form/src/form-item/form-item.tsx +++ b/devui/form/src/form-item/form-item.tsx @@ -84,7 +84,7 @@ export default defineComponent({ onMounted(() => { dForm.formMitt.emit(dFormEvents.addField, formItem); - dForm.formMitt.on('d.form.inputBlur', (e) => { + formItem.formItemMitt.on('d.form.inputBlur', (e) => { console.log('test-> form-item 监听输入框blur事件', e); }); diff --git a/devui/input/src/input.tsx b/devui/input/src/input.tsx index 80db73e2..94760207 100644 --- a/devui/input/src/input.tsx +++ b/devui/input/src/input.tsx @@ -15,7 +15,7 @@ export default defineComponent({ [sizeCls.value]: props.size !== '' } }); - const formItem: any = reactive(inject('dFormItem')); + const formItem: any = inject('dFormItem'); const inputType = computed(() => props.showPassword ? 'password' : 'text'); const onInput = ($event: Event) => { ctx.emit('update:value', ($event.target as HTMLInputElement).value); @@ -26,7 +26,9 @@ export default defineComponent({ onBlur = () => { ctx.emit('blur'); formItem.formItemMitt.emit('d.form.inputBlur'); - // console.log('formItem', formItem); + console.log('formItem', formItem); + console.log('test-> input blur'); + }, -- Gitee From b09c92d0072012c5a37ee88eb0da20cc2feb220e Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Wed, 25 Aug 2021 23:05:13 +0800 Subject: [PATCH 08/48] =?UTF-8?q?fix:=20=E5=AE=8C=E6=88=90=E7=AE=80?= =?UTF-8?q?=E5=8D=95=E7=9A=84=E8=A1=A8=E5=8D=95=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/src/form-control/form-control.tsx | 2 +- devui/form/src/form-item/form-item.tsx | 63 +++++++++++--------- devui/form/src/form.tsx | 12 ++-- sites/components/form/index.md | 26 ++++++-- 4 files changed, 63 insertions(+), 40 deletions(-) diff --git a/devui/form/src/form-control/form-control.tsx b/devui/form/src/form-control/form-control.tsx index d631a35f..db5caadc 100644 --- a/devui/form/src/form-control/form-control.tsx +++ b/devui/form/src/form-control/form-control.tsx @@ -8,7 +8,7 @@ export default defineComponent({ }, setup(props, ctx) { const dForm = inject('dForm', {}); - console.log('form-control dForm', dForm); + // console.log('form-control dForm', dForm); return () => { return
diff --git a/devui/form/src/form-item/form-item.tsx b/devui/form/src/form-item/form-item.tsx index 48a5b51b..45d759f4 100644 --- a/devui/form/src/form-item/form-item.tsx +++ b/devui/form/src/form-item/form-item.tsx @@ -1,4 +1,4 @@ -import { defineComponent, reactive, inject, onMounted, provide} from 'vue'; +import { defineComponent, reactive, inject, onMounted, provide, ref} from 'vue'; import { dFormEvents, IForm } from '../form-types'; import './form-item.scss'; import AsyncValidator, { Rules } from 'async-validator'; @@ -22,6 +22,10 @@ export default defineComponent({ const formData = reactive(dForm.formData); const labelData = reactive(dForm.labelData); const rules = reactive(dForm.rules); + + rules.name && console.log('test-> formData', formData); + // console.log('test-> rules', rules); + const resetField = () => { switch(typeof formData[props.prop]) { @@ -57,66 +61,71 @@ export default defineComponent({ const isColumns = labelData.layout === 'columns'; const nameField = rules ? rules.name : []; + const showMessage = ref(false); const descriptor: Rules = { name: { type: 'string', required: true, - validator: (rule, value) => value === 'muji', + validator: (rule, value) => value.length !== 0, }, age: { type: 'number', - asyncValidator: (rule, value) => { - return new Promise((resolve, reject) => { - if (value < 18) { - reject('too young'); // reject with error message - } else { - resolve(value); - } - }); - }, + validator: (rule, value) => value > 0, + // asyncValidator: (rule, value) => { + // return new Promise((resolve, reject) => { + // if (value < 18) { + // reject('too young'); // reject with error message + // } else { + // resolve(value); + // } + // }); + // }, }, }; - rules.name && console.log('test-> form-item rules toRefs', rules.name[0].message); - const validator = new AsyncValidator(descriptor); onMounted(() => { dForm.formMitt.emit(dFormEvents.addField, formItem); - formItem.formItemMitt.on('d.form.inputBlur', (e) => { - console.log('test-> form-item 监听输入框blur事件', e); - - }); - validator.validate({ name: 'muji222'}).then(() => { - // validation passed or without error message - console.log('validator success'); - }).catch(({ errors, fields }) => { - console.log('validator errors', errors); - console.log('validator fields', fields); - nameField && console.log('validator nameField', nameField[0].message); + props.prop && rules && formItem.formItemMitt.on('d.form.inputBlur', (e) => { + validator.validate({ ...formData }).then(() => { + // validation passed or without error message + console.log('validator success'); + showMessage.value = false; + + }).catch(({ errors, fields }) => { + console.log('validator errors', errors); + console.log('validator fields', fields); + showMessage.value = true; + }); }); + }) return { isHorizontal, isVertical, isColumns, resetField, - rules + rules, + showMessage } }, - render() { + render(props) { + console.log('props', props); + const { isHorizontal, isVertical, isColumns, rules, + showMessage, } = this; return
{this.$slots.default?.()} -
{rules.name && rules.name[0].message}
+
{showMessage && rules[props.prop] && rules[props.prop][0].message}
} }) \ No newline at end of file diff --git a/devui/form/src/form.tsx b/devui/form/src/form.tsx index 55b2fe70..ca559956 100644 --- a/devui/form/src/form.tsx +++ b/devui/form/src/form.tsx @@ -12,26 +12,26 @@ export default defineComponent({ const formMitt = mitt(); const fields: IFormItem[] = []; const resetFormFields = () => { - console.log('resetFormFields fields', fields); + // console.log('resetFormFields fields', fields); fields.forEach((field: IFormItem) => { - console.log('resetFormFields field', field); + // console.log('resetFormFields field', field); field.resetField(); }) } formMitt.on(dFormEvents.addField, (field: any) => { - console.log('dFormEvents.addField field', field); + // console.log('dFormEvents.addField field', field); if(field) { fields.push(field); } - console.log('dFormEvents.addField fields', fields); + // console.log('dFormEvents.addField fields', fields); }) formMitt.on(dFormEvents.removeField, field => { - console.log('dFormEvents.removeField field', field); + // console.log('dFormEvents.removeField field', field); }) @@ -46,7 +46,7 @@ export default defineComponent({ rules: props.rules, }); - console.log('form props', props); + // console.log('form props', props); return { formMitt, diff --git a/sites/components/form/index.md b/sites/components/form/index.md index 412992a2..0a617472 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -232,11 +232,17 @@ Label左右布局方式。 模板中绑定formGroup、formControlName、formControl,使用dValidateRules配置校验规则。
- + Name - + + + + + Age + + @@ -344,15 +350,20 @@ export default defineComponent({ username: 'haha2' }); - console.log('form formModel', formModel); + let validateFormModel: IFormModel = reactive({ + name: 'AlanLee97', + age: 24, + }); + + // console.log('form formModel', formModel); const dForm1 = ref(null); const dForm2 = ref(null); onMounted(() => { - console.log('dForm1', dForm1.value); - console.log('dForm2', dForm2.value); + // console.log('dForm1', dForm1.value); + // console.log('dForm2', dForm2.value); }); @@ -395,7 +406,9 @@ export default defineComponent({ ]); const rules = reactive({ - name: [{ required: true, message: '不能为空', trigger: 'blur'}] + name: [{ required: true, message: '不能为空', trigger: 'blur'}], + age: [{ required: true, message: '年龄不能小于0', trigger: 'blur'}], + }) return { @@ -411,6 +424,7 @@ export default defineComponent({ baseSelectOptions, suggestionList, rules, + validateFormModel, } } }) -- Gitee From ac308b24aa3af912928b962a643a625366c5751a Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sat, 28 Aug 2021 22:18:07 +0800 Subject: [PATCH 09/48] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0formItem?= =?UTF-8?q?=E7=9A=84=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/input/src/input.tsx | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/devui/input/src/input.tsx b/devui/input/src/input.tsx index 94760207..1bc61bac 100644 --- a/devui/input/src/input.tsx +++ b/devui/input/src/input.tsx @@ -1,7 +1,7 @@ -import { defineComponent, computed, inject, reactive } from 'vue'; +import { defineComponent, computed, inject } from 'vue'; import { inputProps } from './use-input'; import './input.scss' -import mitt from 'mitt'; +import { dFormItemEvents, IFormItem } from '../../form/src/form-types'; export default defineComponent({ name: 'DInput', @@ -15,25 +15,22 @@ export default defineComponent({ [sizeCls.value]: props.size !== '' } }); - const formItem: any = inject('dFormItem'); + const formItem: IFormItem = inject('dFormItem'); const inputType = computed(() => props.showPassword ? 'password' : 'text'); const onInput = ($event: Event) => { ctx.emit('update:value', ($event.target as HTMLInputElement).value); + formItem.formItemMitt.emit(dFormItemEvents.input); }, onFocus = () => { ctx.emit('focus'); }, onBlur = () => { ctx.emit('blur'); - formItem.formItemMitt.emit('d.form.inputBlur'); - console.log('formItem', formItem); - console.log('test-> input blur'); - - - + formItem.formItemMitt.emit(dFormItemEvents.blur); }, onChange = ($event: Event) => { ctx.emit('change', ($event.target as HTMLInputElement).value); + formItem.formItemMitt.emit(dFormItemEvents.change); }, onKeydown = ($event: KeyboardEvent) => { ctx.emit('keydown', $event); -- Gitee From 6f047895c02bde33d6c259534b0133fb71e6efc3 Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sat, 28 Aug 2021 22:23:02 +0800 Subject: [PATCH 10/48] =?UTF-8?q?fix:=20=E5=AE=8C=E6=88=90=E7=AE=80?= =?UTF-8?q?=E5=8D=95=E5=93=8D=E5=BA=94=E5=BC=8F=E8=A1=A8=E5=8D=95=E9=AA=8C?= =?UTF-8?q?=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/src/form-item/form-item.tsx | 114 ++++++++++++++----------- devui/form/src/form-types.ts | 8 ++ sites/components/form/index.md | 25 +++++- 3 files changed, 96 insertions(+), 51 deletions(-) diff --git a/devui/form/src/form-item/form-item.tsx b/devui/form/src/form-item/form-item.tsx index 45d759f4..1d18e2af 100644 --- a/devui/form/src/form-item/form-item.tsx +++ b/devui/form/src/form-item/form-item.tsx @@ -1,5 +1,5 @@ -import { defineComponent, reactive, inject, onMounted, provide, ref} from 'vue'; -import { dFormEvents, IForm } from '../form-types'; +import { defineComponent, reactive, inject, onMounted, onBeforeUnmount, provide, ref} from 'vue'; +import { dFormEvents, dFormItemEvents, IForm } from '../form-types'; import './form-item.scss'; import AsyncValidator, { Rules } from 'async-validator'; import mitt from 'mitt'; @@ -16,16 +16,12 @@ export default defineComponent({ default: '' } }, - setup(props, ctx) { + setup(props) { const formItemMitt = mitt(); const dForm: IForm = reactive(inject('dForm', {} as IForm)); const formData = reactive(dForm.formData); const labelData = reactive(dForm.labelData); const rules = reactive(dForm.rules); - - rules.name && console.log('test-> formData', formData); - // console.log('test-> rules', rules); - const resetField = () => { switch(typeof formData[props.prop]) { @@ -60,72 +56,92 @@ export default defineComponent({ const isVertical = labelData.layout === 'vertical'; const isColumns = labelData.layout === 'columns'; - const nameField = rules ? rules.name : []; const showMessage = ref(false); + const tipMessage = ref(''); - const descriptor: Rules = { - name: { - type: 'string', - required: true, - validator: (rule, value) => value.length !== 0, - }, - age: { - type: 'number', - validator: (rule, value) => value > 0, - // asyncValidator: (rule, value) => { - // return new Promise((resolve, reject) => { - // if (value < 18) { - // reject('too young'); // reject with error message - // } else { - // resolve(value); - // } - // }); - // }, - }, - }; + const validate = (trigger: string) => { + console.log('trigger', trigger); + + const ruleKey = props.prop; + const ruleItem = rules[ruleKey]; + const descriptor: Rules = {}; + descriptor[ruleKey] = ruleItem; + + const validator = new AsyncValidator(descriptor); - const validator = new AsyncValidator(descriptor); + validator.validate({[ruleKey]: formData[ruleKey]}).then(() => { + showMessage.value = false; + tipMessage.value = ''; + }).catch(({ errors }) => { + console.log('validator errors', errors); + + showMessage.value = true; + tipMessage.value = errors[0].message; + }); + } + const validateEvents = []; - onMounted(() => { - dForm.formMitt.emit(dFormEvents.addField, formItem); + const addValidateEvents = () => { + + if(rules && rules[props.prop]) { + const ruleItem = rules[props.prop]; + let eventName = ruleItem['trigger']; - props.prop && rules && formItem.formItemMitt.on('d.form.inputBlur', (e) => { - validator.validate({ ...formData }).then(() => { - // validation passed or without error message - console.log('validator success'); - showMessage.value = false; - - }).catch(({ errors, fields }) => { - console.log('validator errors', errors); - console.log('validator fields', fields); - showMessage.value = true; + if(Array.isArray(ruleItem)) { + ruleItem.forEach((item) => { + eventName = item['trigger']; + const cb = () => validate(eventName); + validateEvents.push({eventName: cb}); + formItem.formItemMitt.on(dFormItemEvents[eventName], cb); + }); + }else { + const cb = () => validate(eventName); + validateEvents.push({eventName: cb}); + ruleItem && formItem.formItemMitt.on(dFormItemEvents[eventName], cb); + } + } + } + + const removeValidateEvents = () => { + if(rules && rules[props.prop] && validateEvents.length > 0) { + validateEvents.forEach(item => { + formItem.formItemMitt.off(item.eventName, item.cb); }); - }); + } + } - }) + onMounted(() => { + dForm.formMitt.emit(dFormEvents.addField, formItem); + addValidateEvents(); + }); + + onBeforeUnmount(() => { + console.log('onBeforeUnmount'); + + removeValidateEvents(); + }); return { isHorizontal, isVertical, isColumns, resetField, rules, - showMessage + showMessage, + tipMessage } }, - render(props) { - console.log('props', props); + render() { const { isHorizontal, isVertical, - isColumns, - rules, showMessage, + tipMessage, } = this; return
{this.$slots.default?.()} -
{showMessage && rules[props.prop] && rules[props.prop][0].message}
+
{showMessage && tipMessage}
} }) \ No newline at end of file diff --git a/devui/form/src/form-types.ts b/devui/form/src/form-types.ts index b345027f..a07362a1 100644 --- a/devui/form/src/form-types.ts +++ b/devui/form/src/form-types.ts @@ -59,6 +59,8 @@ export type FormLabelProps = ExtractPropTypes export interface IFormItem { dHasFeedback: boolean + prop: string + formItemMitt: Emitter resetField(): void } @@ -67,3 +69,9 @@ export const dFormEvents = { removeField: 'd.form.removeField', inputBlur: 'd.form.inputBlur', } as const + +export const dFormItemEvents = { + blur: 'd.form.blur', + change: 'd.form.change', + input: 'd.form.input', +} as const diff --git a/sites/components/form/index.md b/sites/components/form/index.md index 0a617472..b7ff229b 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -239,6 +239,12 @@ Label左右布局方式。 + + NickName + + + + Age @@ -351,7 +357,8 @@ export default defineComponent({ }); let validateFormModel: IFormModel = reactive({ - name: 'AlanLee97', + name: 'AlanLee', + nickname: 'AlanLee97', age: 24, }); @@ -407,7 +414,21 @@ export default defineComponent({ const rules = reactive({ name: [{ required: true, message: '不能为空', trigger: 'blur'}], - age: [{ required: true, message: '年龄不能小于0', trigger: 'blur'}], + nickname: { required: true, message: '不能为空', trigger: 'blur'}, + age: [ + { + required: true, + message: '年龄不能小于0', + trigger: 'blur', + validator: (rule, value) => value > 0 + }, + { + required: true, + message: '年龄不能大于120', + trigger: 'input', + validator: (rule, value) => value < 120 + } + ], }) -- Gitee From a5103efcc63366c87a7f7173635d059b8be74834 Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sat, 28 Aug 2021 23:12:44 +0800 Subject: [PATCH 11/48] =?UTF-8?q?fix:=20=E7=AE=80=E5=8D=95=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E8=A1=A8=E5=8D=95=E6=8F=90=E4=BA=A4=E4=B8=8E=E9=87=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/src/form-item/form-item.tsx | 20 ++------------------ devui/form/src/form.tsx | 16 ++++++++++++++-- sites/components/form/index.md | 4 ++-- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/devui/form/src/form-item/form-item.tsx b/devui/form/src/form-item/form-item.tsx index 1d18e2af..a0efeded 100644 --- a/devui/form/src/form-item/form-item.tsx +++ b/devui/form/src/form-item/form-item.tsx @@ -20,28 +20,12 @@ export default defineComponent({ const formItemMitt = mitt(); const dForm: IForm = reactive(inject('dForm', {} as IForm)); const formData = reactive(dForm.formData); + const initFormTemData = formData[props.prop]; const labelData = reactive(dForm.labelData); const rules = reactive(dForm.rules); const resetField = () => { - switch(typeof formData[props.prop]) { - case 'string': - formData[props.prop] = ''; - break; - case 'number': - formData[props.prop] = undefined; - break; - case 'boolean': - formData[props.prop] = false; - break; - } - if(Array.isArray(formData[props.prop])) { - formData[props.prop] = []; - } - if(typeof props.prop === 'object') { - formData[props.prop] = null; - } - console.log('form-item resetField formData', formData); + formData[props.prop] = initFormTemData; } const formItem = reactive({ diff --git a/devui/form/src/form.tsx b/devui/form/src/form.tsx index ca559956..b689af93 100644 --- a/devui/form/src/form.tsx +++ b/devui/form/src/form.tsx @@ -8,7 +8,7 @@ export default defineComponent({ name: 'DForm', props: formProps, emits: ['submit'], - setup(props: FormProps) { + setup(props: FormProps, ctx) { const formMitt = mitt(); const fields: IFormItem[] = []; const resetFormFields = () => { @@ -46,17 +46,29 @@ export default defineComponent({ rules: props.rules, }); + const onSubmit = (e) => { + // console.log(e); + e.preventDefault(); + + console.log('form onSubmit e', e); + + ctx.emit('submit'); + + } + + // console.log('form props', props); return { formMitt, fields, resetFormFields, + onSubmit, } }, render() { return ( -
+ {this.$slots.default?.()}
); diff --git a/sites/components/form/index.md b/sites/components/form/index.md index b7ff229b..dffe9a39 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -72,8 +72,8 @@
- 确定 - 重置 + 确定 + 重置
-- Gitee From 186e531a2383520b9aaffc009e01c41be39cf6b3 Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sat, 28 Aug 2021 23:28:35 +0800 Subject: [PATCH 12/48] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0md=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sites/components/form/index.md | 223 ++++++++++++++++++++++++++++++--- 1 file changed, 209 insertions(+), 14 deletions(-) diff --git a/sites/components/form/index.md b/sites/components/form/index.md index dffe9a39..90198624 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -8,6 +8,8 @@ ### 基础用法 +> done + 基本用法当中,Label是在数据框的上面。
@@ -73,36 +75,160 @@ 确定 - 重置 + 重置
```html
- - - 用户名 + + + Name - + - - 密码 + + Description + + + + + + Select + + + + + + Multiple options + + + + + + Tags - + + + + + Radio + + + 男 + + + 女 + + + + + Switch + + + + + + Execution day + + - 确定 - 重置 + 确定 + 重置
``` +```ts + +``` + ### 横向排列 +> done + Label左右布局方式。
@@ -227,7 +353,7 @@ Label左右布局方式。 ### 响应式表单验证 -> todo +> done 模板中绑定formGroup、formControlName、formControl,使用dValidateRules配置校验规则。 @@ -257,10 +383,79 @@ Label左右布局方式。 ```html
- + + + Name + + + + + + NickName + + + + + + Age + + + + +
``` +```ts + +``` + ### 指定表单Feedback状态 > todo @@ -398,7 +593,7 @@ export default defineComponent({ console.log('form md onConfirm2', toRefs(formModel2)); } - const resetDFrom1 = () => { + const resetDForm1 = () => { dForm1.value.resetFormFields(); } @@ -439,7 +634,7 @@ export default defineComponent({ onConfirm, onConfirm2, onUpdateValue, - resetDFrom1, + resetDForm1, dForm1, dForm2, baseSelectOptions, -- Gitee From 874f1e26e21da15d68fdf3fa44aa3977c2c1b2e3 Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sun, 29 Aug 2021 13:21:59 +0800 Subject: [PATCH 13/48] =?UTF-8?q?fix:=20=E5=AE=8C=E6=88=90=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E7=82=B9=EF=BC=9A=20=E6=89=8B=E5=8A=A8=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E5=8F=8D=E9=A6=88=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/src/form-control/form-control.scss | 49 ++++++++++++ devui/form/src/form-control/form-control.tsx | 56 +++++++++++-- sites/components/form/index.md | 78 +++++++++++++------ 3 files changed, 153 insertions(+), 30 deletions(-) diff --git a/devui/form/src/form-control/form-control.scss b/devui/form/src/form-control/form-control.scss index 78cbf5c0..99d0d6b7 100644 --- a/devui/form/src/form-control/form-control.scss +++ b/devui/form/src/form-control/form-control.scss @@ -2,4 +2,53 @@ .star { color: red; } + + .devui-form-control-container { + position: relative; + + .feedback-status { + position: absolute; + top: 50%; + right: 0; + z-index: 1; + width: 32px; + height: 16px; + margin-top: -7px; + line-height: 16px; + text-align: center; + visibility: visible; + pointer-events: none; + } + } + + .has-feedback { + display: flex; + align-items: center; + + input { + padding-right: 28px; + } + } + + .feedback-error { + border: 1px solid #f66f6a; + border-radius: 2px; + + input { + background-color: #ffeeed; + border-color: transparent; + + &:hover { + border-color: transparent !important; + } + + &:focus { + border-color: transparent !important; + } + } + + .devui-select-arrow { + right: 24px !important; + } + } } diff --git a/devui/form/src/form-control/form-control.tsx b/devui/form/src/form-control/form-control.tsx index db5caadc..bf9d6fe4 100644 --- a/devui/form/src/form-control/form-control.tsx +++ b/devui/form/src/form-control/form-control.tsx @@ -1,18 +1,62 @@ -import { defineComponent, inject } from 'vue'; +import { defineComponent, inject, onMounted, nextTick, ref, computed } from 'vue'; import './form-control.scss'; +import Icon from '../../../icon/src/icon' export default defineComponent({ name: 'DFormControl', props: { - + feedbackStatus: { + type: String, + default: '' + }, + extraInfo: { + type: String, + default: '' + }, + suffixTemplate: { + type: String, + default: '' + } }, setup(props, ctx) { - const dForm = inject('dForm', {}); - // console.log('form-control dForm', dForm); + + const formControl = ref(); + + onMounted(() => { + const dom = formControl.value; + console.log('dom', dom); + + }); + + const iconData = computed(() => { + switch(props.feedbackStatus) { + case 'pending': + return {name: 'priority', color: '#e9edfa'}; + case 'success': + return {name: 'right-o', color: 'rgb(61, 204, 166)'}; + case 'error': + return {name: 'error-o', color: 'rgb(249, 95, 91)'}; + default: + return {name: '', color: ''}; + } + }) return () => { - return
- {ctx.slots.default?.()} + const { + feedbackStatus, + } = props; + return
+ +
+ {ctx.slots.default?.()} + { + feedbackStatus && + + } +
+
} } diff --git a/sites/components/form/index.md b/sites/components/form/index.md index 90198624..cedff627 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -366,7 +366,7 @@ Label左右布局方式。 - NickName + Nickname @@ -391,7 +391,7 @@ Label左右布局方式。 - NickName + Nickname @@ -458,13 +458,42 @@ export default defineComponent({ ### 指定表单Feedback状态 -> todo +> doing 你可通过对d-form-control设置feedbackStatus手动指定反馈状态。当前已支持状态:success、error、pending。
- - + + + Name + + + + + + Nickname + + + + + + Age + + + + + + Sex + + + + + + City + + + +
@@ -521,21 +550,17 @@ import DFormItem from '../../../devui/form/src/form-item/form-item'; import DFormControl from '../../../devui/form/src/form-control/form-control'; import DFormOperation from '../../../devui/form/src/form-operation/form-operation'; - -interface IFormModel { - username: string, - password: string, -} - export default defineComponent({ // name: 'DFormDemo', components: {DFormLabel, DFormItem, DFormControl, DFormOperation}, props: { }, setup(props, ctx) { + const dForm1 = ref(null); + const dForm2 = ref(null); + const dForm4 = ref(null); - - let formModel: IFormModel = reactive({ + let formModel = reactive({ name: 'AlanLee', description: '', select: '', @@ -547,25 +572,26 @@ export default defineComponent({ executionDay: true, }); - let formModel2: IFormModel = reactive({ + let formModel2 = reactive({ username: 'haha2' }); - let validateFormModel: IFormModel = reactive({ + let validateFormModel = reactive({ name: 'AlanLee', nickname: 'AlanLee97', age: 24, }); - // console.log('form formModel', formModel); - - const dForm1 = ref(null); - const dForm2 = ref(null); + let formModel4 = reactive({ + name: 'AlanLee', + nickname: 'AlanLee97', + age: 24, + sex: '', + city: '深圳', + }); onMounted(() => { - // console.log('dForm1', dForm1.value); - // console.log('dForm2', dForm2.value); }); @@ -573,7 +599,6 @@ export default defineComponent({ const onInputChange = (e: any) => { console.log('form onInputChange', e); - // text.value = e; } @@ -583,8 +608,6 @@ export default defineComponent({ } - // const username = toRefs(formModel); - const onConfirm = () => { console.log('form md onConfirm', formModel); } @@ -601,6 +624,10 @@ export default defineComponent({ 'Option1','Option2','Option3' ]) + const sexSelectOptions = reactive([ + '男', '女' + ]) + const suggestionList = reactive([ {name: 'Option1'}, {name: 'Option2'}, @@ -630,6 +657,7 @@ export default defineComponent({ return { formModel, formModel2, + formModel4, onInputChange, onConfirm, onConfirm2, @@ -637,7 +665,9 @@ export default defineComponent({ resetDForm1, dForm1, dForm2, + dForm4, baseSelectOptions, + sexSelectOptions, suggestionList, rules, validateFormModel, -- Gitee From d212b86dfd2517d902ab3787b04c1b574c89ebd1 Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sun, 29 Aug 2021 13:39:48 +0800 Subject: [PATCH 14/48] =?UTF-8?q?fix:=20=E5=AE=8C=E6=88=90extraInfo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/src/form-control/form-control.scss | 8 ++++++++ devui/form/src/form-control/form-control.tsx | 3 +++ devui/form/src/form-label/form-label.scss | 3 +++ sites/components/form/index.md | 4 ++-- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/devui/form/src/form-control/form-control.scss b/devui/form/src/form-control/form-control.scss index 99d0d6b7..a21d9d91 100644 --- a/devui/form/src/form-control/form-control.scss +++ b/devui/form/src/form-control/form-control.scss @@ -51,4 +51,12 @@ right: 24px !important; } } + + .devui-form-control-extra-info { + font-size: 12px; + color: #8a8e99; + min-height: 20px; + line-height: 1.5; + text-align: justify; + } } diff --git a/devui/form/src/form-control/form-control.tsx b/devui/form/src/form-control/form-control.tsx index bf9d6fe4..b6aebd43 100644 --- a/devui/form/src/form-control/form-control.tsx +++ b/devui/form/src/form-control/form-control.tsx @@ -44,6 +44,7 @@ export default defineComponent({ return () => { const { feedbackStatus, + extraInfo, } = props; return
@@ -56,6 +57,8 @@ export default defineComponent({ }
+ + {extraInfo &&
{extraInfo}
}
} diff --git a/devui/form/src/form-label/form-label.scss b/devui/form/src/form-label/form-label.scss index f9b26e75..358f522b 100644 --- a/devui/form/src/form-label/form-label.scss +++ b/devui/form/src/form-label/form-label.scss @@ -20,14 +20,17 @@ .form-label_sm { width: 80px; + min-width: 80px; } .form-label_sd { width: 100px; + min-width: 100px; } .form-label_lg { width: 150px; + min-width: 150px; } .form-label_center { diff --git a/sites/components/form/index.md b/sites/components/form/index.md index cedff627..8b4c7b28 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -235,13 +235,13 @@ Label左右布局方式。 用户名 - + 密码 - + -- Gitee From d493b24990f2578db01fc3c1e75b8f1e47615066 Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sun, 29 Aug 2021 13:53:49 +0800 Subject: [PATCH 15/48] =?UTF-8?q?fix:=20=E5=AE=8C=E6=88=90suffixTemplate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/src/form-control/form-control.tsx | 6 +++--- sites/components/form/index.md | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/devui/form/src/form-control/form-control.tsx b/devui/form/src/form-control/form-control.tsx index b6aebd43..ebb7578a 100644 --- a/devui/form/src/form-control/form-control.tsx +++ b/devui/form/src/form-control/form-control.tsx @@ -24,7 +24,6 @@ export default defineComponent({ onMounted(() => { const dom = formControl.value; - console.log('dom', dom); }); @@ -51,9 +50,10 @@ export default defineComponent({
{ctx.slots.default?.()} { - feedbackStatus && + (feedbackStatus || ctx.slots.suffixTemplate?.()) && }
diff --git a/sites/components/form/index.md b/sites/components/form/index.md index 8b4c7b28..6c8a26d3 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -494,6 +494,15 @@ export default defineComponent({ + + City + + + + +
-- Gitee From c431a83b173d88c44bde5c5659b82203f4d72e7d Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sun, 29 Aug 2021 14:42:06 +0800 Subject: [PATCH 16/48] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0hasHelp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/src/form-label/form-label.scss | 26 +++++++++++++ devui/form/src/form-label/form-label.tsx | 7 +++- sites/components/form/index.md | 46 +++++++++++++++++++++-- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/devui/form/src/form-label/form-label.scss b/devui/form/src/form-label/form-label.scss index 358f522b..89fccbe8 100644 --- a/devui/form/src/form-label/form-label.scss +++ b/devui/form/src/form-label/form-label.scss @@ -8,6 +8,9 @@ margin-right: 16px; .devui-required { + display: inline-flex; + align-items: center; + &::before { content: '*'; color: red; @@ -40,3 +43,26 @@ .form-label_end { text-align: end; } + +.form-label-help { + border-radius: 50%; + display: inline-flex; + justify-content: center; + align-items: center; + position: relative; + margin-left: 10px; + + &:hover { + &::after { + position: absolute; + z-index: 100; + min-width: 200px; + content: '提示内容(待替换popover组件)'; + color: #ffffff; + background-color: #e9edfa; + top: -80px; + padding: 10px; + border-radius: 4px; + } + } +} diff --git a/devui/form/src/form-label/form-label.tsx b/devui/form/src/form-label/form-label.tsx index 27203865..62566892 100644 --- a/devui/form/src/form-label/form-label.tsx +++ b/devui/form/src/form-label/form-label.tsx @@ -1,6 +1,7 @@ import { defineComponent, inject, reactive, computed } from 'vue'; import { IForm, formLabelProps, FormLabelProps } from '../form-types'; import './form-label.scss'; +import Icon from '../../../icon/src/icon'; export default defineComponent({ name: 'DFormLabel', @@ -23,7 +24,11 @@ export default defineComponent({ return {ctx.slots.default?.()} - {props.hasHelp && {(props.hasHelp ? props.helpTips : '?')}} + { + props.hasHelp && + + {(props.hasHelp ? : null)} + } } diff --git a/sites/components/form/index.md b/sites/components/form/index.md index 6c8a26d3..9276b6d2 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -234,7 +234,7 @@ Label左右布局方式。
- 用户名 + 用户名 @@ -458,7 +458,7 @@ export default defineComponent({ ### 指定表单Feedback状态 -> doing +> done 你可通过对d-form-control设置feedbackStatus手动指定反馈状态。当前已支持状态:success、error、pending。 @@ -509,7 +509,47 @@ export default defineComponent({ ```html
- + + + Name + + + + + + Nickname + + + + + + Age + + + + + + Sex + + + + + + City + + + + + + City + + + + + +
``` -- Gitee From 6837af7fefeffd713c26c3ee7e39d0b14977b040 Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sun, 29 Aug 2021 23:15:55 +0800 Subject: [PATCH 17/48] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=AD=90?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/index.ts | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/devui/form/index.ts b/devui/form/index.ts index 08c2cdcc..83c59e45 100644 --- a/devui/form/index.ts +++ b/devui/form/index.ts @@ -1,16 +1,40 @@ import type { App } from 'vue' import Form from './src/form' +import FormLabel from './src/form-label/form-label'; +import FormItem from './src/form-item/form-item'; +import FormControl from './src/form-control/form-control'; +import FormOperation from './src/form-operation/form-operation'; Form.install = function(app: App) { app.component(Form.name, Form) } -export { Form } +FormLabel.install = function(app: App) { + app.component(FormLabel.name, FormLabel) +} + +FormItem.install = function(app: App) { + app.component(FormItem.name, FormItem) +} + +FormControl.install = function(app: App) { + app.component(FormControl.name, FormControl) +} + +FormOperation.install = function(app: App) { + app.component(FormOperation.name, FormOperation) +} + +export { Form, FormLabel, FormItem, FormControl, FormOperation } export default { title: 'Form 表单', category: '数据录入', install(app: App): void { - app.use(Form as any) + app.use(Form as any); + app.use(FormLabel as any); + app.use(FormItem as any); + app.use(FormControl as any); + app.use(FormOperation as any); } } -- Gitee From bc6909dafcfcf0ed6e56f3814639b3b8e7ac2031 Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sun, 29 Aug 2021 23:16:49 +0800 Subject: [PATCH 18/48] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/form/src/form-item/form-item.tsx | 6 +++--- devui/form/src/form-types.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/devui/form/src/form-item/form-item.tsx b/devui/form/src/form-item/form-item.tsx index a0efeded..25586a6a 100644 --- a/devui/form/src/form-item/form-item.tsx +++ b/devui/form/src/form-item/form-item.tsx @@ -20,12 +20,12 @@ export default defineComponent({ const formItemMitt = mitt(); const dForm: IForm = reactive(inject('dForm', {} as IForm)); const formData = reactive(dForm.formData); - const initFormTemData = formData[props.prop]; + const initFormItemData = formData[props.prop]; const labelData = reactive(dForm.labelData); const rules = reactive(dForm.rules); const resetField = () => { - formData[props.prop] = initFormTemData; + formData[props.prop] = initFormItemData; } const formItem = reactive({ @@ -123,7 +123,7 @@ export default defineComponent({ showMessage, tipMessage, } = this; - return
+ return
{this.$slots.default?.()}
{showMessage && tipMessage}
diff --git a/devui/form/src/form-types.ts b/devui/form/src/form-types.ts index a07362a1..59deca39 100644 --- a/devui/form/src/form-types.ts +++ b/devui/form/src/form-types.ts @@ -22,8 +22,8 @@ export const formProps = { default: 'start', // 'start' | 'center' | 'end' }, rules: { - type: Array, - default: [], + type: Object, + default: {}, }, } as const -- Gitee From 9ee67eed859bc41f053d05508ece9b8d6a047ef7 Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sun, 29 Aug 2021 23:17:18 +0800 Subject: [PATCH 19/48] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sites/components/form/index.md | 1077 ++++++++++++++++---------------- 1 file changed, 544 insertions(+), 533 deletions(-) diff --git a/sites/components/form/index.md b/sites/components/form/index.md index 9276b6d2..28683979 100644 --- a/sites/components/form/index.md +++ b/sites/components/form/index.md @@ -6,430 +6,496 @@ 需要进行数据收集、数据校验、数据提交功能时。 + + ### 基础用法 > done 基本用法当中,Label是在数据框的上面。 -
- + +:::demo + +```vue + + + + + + + +``` + +::: + + +### 横向排列 + +> done + +Label左右布局方式。 + + +:::demo + +```vue +