干燥机配套车间生产管理系统/云平台服务端
baoshiwei
2024-05-27 fa3ac93010bea3805438ee3ab0a182bfbf7423da
src/views/demo/form/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,621 @@
<template>
   <PageWrapper title="表单基础示例" contentFullHeight>
      <CollapseContainer title="基础示例">
         <BasicForm
            autoFocusFirstItem
            :labelWidth="200"
            :schemas="schemas"
            :actionColOptions="{ span: 24 }"
            :labelCol="{ span: 8 }"
            @submit="handleSubmit"
            @reset="handleReset"
         >
            <template #jAreaLinkage="{ model, field }">
               <JAreaLinkage v-model:value="model[field]" :showArea="true" :showAll="false" />
            </template>
            <template #localSearch="{ model, field }">
               <ApiSelect
                  :api="optionsListApi"
                  showSearch
                  v-model:value="model[field]"
                  optionFilterProp="label"
                  resultField="list"
                  labelField="name"
                  valueField="id"
               />
            </template>
            <template #selectA="{ model, field }">
               <a-select :options="optionsA" mode="multiple" v-model:value="model[field]" @change="valueSelectA = model[field]" allowClear />
            </template>
            <template #selectB="{ model, field }">
               <a-select :options="optionsB" mode="multiple" v-model:value="model[field]" @change="valueSelectB = model[field]" allowClear />
            </template>
            <template #remoteSearch="{ model, field }">
               <ApiSelect
                  :api="optionsListApi"
                  showSearch
                  v-model:value="model[field]"
                  :filterOption="false"
                  resultField="list"
                  labelField="name"
                  valueField="id"
                  @search="onSearch"
               />
            </template>
         </BasicForm>
      </CollapseContainer>
   </PageWrapper>
