Skip to content

通用表单

基础表单

<template>
  <div class="common-form-container">
    <ca-common-form ref="formRef" v-bind="form" />
  </div>
</template>

<script lang="ts" setup>
import { computed, reactive } from 'vue'
import { CommonForm, FormField } from '#/castor-antdv'

const optionsMap = reactive({
  sex: [
    {
      value: 1,
      label: ''
    },
    {
      value: 2,
      label: ''
    }
  ],
  equipment: [
    {
      value: 'double',
      label: '双压记录仪',
      disabled: false
    },
    {
      value: 'remote',
      label: '压力远传处理仪',
      disabled: false
    }
  ]
})

const fields = computed<Array<FormField>>(() => {
  return [
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '1、基本信息',
        groupCommands: [
          {
            text: '取消关注',
            command: 'handleUnStar'
          },
          {
            text: '关注',
            command: 'handleStar'
          }
        ],
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'text',
      label: '编号',
      dataField: 'code',
      columnSpan: 1
    },
    {
      type: 'default',
      label: '姓名',
      dataField: 'name',
      columnSpan: 1
    },
    {
      type: 'select',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    },
    {
      type: 'inputNumber',
      label: '年龄',
      dataField: 'age',
      columnSpan: 1
    },
    {
      type: 'date',
      label: '年份',
      dataField: 'userYear',
      columnSpan: 1,
      elementProps: {
        picker: 'year',
        valueFormat: 'YYYY'
      }
    },
    {
      type: 'date',
      label: '月份',
      dataField: 'userMonth',
      columnSpan: 1,
      elementProps: {
        picker: 'month',
        valueFormat: 'YYYY-MM'
      }
    },
    {
      type: 'date',
      label: '日期',
      dataField: 'userDate',
      columnSpan: 1,
      elementProps: {
        picker: 'date',
        valueFormat: 'YYYY-MM-DD'
      }
    },
    {
      type: 'switch',
      label: '是否启用',
      dataField: 'userEnabled',
      columnSpan: 1
    },
    {
      type: 'textArea',
      label: '地址',
      dataField: 'address',
      columnSpan: 2
    },
    {
      type: 'image',
      label: '头像',
      dataField: 'avatar',
      columnSpan: 2,
      elementProps: {
        imageOptions: {
          width: '100px',
          height: '100px',
          style: {
            border: '1px solid #ccc'
          }
        }
      }
    },
    {
      type: 'space',
      label: '',
      dataField: '',
      columnSpan: 2
    },
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '2、其它信息',
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'checkboxGroup',
      label: '主打产品',
      dataField: 'equipment',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['equipment']
      }
    },
    {
      type: 'radioGroup',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    }
  ]
})

const handleStar = () => {
  console.log('handleStar', form.model)
}

const handleUnStar = () => {
  console.log('handleUnStar', form.model)
}

