From 2069d53e9be24adec3c8d6717fd7317555bd9a52 Mon Sep 17 00:00:00 2001 From: Ben Lin <maobin001@msn.com> Date: 星期二, 02 七月 2024 23:02:51 +0800 Subject: [PATCH] 高级表单优化 --- src/views/demo/form/index.vue | 286 ++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 204 insertions(+), 82 deletions(-) diff --git a/src/views/demo/form/index.vue b/src/views/demo/form/index.vue index de2af82..9300af0 100644 --- a/src/views/demo/form/index.vue +++ b/src/views/demo/form/index.vue @@ -10,7 +10,7 @@ @reset="handleReset" > <template #selectA="{ model, field }"> - <a-select + <Select :options="optionsA" mode="multiple" v-model:value="model[field]" @@ -19,7 +19,7 @@ /> </template> <template #selectB="{ model, field }"> - <a-select + <Select :options="optionsB" mode="multiple" v-model:value="model[field]" @@ -48,42 +48,44 @@ labelField="name" valueField="id" :params="searchParams" - @search="onSearch" + @search="debounceOptionsFn" /> </template> </BasicForm> </CollapseContainer> </PageWrapper> </template> -<script lang="ts"> - import { computed, defineComponent, unref, ref } from 'vue'; - import { BasicForm, FormSchema, ApiSelect } from '/@/components/Form/index'; - import { CollapseContainer } from '/@/components/Container'; - import { useMessage } from '/@/hooks/web/useMessage'; - import { PageWrapper } from '/@/components/Page'; +<script lang="ts" setup> + import { type Recordable } from '@vben/types'; + import { computed, unref, ref } from 'vue'; + import { BasicForm, ApiSelect, FormSchema } from '@/components/Form'; + import { CollapseContainer } from '@/components/Container'; + import { useMessage } from '@/hooks/web/useMessage'; + import { PageWrapper } from '@/components/Page'; - import { optionsListApi } from '/@/api/demo/select'; + import { optionsListApi } from '@/api/demo/select'; import { useDebounceFn } from '@vueuse/core'; - import { treeOptionsListApi } from '/@/api/demo/tree'; - import { Select } from 'ant-design-vue'; + import { treeOptionsListApi } from '@/api/demo/tree'; + import { Select, type SelectProps } from 'ant-design-vue'; import { cloneDeep } from 'lodash-es'; - import { areaRecord } from '/@/api/demo/cascader'; - import { uploadApi } from '/@/api/sys/upload'; + import { areaRecord } from '@/api/demo/cascader'; + import { uploadApi } from '@/api/sys/upload'; + let debounceOptionsFn = useDebounceFn(onSearch, 300); const valueSelectA = ref<string[]>([]); const valueSelectB = ref<string[]>([]); - const options = ref<Recordable[]>([]); + const options = ref<Required<SelectProps>['options']>([]); for (let i = 1; i < 10; i++) options.value.push({ label: '閫夐」' + i, value: `${i}` }); const optionsA = computed(() => { return cloneDeep(unref(options)).map((op) => { - op.disabled = unref(valueSelectB).indexOf(op.value) !== -1; + op.disabled = unref(valueSelectB).indexOf(op.value as string) !== -1; return op; }); }); const optionsB = computed(() => { return cloneDeep(unref(options)).map((op) => { - op.disabled = unref(valueSelectA).indexOf(op.value) !== -1; + op.disabled = unref(valueSelectA).indexOf(op.value as string) !== -1; return op; }); }); @@ -151,12 +153,13 @@ { field: 'field1', component: 'Input', - label: '瀛楁1', + label: ({ model }) => { + return `瀛楁1${model.field3 ? model.field3 : ''}`; + }, colProps: { span: 8, }, - // componentProps:{}, // can func componentProps: ({ schema, formModel }) => { console.log('form:', schema); @@ -307,8 +310,8 @@ value: '2', }, ], - onChange: (e, v) => { - console.log('RadioButtonGroup====>:', e, v); + onChange: (e) => { + console.log(e); }, }, }, @@ -354,6 +357,39 @@ ], }, ], + }, + }, + { + field: 'field12', + component: 'BasicTitle', + label: '鏍囬鍖哄垎', + componentProps: { + // line: true, + span: true, + }, + colProps: { + span: 24, + }, + }, + { + field: 'field13', + component: 'CropperAvatar', + label: '澶村儚涓婁紶', + colProps: { + span: 8, + }, + }, + { + field: 'field14', + component: 'Transfer', + label: '绌挎妗�', + colProps: { + span: 8, + }, + componentProps: { + render: (item) => item.label, + dataSource: citiesOptionsData.guangdong, + targetKeys: ['1'], }, }, { @@ -407,7 +443,7 @@ componentProps: { api: areaRecord, apiParamKey: 'parentCode', - dataField: 'data', + // dataField: 'data', labelField: 'name', valueField: 'code', initFetchParams: { @@ -423,7 +459,6 @@ }, { field: 'field31', - component: 'Input', label: '涓嬫媺鏈湴鎼滅储', helpMessage: ['ApiSelect缁勪欢', '杩滅▼鏁版嵁婧愭湰鍦版悳绱�', '鍙彂璧蜂竴娆¤姹傝幏鍙栨墍鏈夐�夐」'], required: true, @@ -432,10 +467,12 @@ span: 8, }, defaultValue: '0', + componentProps: { + onOptionsChange() {}, + }, }, { field: 'field32', - component: 'Input', label: '涓嬫媺杩滅▼鎼滅储', helpMessage: ['ApiSelect缁勪欢', '灏嗗叧閿瘝鍙戦�佸埌鎺ュ彛杩涜杩滅▼鎼滅储'], required: true, @@ -456,6 +493,49 @@ resultField: 'list', onChange: (e, v) => { console.log('ApiTreeSelect====>:', e, v); + }, + }, + colProps: { + span: 8, + }, + }, + { + field: 'field33', + component: 'ApiTreeSelect', + label: '杩滅▼鎳掑姞杞戒笅鎷夋爲', + helpMessage: ['ApiTreeSelect缁勪欢', '浣跨敤鎺ュ彛鎻愪緵鐨勬暟鎹敓鎴愰�夐」'], + required: true, + componentProps: { + api: () => { + return new Promise((resolve) => { + resolve([ + { + title: 'Parent Node', + value: '0-0', + }, + ]); + }); + }, + async: true, + onChange: (e, v) => { + console.log('ApiTreeSelect====>:', e, v); + }, + onLoadData: ({ treeData, resolve, treeNode }) => { + console.log('treeNode====>:', treeNode); + setTimeout(() => { + const children: Recordable[] = [ + { title: `Child Node ${treeNode.eventKey}-0`, value: `${treeNode.eventKey}-0` }, + { title: `Child Node ${treeNode.eventKey}-1`, value: `${treeNode.eventKey}-1` }, + ]; + children.forEach((item) => { + item.isLeaf = false; + item.children = []; + }); + treeNode.dataRef.children = children; + treeData.value = [...treeData.value]; + resolve(); + return; + }, 300); }, }, colProps: { @@ -501,35 +581,48 @@ // use id as value valueField: 'id', isBtn: true, - onChange: (e, v) => { - console.log('ApiRadioGroup====>:', e, v); + onChange: (e) => { + console.log('ApiRadioGroup====>:', e); }, }, colProps: { span: 8, }, }, - // { - // field: 'field36', - // component: 'ApiTree', - // label: '杩滅▼Tree', - // helpMessage: ['ApiTree缁勪欢', '浣跨敤鎺ュ彛鎻愪緵鐨勬暟鎹敓鎴愰�夐」'], - // required: true, - // componentProps: { - // api: treeOptionsListApi, - // params: { - // count: 2, - // }, - // afterFetch: (v) => { - // //do something - // return v; - // }, - // resultField: 'list', - // }, - // colProps: { - // span: 8, - // }, - // }, + { + field: 'field36', + component: 'ApiTree', + label: '杩滅▼Tree', + helpMessage: ['ApiTree缁勪欢', '浣跨敤鎺ュ彛鎻愪緵鐨勬暟鎹敓鎴愰�夐」'], + required: true, + componentProps: { + api: treeOptionsListApi, + params: { + count: 2, + }, + afterFetch: (v) => { + //do something + return v; + }, + resultField: 'list', + }, + colProps: { + span: 8, + }, + }, + { + label: '杩滅▼绌挎妗�', + field: 'field37', + component: 'ApiTransfer', + componentProps: { + render: (item) => item.label, + api: async () => { + return Promise.resolve(citiesOptionsData.guangdong); + }, + }, + defaultValue: ['1'], + required: true, + }, { field: 'divider-linked', component: 'Divider', @@ -594,7 +687,6 @@ }, { field: 'selectA', - component: 'Select', label: '浜掓枼SelectA', slot: 'selectA', defaultValue: [], @@ -604,7 +696,6 @@ }, { field: 'selectB', - component: 'Select', label: '浜掓枼SelectB', slot: 'selectB', defaultValue: [], @@ -624,10 +715,28 @@ { field: '[startTime, endTime]', label: '鏃堕棿鑼冨洿', + component: 'TimeRangePicker', + componentProps: { + format: 'HH:mm:ss', + placeholder: ['寮�濮嬫椂闂�', '缁撴潫鏃堕棿'], + }, + }, + { + field: '[startDate, endDate]', + label: '鏃ユ湡鑼冨洿', + component: 'RangePicker', + componentProps: { + format: 'YYYY-MM-DD', + placeholder: ['寮�濮嬫棩鏈�', '缁撴潫鏃ユ湡'], + }, + }, + { + field: '[startDateTime, endDateTime]', + label: '鏃ユ湡鏃堕棿鑼冨洿', component: 'RangePicker', componentProps: { format: 'YYYY-MM-DD HH:mm:ss', - placeholder: ['寮�濮嬫椂闂�', '缁撴潫鏃堕棿'], + placeholder: ['寮�濮嬫棩鏈熴�佹椂闂�', '缁撴潫鏃ユ湡銆佹椂闂�'], showTime: { format: 'HH:mm:ss' }, }, }, @@ -678,39 +787,52 @@ allowHalf: true, }, }, + { + field: 'field23', + component: 'ImageUpload', + label: '涓婁紶鍥剧墖', + required: true, + defaultValue: [ + 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', + ], + componentProps: { + api: uploadApi, + accept: ['png', 'jpeg', 'jpg'], + maxSize: 2, + maxNumber: 1, + }, + // rules: [ + // { + // required: true, + // trigger: 'change', + // validator(_, value) { + // if (isArray(value) && value.length > 0) { + // return Promise.resolve(); + // } else { + // return Promise.reject('璇烽�夋嫨涓婁紶鍥剧墖'); + // } + // }, + // }, + // ], + }, ]; - export default defineComponent({ - components: { BasicForm, CollapseContainer, PageWrapper, ApiSelect, ASelect: Select }, - setup() { - const check = ref(null); - const { createMessage } = useMessage(); - const keyword = ref<string>(''); - const searchParams = computed<Recordable>(() => { - return { keyword: unref(keyword) }; - }); - - function onSearch(value: string) { - keyword.value = value; - } - return { - schemas, - optionsListApi, - optionsA, - optionsB, - valueSelectA, - valueSelectB, - onSearch: useDebounceFn(onSearch, 300), - searchParams, - handleReset: () => { - keyword.value = ''; - }, - handleSubmit: (values: any) => { - console.log('values', values); - createMessage.success('click search,values:' + JSON.stringify(values)); - }, - check, - }; - }, + const { createMessage } = useMessage(); + const keyword = ref<string>(''); + const searchParams = computed<Recordable<string>>(() => { + return { keyword: unref(keyword) }; }); + + function onSearch(value: string) { + keyword.value = value; + } + + function handleReset() { + keyword.value = ''; + } + + function handleSubmit(values: any) { + console.log('values', values); + createMessage.success('click search,values:' + JSON.stringify(values)); + } </script> -- Gitblit v1.9.3