</template>
<script lang="ts">
   import { computed, defineComponent, unref, ref } from 'vue'
   import { BasicForm, FormSchema, ApiSelect, JAreaLinkage } from '/@/components/Form/index'
   import { CollapseContainer } from '/@/components/Container'
   import { useMessage } from '/@/hooks/web/useMessage'
   import { PageWrapper } from '/@/components/Page'
   import { optionsListApi } from '/@/api/demo/select'
   import { useDebounceFn } from '@vueuse/core'
   import { treeOptionsListApi } from '/@/api/demo/tree'
   import { Select } from 'ant-design-vue'
   import { cloneDeep } from 'lodash-es'
   const valueSelectA = ref<string[]>([])
   const valueSelectB = ref<string[]>([])
   const options = ref<Recordable[]>([])
   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
         return op
      })
   })
   const optionsB = computed(() => {
      return cloneDeep(unref(options)).map((op) => {
         op.disabled = unref(valueSelectA).indexOf(op.value) !== -1
         return op
      })
   })
   const provincesOptions = [
      {
         id: 'guangdong',
         label: '广东省',
         value: '1',
         key: '1',
      },
      {
         id: 'jiangsu',
         label: '江苏省',
         value: '2',
         key: '2',
      },
   ]
   const citiesOptionsData = {
      guangdong: [
         {
            label: '珠海市',
            value: '1',
            key: '1',
         },
         {
            label: '深圳市',
            value: '2',
            key: '2',
         },
         {
            label: '广州市',
            value: '3',
            key: '3',
         },
      ],
      jiangsu: [
         {
            label: '南京市',
            value: '1',
            key: '1',
         },
         {
            label: '无锡市',
            value: '2',
            key: '2',
         },
         {
            label: '苏州市',
            value: '3',
            key: '3',
         },
      ],
   }
   const schemas: FormSchema[] = [
      {
         field: 'divider-basic',
         component: 'Divider',
         label: '基础字段',
      },
      {
         field: 'field1',
         component: 'Input',
         label: '字段1',
         colProps: {
            span: 8,
         },
         // componentProps:{},
         // can func
         componentProps: ({ schema, formModel }) => {
            console.log('form:', schema)
            console.log('formModel:', formModel)
            return {
               placeholder: '自定义placeholder',
               onChange: (e: any) => {
                  console.log(e)
               },
            }
         },
         renderComponentContent: () => {
            return {
               prefix: () => 'pSlot',
               suffix: () => 'sSlot',
            }
         },
      },
      {
         field: 'field2',
         component: 'Input',
         label: '字段2',
         defaultValue: '111',
         colProps: {
            span: 8,
         },
         componentProps: {
            onChange: (e: any) => {
               console.log(e)
            },
         },
         suffix: '天',
      },
      {
         field: 'field3',
         component: 'DatePicker',
         label: '字段3',
         colProps: {
            span: 8,
         },
      },
      {
         field: 'field4',
         component: 'Select',
         label: '字段4',
         colProps: {
            span: 8,
         },
         componentProps: {
            options: [
               {
                  label: '选项1',
                  value: '1',
                  key: '1',
               },
               {
                  label: '选项2',
                  value: '2',
                  key: '2',
               },
            ],
         },
      },
      {
         field: 'field5',
         component: 'CheckboxGroup',
         label: '字段5',
         colProps: {
            span: 8,
         },
         componentProps: {
            options: [
               {
                  label: '选项1',
                  value: '1',
               },
               {
                  label: '选项2',
                  value: '2',
               },
            ],
         },
      },
      {
         field: 'field7',
         component: 'RadioGroup',
         label: '字段7',
         colProps: {
            span: 8,
         },
         componentProps: {
            options: [
               {
                  label: '选项1',
                  value: '1',
               },
               {
                  label: '选项2',
                  value: '2',
               },
            ],
         },
      },
      {
         field: 'field8',
         component: 'Checkbox',
         label: '字段8',
         colProps: {
            span: 8,
         },
         renderComponentContent: 'Check',
      },
      {
         field: 'field9',
         component: 'Switch',
         label: '字段9',
         colProps: {
            span: 8,
         },
      },
      {
         field: 'field10',
         component: 'RadioButtonGroup',
         label: '字段10',
         colProps: {
            span: 8,
         },
         componentProps: {
            options: [
               {
                  label: '选项1',
                  value: '1',
               },
               {
                  label: '选项2',
                  value: '2',
               },
            ],
         },
      },
      {
         field: 'field11',
         component: 'Cascader',
         label: '字段11',
         colProps: {
            span: 8,
         },
         componentProps: {
            options: [
               {
                  value: 'zhejiang',
                  label: 'Zhejiang',
                  children: [
                     {
                        value: 'hangzhou',
                        label: 'Hangzhou',
                        children: [
                           {
                              value: 'xihu',
                              label: 'West Lake',
                           },
                        ],
                     },
                  ],
               },
               {
                  value: 'jiangsu',
                  label: 'Jiangsu',
                  children: [
                     {
                        value: 'nanjing',
                        label: 'Nanjing',
                        children: [
                           {
                              value: 'zhonghuamen',
                              label: 'Zhong Hua Men',
                           },
                        ],
                     },
                  ],
               },
            ],
         },
      },
      {
         field: 'divider-api-select',
         component: 'Divider',
         label: '远程下拉演示',
      },
      {
         field: 'field30',
         component: 'ApiSelect',
         label: '懒加载远程下拉',
         required: true,
         componentProps: {
            // more details see /src/components/Form/src/components/ApiSelect.vue
            api: optionsListApi,
            params: {
               id: 1,
            },
            resultField: 'list',
            // use name as label
            labelField: 'name',
            // use id as value
            valueField: 'id',
            // not request untill to select
            immediate: false,
            onChange: (e) => {
               console.log('selected:', e)
            },
            // atfer request callback
            onOptionsChange: (options) => {
               console.log('get options', options.length, options)
            },
         },
         colProps: {
            span: 8,
         },
         defaultValue: '0',
      },
      {
         field: 'field311',
         component: 'JAreaLinkage',
         label: '省市区选择',
         helpMessage: ['JAreaLinkage组件', '省市区选择'],
         required: true,
         slot: 'jAreaLinkage',
         colProps: {
            span: 8,
         },
         defaultValue: ['130000', '130200'],
      },
      {
         field: 'field31',
         component: 'Input',
         label: '下拉本地搜索',
         helpMessage: ['ApiSelect组件', '远程数据源本地搜索', '只发起一次请求获取所有选项'],
         required: true,
         slot: 'localSearch',
         colProps: {
            span: 8,
         },
         defaultValue: '0',
      },
      {
         field: 'field32',
         component: 'Input',
         label: '下拉远程搜索',
         helpMessage: ['ApiSelect组件', '将关键词发送到接口进行远程搜索'],
         required: true,
         slot: 'remoteSearch',
         colProps: {
            span: 8,
         },
         defaultValue: '0',
      },
      {
         field: 'field33',
         component: 'ApiTreeSelect',
         label: '远程下拉树',
         helpMessage: ['ApiTreeSelect组件', '使用接口提供的数据生成选项'],
         required: true,
         componentProps: {
            api: treeOptionsListApi,
            resultField: 'list',
         },
         colProps: {
            span: 8,
         },
      },
      {
         field: 'field34',
         component: 'ApiRadioGroup',
         label: '远程Radio',
         helpMessage: ['ApiRadioGroup组件', '使用接口提供的数据生成选项'],
         required: true,
         componentProps: {
            api: optionsListApi,
            params: {
               count: 2,
            },
            resultField: 'list',
            // use name as label
            labelField: 'name',
            // use id as value
            valueField: 'id',
         },
         defaultValue: '1',
         colProps: {
            span: 8,
         },
      },
      {
         field: 'field35',
         component: 'ApiRadioGroup',
         label: '远程Radio',
         helpMessage: ['ApiRadioGroup组件', '使用接口提供的数据生成选项'],
         required: true,
         componentProps: {
            api: optionsListApi,
            params: {
               count: 2,
            },
            resultField: 'list',
            // use name as label
            labelField: 'name',
            // use id as value
            valueField: 'id',
            isBtn: true,
         },
         colProps: {
            span: 8,
         },
      },
      {
         field: 'divider-linked',
         component: 'Divider',
         label: '字段联动',
      },
      {
         field: 'province',
         component: 'Select',
         label: '省份',
         colProps: {
            span: 8,
         },
         componentProps: ({ formModel, formActionType }) => {
            return {
               options: provincesOptions,
               placeholder: '省份与城市联动',
               onChange: (e: any) => {
                  // console.log(e)
                  let citiesOptions = e == 1 ? citiesOptionsData[provincesOptions[0].id] : citiesOptionsData[provincesOptions[1].id]
                  // console.log(citiesOptions)
                  if (e === undefined) {
                     citiesOptions = []
                  }
                  formModel.city = undefined //  reset city value
                  const { updateSchema } = formActionType
                  updateSchema({
                     field: 'city',
                     componentProps: {
                        options: citiesOptions,
                     },
                  })
               },
            }
         },
      },
      {
         field: 'city',
         component: 'Select',
         label: '城市',
         colProps: {
            span: 8,
         },
         componentProps: {
            options: [], // defalut []
            placeholder: '省份与城市联动',
         },
      },
      {
         field: 'divider-selects',
         component: 'Divider',
         label: '互斥多选',
         helpMessage: ['两个Select共用数据源', '但不可选择对方已选中的项目'],
      },
      {
         field: 'selectA',
         component: 'Select',
         label: '互斥SelectA',
         slot: 'selectA',
         defaultValue: [],
         colProps: {
            span: 8,
         },
      },
      {
         field: 'selectB',
         component: 'Select',
         label: '互斥SelectB',
         slot: 'selectB',
         defaultValue: [],
         colProps: {
            span: 8,
         },
      },
      {
         field: 'divider-others',
         component: 'Divider',
         label: '其它',
      },
      {
         field: 'field20',
         component: 'InputNumber',
         label: '字段20',
         required: true,
         colProps: {
            span: 8,
         },
      },
      {
         field: 'field21',
         component: 'Slider',
         label: '字段21',
         componentProps: {
            min: 0,
            max: 100,
            range: true,
            marks: {
               20: '20°C',
               60: '60°C',
            },
         },
         colProps: {
            span: 8,
         },
      },
      {
         field: 'field22',
         component: 'Rate',
         label: '字段22',
         defaultValue: 3,
         colProps: {
            span: 8,
         },
         componentProps: {
            disabled: false,
            allowHalf: true,
         },
      },
   ]
   export default defineComponent({
      components: {
         BasicForm,
         CollapseContainer,
         PageWrapper,
         ApiSelect,
         JAreaLinkage,
         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
         }
         function areaChange(value) {
            alert(value)
         }
         return {
            schemas,
            optionsListApi,
            optionsA,
            optionsB,
            valueSelectA,
            valueSelectB,
            onSearch: useDebounceFn(onSearch, 300),
            searchParams,
            handleReset: () => {
               keyword.value = ''
            },
            handleSubmit: (values: any) => {
               createMessage.success('click search,values:' + JSON.stringify(values))
            },
            check,
         }
      },
   })
</script>