const handleSave = ({ command }) => {
  console.log('handleSave', form.model)
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const handleCancel = ({ command }) => {
  console.log('handleCancel')
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const form = reactive<CommonForm>({
  loading: false,
  operateType: 'add',
  model: {
    code: '1001',
    name: '张三',
    sex: null,
    age: 18,
    userYear: '',
    userMonth: '',
    userDate: '',
    userEnabled: true,
    address: '长江路555号',
    equipment: [],
    avatar: 'https://q2.itc.cn/q_70/images03/20241013/47ff05019e93455abd85cd47612fbf7b.jpeg'
  },
  fields,
  commands: [
    {
      text: '取消',
      command: 'handleCancel'
    },
    {
      text: '确定',
      command: 'handleSave',
      loading: false,
      elementProps: {
        type: 'primary',
        style: {
          fontWeight: 'bold'
        }
      }
    }
  ],
  elementProps: {
    labelCol: { style: { width: '80px' } },
    wrapperCol: { style: { flex: 1 } },
    style: {
      // margin: '0 12px 12px 12px',
      'margin-bottom': '12px'
    }
  },
  extendProps: {
    contentStyle: { overflow: 'auto', flex: 1, marginTop: '12px' }
  },
  emitRegister: {
    handleStar,
    handleUnStar,
    handleSave,
    handleCancel
  }
})
</script>

<style lang="scss" scoped>
.common-form-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}
</style>

表单校验

<template>
  <div class="common-form-container">
    <ca-common-form v-bind="form" />
  </div>
</template>

<script lang="ts" setup>
import { message } from 'ant-design-vue'
import { Rule } from 'ant-design-vue/es/form/interface'
import { computed, reactive } from 'vue'
import { CommonForm, FormField } from '#/castor-antdv'

const optionsMap = reactive({
  sex: [
    {
      value: 1,
      label: ''
    },
    {
      value: 2,
      label: ''
    }
  ],
  equipment: [
    {
      value: 'double',
      label: '双压记录仪',
      disabled: false
    },
    {
      value: 'remote',
      label: '压力远传处理仪',
      disabled: false
    }
  ]
})

const fields = computed<Array<FormField>>(() => {
  return [
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '1、基本信息',
        groupCommands: [
          {
            text: '取消关注',
            command: 'handleUnStar'
          },
          {
            text: '关注',
            command: 'handleStar'
          }
        ],
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'text',
      label: '编号',
      dataField: 'code',
      columnSpan: 1
    },
    {
      type: 'default',
      label: '姓名',
      dataField: 'name',
      columnSpan: 1
    },
    {
      type: 'select',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex'],
        allowClear: true
      }
    },
    {
      type: 'inputNumber',
      label: '年龄',
      dataField: 'age',
      columnSpan: 1
    },
    {
      type: 'date',
      label: '年份',
      dataField: 'userYear',
      columnSpan: 1,
      elementProps: {
        picker: 'year',
        valueFormat: 'YYYY'
      }
    },
    {
      type: 'date',
      label: '月份',
      dataField: 'userMonth',
      columnSpan: 1,
      elementProps: {
        picker: 'month',
        valueFormat: 'YYYY-MM'
      }
    },
    {
      type: 'date',
      label: '日期',
      dataField: 'userDate',
      columnSpan: 1,
      elementProps: {
        picker: 'date',
        valueFormat: 'YYYY-MM-DD'
      }
    },
    {
      type: 'textArea',
      label: '地址',
      dataField: 'address',
      columnSpan: 2
    },
    {
      type: 'space',
      label: '',
      dataField: '',
      columnSpan: 2
    },
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '2、其它信息',
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'checkboxGroup',
      label: '主打产品',
      dataField: 'equipment',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['equipment']
      }
    },
    {
      type: 'radioGroup',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    }
  ]
})

const handleStar = () => {
  console.log('handleStar', form.model)
}

const handleUnStar = () => {
  console.log('handleUnStar', form.model)
}

const handleSave = async ({ command }) => {
  console.log('handleSave', form.model, form.emitRegister)
  command.loading = true
  try {
    await form.emitRegister?.validate?.()
    message.success('保存成功')
  } finally {
    setTimeout(() => (command.loading = false), 2000)
  }
}

const handleCancel = ({ command }) => {
  console.log('handleCancel')
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const rules: Record<string, Rule[]> = {
  name: [{ required: true, message: '不能为空', trigger: 'blur' }],
  sex: [{ required: true, message: '不能为空' }]
}

const form = reactive<CommonForm>({
  loading: false,
  operateType: 'add',
  model: {
    code: '1001',
    name: '',
    sex: null,
    age: 18,
    userYear: '',
    userMonth: '',
    userDate: '',
    address: '长江路555号',
    equipment: []
  },
  fields,
  commands: [
    {
      text: '取消',
      command: 'handleCancel'
    },
    {
      text: '确定',
      command: 'handleSave',
      loading: false,
      elementProps: {
        type: 'primary'
      }
    }
  ],
  elementProps: {
    rules,
    labelCol: { style: { width: '80px' } },
    wrapperCol: { style: { flex: 1 } },
    scrollToFirstError: true,
    style: {}
  },
  extendProps: {
    contentStyle: { overflow: 'auto', flex: 1, marginTop: '12px' }
  },
  emitRegister: {
    handleStar,
    handleUnStar,
    handleSave,
    handleCancel
  }
})
</script>
<style lang="scss" scoped>
.common-form-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}
</style>

单项校验

<template>
  <div class="common-form-container">
    <ca-common-form v-bind="form" />
  </div>
</template>

<script lang="ts" setup>
import { message } from 'ant-design-vue'
import { computed, reactive } from 'vue'
import { CommonForm, FormField } from '#/castor-antdv'

const optionsMap = reactive({
  sex: [
    {
      value: 1,
      label: ''
    },
    {
      value: 2,
      label: ''
    }
  ],
  equipment: [
    {
      value: 'double',
      label: '双压记录仪',
      disabled: false
    },
    {
      value: 'remote',
      label: '压力远传处理仪',
      disabled: false
    }
  ]
})

const fields = computed<Array<FormField>>(() => {
  return [
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '1、基本信息',
        groupCommands: [
          {
            text: '取消关注',
            command: 'handleUnStar'
          },
          {
            text: '关注',
            command: 'handleStar'
          }
        ],
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'text',
      label: '编号',
      dataField: 'code',
      columnSpan: 1
    },
    {
      type: 'default',
      label: '姓名',
      dataField: 'name',
      columnSpan: 1,
      rules: [{ required: true, message: '不能为空', trigger: 'blur' }]
    },
    {
      type: 'select',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      rules: [{ required: true, trigger: 'change', message: '不能为空' }],
      elementProps: {
        options: optionsMap['sex'],
        allowClear: true
      }
    },
    {
      type: 'inputNumber',
      label: '年龄',
      dataField: 'age',
      columnSpan: 1
    },
    {
      type: 'date',
      label: '年份',
      dataField: 'userYear',
      columnSpan: 1,
      elementProps: {
        picker: 'year',
        valueFormat: 'YYYY'
      }
    },
    {
      type: 'date',
      label: '月份',
      dataField: 'userMonth',
      columnSpan: 1,
      elementProps: {
        picker: 'month',
        valueFormat: 'YYYY-MM'
      }
    },
    {
      type: 'date',
      label: '日期',
      dataField: 'userDate',
      columnSpan: 1,
      elementProps: {
        picker: 'date',
        valueFormat: 'YYYY-MM-DD'
      }
    },
    {
      type: 'textArea',
      label: '地址',
      dataField: 'address',
      columnSpan: 2
    },
    {
      type: 'space',
      label: '',
      dataField: '',
      columnSpan: 2
    },
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '2、其它信息',
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'checkboxGroup',
      label: '主打产品',
      dataField: 'equipment',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['equipment']
      }
    },
    {
      type: 'radioGroup',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    }
  ]
})

const handleStar = () => {
  console.log('handleStar', form.model)
}

const handleUnStar = () => {
  console.log('handleUnStar', form.model)
}

const handleSave = async ({ command }) => {
  console.log('handleSave', form.model, form.emitRegister)
  command.loading = true
  try {
    await form.emitRegister?.validate?.()
    message.success('保存成功')
  } finally {
    setTimeout(() => (command.loading = false), 2000)
  }
}

const handleCancel = ({ command }) => {
  console.log('handleCancel')
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const form = reactive<CommonForm>({
  loading: false,
  operateType: 'add',
  model: {
    code: '1001',
    name: '',
    sex: null,
    age: 18,
    userYear: '',
    userMonth: '',
    userDate: '',
    address: '长江路555号',
    equipment: []
  },
  fields,
  commands: [
    {
      text: '取消',
      command: 'handleCancel'
    },
    {
      text: '确定',
      command: 'handleSave',
      loading: false,
      elementProps: {
        type: 'primary'
      }
    }
  ],
  elementProps: {
    labelCol: { style: { width: '80px' } },
    wrapperCol: { style: { flex: 1 } },
    style: {}
  },
  extendProps: {
    contentStyle: { overflow: 'auto', flex: 1, marginTop: '12px' }
  },
  emitRegister: {
    handleStar,
    handleUnStar,
    handleSave,
    handleCancel
  }
})
</script>
<style lang="scss" scoped>
.common-form-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}
</style>

自定义组件

<template>
  <div class="common-form-container">
    <ca-common-form ref="formRef" v-bind="form" />
  </div>
</template>

<script lang="ts" setup>
import { computed, reactive, shallowRef } from 'vue'
import { CommonForm, FormField } from '#/castor-antdv'
import CustomTable from './components/CustomTable.vue'

const optionsMap = reactive({
  sex: [
    {
      value: 1,
      label: ''
    },
    {
      value: 2,
      label: ''
    }
  ],
  equipment: [
    {
      value: 'double',
      label: '双压记录仪',
      disabled: false
    },
    {
      value: 'remote',
      label: '压力远传处理仪',
      disabled: false
    }
  ]
})

const fields = computed<Array<FormField>>(() => {
  return [
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '1、基本信息',
        groupCommands: [
          {
            text: '取消关注',
            command: 'handleUnStar'
          },
          {
            text: '关注',
            command: 'handleStar'
          }
        ],
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'text',
      label: '编号',
      dataField: 'code',
      columnSpan: 1
    },
    {
      type: 'default',
      label: '姓名',
      dataField: 'name',
      columnSpan: 1
    },
    {
      type: 'select',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    },
    {
      type: 'inputNumber',
      label: '年龄',
      dataField: 'age',
      columnSpan: 1
    },
    {
      type: 'date',
      label: '年份',
      dataField: 'userYear',
      columnSpan: 1,
      elementProps: {
        picker: 'year',
        valueFormat: 'YYYY'
      }
    },
    {
      type: 'date',
      label: '月份',
      dataField: 'userMonth',
      columnSpan: 1,
      elementProps: {
        picker: 'month',
        valueFormat: 'YYYY-MM'
      }
    },
    {
      type: 'date',
      label: '日期',
      dataField: 'userDate',
      columnSpan: 1,
      elementProps: {
        picker: 'date',
        valueFormat: 'YYYY-MM-DD'
      }
    },
    {
      type: 'checkboxGroup',
      label: '主打产品',
      dataField: 'equipment',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['equipment']
      }
    },
    {
      type: 'radioGroup',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    },
    {
      type: 'space',
      label: '',
      dataField: '',
      columnSpan: 2
    },
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '2、用户信息',
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'custom',
      label: '',
      dataField: 'users',
      columnSpan: 2,
      extendProps: {
        componentKey: 'customTable',
        formItemStyle: {
          marginBottom: '12px'
        }
      }
    },
    {
      type: 'space',
      label: '',
      dataField: '',
      columnSpan: 2
    },
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '3、其它信息',
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'textArea',
      label: '地址',
      dataField: 'address',
      columnSpan: 2
    }
  ]
})

const handleStar = () => {
  console.log('handleStar', form.model)
}

const handleUnStar = () => {
  console.log('handleUnStar', form.model)
}

const handleSave = ({ command }) => {
  console.log('handleSave', form.model)
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const handleCancel = ({ command }) => {
  console.log('handleCancel')
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const form = reactive<CommonForm>({
  loading: false,
  operateType: 'add',
  model: {
    code: '1001',
    name: '张三',
    sex: null,
    age: 18,
    userYear: '',
    userMonth: '',
    userDate: '',
    address: '长江路555号',
    equipment: [],
    users: []
  },
  fields,
  commands: [
    {
      text: '取消',
      command: 'handleCancel'
    },
    {
      text: '确定',
      command: 'handleSave',
      loading: false,
      elementProps: {
        type: 'primary'
      }
    }
  ],
  customComponents: {
    customTable: shallowRef(CustomTable)
  },
  elementProps: {
    labelCol: { style: { width: '80px' } },
    wrapperCol: { style: { flex: 1 } },
    style: {}
  },
  extendProps: {
    contentStyle: { overflow: 'auto', flex: 1, marginTop: '12px' }
  },
  emitRegister: {
    handleStar,
    handleUnStar,
    handleSave,
    handleCancel
  }
})
</script>
<style lang="scss" scoped>
.common-form-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}
</style>

底部状态

<template>
  <div class="common-form-container">
    <ca-common-form ref="formRef" v-bind="form" />
  </div>
</template>

<script lang="ts" setup>
import { computed, reactive } from 'vue'
import { CommonForm, FormField } from '#/castor-antdv'

const optionsMap = reactive({
  sex: [
    {
      value: 1,
      label: ''
    },
    {
      value: 2,
      label: ''
    }
  ],
  equipment: [
    {
      value: 'double',
      label: '双压记录仪',
      disabled: false
    },
    {
      value: 'remote',
      label: '压力远传处理仪',
      disabled: false
    }
  ],
  status: [
    {
      value: 4,
      label: '未开始',
      color: '#4a90e2'
    },
    {
      value: 1,
      label: '进行中',
      color: '#f5a623'
    },
    {
      value: 2,
      label: '已驳回',
      color: '#d0021b'
    },
    {
      value: 3,
      label: '已完成',
      color: '#3d1ab7'
    }
  ]
})

const fields = computed<Array<FormField>>(() => {
  return [
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '1、基本信息',
        groupCommands: [
          {
            text: '取消关注',
            command: 'handleUnStar'
          },
          {
            text: '关注',
            command: 'handleStar'
          }
        ],
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'text',
      label: '编号',
      dataField: 'code',
      columnSpan: 1
    },
    {
      type: 'default',
      label: '姓名',
      dataField: 'name',
      columnSpan: 1
    },
    {
      type: 'select',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    },
    {
      type: 'inputNumber',
      label: '年龄',
      dataField: 'age',
      columnSpan: 1
    },
    {
      type: 'date',
      label: '年份',
      dataField: 'userYear',
      columnSpan: 1,
      elementProps: {
        picker: 'year',
        valueFormat: 'YYYY'
      }
    },
    {
      type: 'date',
      label: '月份',
      dataField: 'userMonth',
      columnSpan: 1,
      elementProps: {
        picker: 'month',
        valueFormat: 'YYYY-MM'
      }
    },
    {
      type: 'date',
      label: '日期',
      dataField: 'userDate',
      columnSpan: 1,
      elementProps: {
        picker: 'date',
        valueFormat: 'YYYY-MM-DD'
      }
    },
    {
      type: 'textArea',
      label: '地址',
      dataField: 'address',
      columnSpan: 2
    },
    {
      type: 'space',
      label: '',
      dataField: '',
      columnSpan: 2
    },
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '2、其它信息',
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'checkboxGroup',
      label: '主打产品',
      dataField: 'equipment',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['equipment']
      }
    },
    {
      type: 'radioGroup',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    },
    {
      type: 'status',
      label: '',
      dataField: 'status',
      columnSpan: 1,
      extendProps: {
        showInFooter: true,
        statusOptions: optionsMap['status'],
        formItemStyle: {
          width: '80px',
          marginBottom: 0
        }
      }
    }
  ]
})

const handleStar = () => {
  console.log('handleStar', form.model)
}

const handleUnStar = () => {
  console.log('handleUnStar', form.model)
}

const handleSave = ({ command }) => {
  console.log('handleSave', form.model)
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const handleCancel = ({ command }) => {
  console.log('handleCancel')
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const form = reactive<CommonForm>({
  loading: false,
  operateType: 'add',
  model: {
    code: '1001',
    name: '张三',
    sex: null,
    age: 18,
    userYear: '',
    userMonth: '',
    userDate: '',
    address: '长江路555号',
    equipment: [],
    status: 2
  },
  fields,
  commands: [
    {
      text: '取消',
      command: 'handleCancel'
    },
    {
      text: '确定',
      command: 'handleSave',
      loading: false,
      elementProps: {
        type: 'primary'
      }
    }
  ],
  elementProps: {
    labelCol: { style: { width: '80px' } },
    wrapperCol: { style: { flex: 1 } },
    style: {}
  },
  extendProps: {
    contentStyle: { overflow: 'auto', flex: 1, marginTop: '12px' }
  },
  emitRegister: {
    handleStar,
    handleUnStar,
    handleSave,
    handleCancel
  }
})
</script>

<style lang="scss" scoped>
.common-form-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}
</style>

加载中

<template>
  <div class="common-form-container">
    <ca-common-form ref="formRef" v-bind="form" />
  </div>
</template>

<script lang="ts" setup>
import { computed, onMounted, reactive } from 'vue'
import { CommonForm, FormField } from '#/castor-antdv'

const optionsMap = reactive({
  sex: [
    {
      value: 1,
      label: ''
    },
    {
      value: 2,
      label: ''
    }
  ],
  equipment: [
    {
      value: 'double',
      label: '双压记录仪',
      disabled: false
    },
    {
      value: 'remote',
      label: '压力远传处理仪',
      disabled: false
    }
  ]
})

const fields = computed<Array<FormField>>(() => {
  return [
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '1、基本信息',
        groupCommands: [
          {
            text: '取消关注',
            command: 'handleUnStar'
          },
          {
            text: '关注',
            command: 'handleStar'
          }
        ],
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'text',
      label: '编号',
      dataField: 'code',
      columnSpan: 1
    },
    {
      type: 'default',
      label: '姓名',
      dataField: 'name',
      columnSpan: 1
    },
    {
      type: 'select',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    },
    {
      type: 'inputNumber',
      label: '年龄',
      dataField: 'age',
      columnSpan: 1
    },
    {
      type: 'date',
      label: '年份',
      dataField: 'userYear',
      columnSpan: 1,
      elementProps: {
        picker: 'year',
        valueFormat: 'YYYY'
      }
    },
    {
      type: 'date',
      label: '月份',
      dataField: 'userMonth',
      columnSpan: 1,
      elementProps: {
        picker: 'month',
        valueFormat: 'YYYY-MM'
      }
    },
    {
      type: 'date',
      label: '日期',
      dataField: 'userDate',
      columnSpan: 1,
      elementProps: {
        picker: 'date',
        valueFormat: 'YYYY-MM-DD'
      }
    },
    {
      type: 'switch',
      label: '是否启用',
      dataField: 'userEnabled',
      columnSpan: 1
    },
    {
      type: 'textArea',
      label: '地址',
      dataField: 'address',
      columnSpan: 2
    },
    {
      type: 'space',
      label: '',
      dataField: '',
      columnSpan: 2
    },
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '2、其它信息',
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'checkboxGroup',
      label: '主打产品',
      dataField: 'equipment',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['equipment']
      }
    },
    {
      type: 'radioGroup',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    }
  ]
})

const handleStar = () => {
  console.log('handleStar', form.model)
}

const handleUnStar = () => {
  console.log('handleUnStar', form.model)
}

const handleSave = ({ command }) => {
  console.log('handleSave', form.model)
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const handleCancel = ({ command }) => {
  console.log('handleCancel')
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const form = reactive<CommonForm>({
  loading: false,
  operateType: 'add',
  model: {
    code: '1001',
    name: '张三',
    sex: null,
    age: 18,
    userYear: '',
    userMonth: '',
    userDate: '',
    userEnabled: true,
    address: '长江路555号',
    equipment: []
  },
  fields,
  commands: [
    {
      text: '取消',
      command: 'handleCancel'
    },
    {
      text: '确定',
      command: 'handleSave',
      loading: false,
      elementProps: {
        type: 'primary'
      }
    }
  ],
  elementProps: {
    labelCol: { style: { width: '80px' } },
    wrapperCol: { style: { flex: 1 } },
    style: {}
  },
  extendProps: {
    contentStyle: { overflow: 'auto', flex: 1, marginTop: '12px' }
  },
  emitRegister: {
    handleStar,
    handleUnStar,
    handleSave,
    handleCancel
  }
})

onMounted(() => {
  form.loading = true
  setTimeout(() => (form.loading = false), 3000)
})
</script>

<style lang="scss" scoped>
.common-form-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}
</style>

表单查看

查看表单时,表单处于不可编辑状态。为了提升展示效果,统一转化为文本展示.

<template>
  <div class="common-form-container">
    <ca-common-form ref="formRef" v-bind="form" />
  </div>
</template>

<script lang="ts" setup>
import { computed, reactive } from 'vue'
import { CommonForm, FormField } from '#/castor-antdv'

const optionsMap = reactive({
  sex: [
    {
      value: 1,
      label: ''
    },
    {
      value: 2,
      label: ''
    }
  ],
  equipment: [
    {
      value: 'double',
      label: '双压记录仪',
      disabled: false
    },
    {
      value: 'remote',
      label: '压力远传处理仪',
      disabled: false
    }
  ]
})

const fields = computed<Array<FormField>>(() => {
  return [
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '1、基本信息',
        groupCommands: [
          {
            text: '取消关注',
            command: 'handleUnStar'
          },
          {
            text: '关注',
            command: 'handleStar'
          }
        ],
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'text',
      label: '编号',
      dataField: 'code',
      columnSpan: 1
    },
    {
      type: 'default',
      label: '姓名',
      dataField: 'name',
      columnSpan: 1,
    },
    {
      type: 'select',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    },
    {
      type: 'inputNumber',
      label: '年龄',
      dataField: 'age',
      columnSpan: 1,
    },
    {
      type: 'date',
      label: '年份',
      dataField: 'userYear',
      columnSpan: 1,
      elementProps: {
        picker: 'year',
        valueFormat: 'YYYY'
      }
    },
    {
      type: 'date',
      label: '月份',
      dataField: 'userMonth',
      columnSpan: 1,
      elementProps: {
        picker: 'month',
        valueFormat: 'YYYY-MM'
      }
    },
    {
      type: 'date',
      label: '日期',
      dataField: 'userDate',
      columnSpan: 1,
      elementProps: {
        picker: 'date',
        valueFormat: 'YYYY-MM-DD'
      }
    },
    {
      type: 'switch',
      label: '是否启用',
      dataField: 'userEnabled',
      columnSpan: 1,
    },
    {
      type: 'textArea',
      label: '地址',
      dataField: 'address',
      columnSpan: 2,
    },
    {
      type: 'image',
      label: '头像',
      dataField: 'avatar',
      columnSpan: 2,
      elementProps: {
        imageOptions: {
          width: '100px',
          height: '100px',
          radius: '50%'
        }
      }
    },
    {
      type: 'space',
      label: '',
      dataField: '',
      columnSpan: 2
    },
    {
      type: 'groupTitle',
      label: '',
      dataField: '',
      columnSpan: 2,
      extendProps: {
        groupTitle: '2、其它信息',
        formItemStyle: {
          marginTop: '6px'
        }
      }
    },
    {
      type: 'checkboxGroup',
      label: '主打产品',
      dataField: 'equipment',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['equipment']
      }
    },
    {
      type: 'radioGroup',
      label: '用户性别',
      dataField: 'sex',
      columnSpan: 1,
      elementProps: {
        options: optionsMap['sex']
      }
    }
  ]
})

const handleStar = () => {
  console.log('handleStar', form.model)
}

const handleUnStar = () => {
  console.log('handleUnStar', form.model)
}

const handleSave = ({ command }) => {
  console.log('handleSave', form.model)
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const handleCancel = ({ command }) => {
  console.log('handleCancel')
  command.loading = true
  setTimeout(() => (command.loading = false), 2000)
}

const form = reactive<CommonForm>({
  loading: false,
  operateType: 'view',
  model: {
    code: '1001',
    name: '张三',
    sex: 1,
    age: 18,
    userYear: '2025',
    userMonth: '2025-05',
    userDate: '2025-05-10',
    userEnabled: true,
    address: '长江路555号',
    equipment: ['double', 'remote'],
    avatar: 'https://q2.itc.cn/q_70/images03/20241013/47ff05019e93455abd85cd47612fbf7b.jpeg'
  },
  fields,
  commands: [
    {
      text: '取消',
      command: 'handleCancel'
    },
    {
      text: '确定',
      command: 'handleSave',
      loading: false,
      elementProps: {
        type: 'primary',
        style: {
          fontWeight: 'bold'
        }
      }
    }
  ],
  elementProps: {
    labelCol: { style: { width: '80px' } },
    wrapperCol: { style: { flex: 1 } },
    style: {
      // margin: '0 12px 12px 12px',
      'margin-bottom': '12px'
    }
  },
  extendProps: {
    contentStyle: { overflow: 'auto', flex: 1, marginTop: '12px' }
  },
  emitRegister: {
    handleStar,
    handleUnStar,
    handleSave,
    handleCancel
  }
})
</script>

<style lang="scss" scoped>
.common-form-container {
  height: 100%;
  display: flex;
  flex-direction: column;
}
</style>