|
|
@@ -1,278 +0,0 @@
|
|
|
-<!-- 表单示例 -->
|
|
|
-<template>
|
|
|
- <div class="form-example">
|
|
|
- <h2 class="title">表单组件示例</h2>
|
|
|
-
|
|
|
- <ElCard class="art-custom-card" shadow="never">
|
|
|
- <ArtForm
|
|
|
- ref="formRef"
|
|
|
- v-model="formData"
|
|
|
- :items="formItems"
|
|
|
- :rules="formRules"
|
|
|
- :defaultExpanded="true"
|
|
|
- :labelWidth="labelWidth"
|
|
|
- :labelPosition="labelPosition"
|
|
|
- :span="span"
|
|
|
- :gutter="gutter"
|
|
|
- @reset="handleReset"
|
|
|
- @submit="handleSubmit"
|
|
|
- >
|
|
|
- <template #slots>
|
|
|
- <ElInput v-model="formData.slots" placeholder="我是插槽渲染出来的组件" />
|
|
|
- </template>
|
|
|
- </ArtForm>
|
|
|
- </ElCard>
|
|
|
-
|
|
|
- <div class="code">
|
|
|
- <pre><code>{{ formData }}</code></pre>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup lang="ts">
|
|
|
- import { SearchFormItem } from '@/components/core/forms/art-search-bar/index.vue'
|
|
|
- import { ElMessage, ElUpload, ElButton } from 'element-plus'
|
|
|
- import type { UploadFile, UploadFiles, UploadUserFile } from 'element-plus'
|
|
|
-
|
|
|
- interface Emits {
|
|
|
- (e: 'update:modelValue', value: Record<string, any>): void
|
|
|
- (e: 'search', params: Record<string, any>): void
|
|
|
- (e: 'reset'): void
|
|
|
- }
|
|
|
- const emit = defineEmits<Emits>()
|
|
|
-
|
|
|
- // 表单数据双向绑定
|
|
|
- const formRef = ref()
|
|
|
-
|
|
|
- // 表单数据
|
|
|
- const formData = ref({
|
|
|
- name: undefined,
|
|
|
- phone: undefined,
|
|
|
- level: undefined,
|
|
|
- address: undefined,
|
|
|
- slots: undefined,
|
|
|
- date: undefined,
|
|
|
- daterange: undefined,
|
|
|
- cascader: undefined,
|
|
|
- checkboxgroup: undefined,
|
|
|
- userGender: undefined,
|
|
|
- iconSelector: undefined,
|
|
|
- status: undefined,
|
|
|
- systemName: undefined,
|
|
|
- fileUpload: [] as UploadUserFile[],
|
|
|
- imageUpload: [] as UploadUserFile[],
|
|
|
- multipleFiles: [] as UploadUserFile[],
|
|
|
- richTextContent: ''
|
|
|
- })
|
|
|
-
|
|
|
- // 表单校验规则
|
|
|
- const formRules = {
|
|
|
- name: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
|
|
- phone: [
|
|
|
- { required: true, message: '请输入手机号', trigger: 'blur' },
|
|
|
- { min: 11, max: 11, message: '请输入11位手机号', trigger: 'blur' },
|
|
|
- { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
|
|
|
- ]
|
|
|
- }
|
|
|
-
|
|
|
- const labelWidth = ref(100)
|
|
|
- const labelPosition = ref<'right' | 'left' | 'top'>('right')
|
|
|
- const span = ref(6)
|
|
|
- const gutter = ref(12)
|
|
|
-
|
|
|
- // 动态 options
|
|
|
- const levelOptions = ref<{ label: string; value: string; disabled?: boolean }[]>([])
|
|
|
-
|
|
|
- // 共享的选项数据
|
|
|
- const LEVEL_OPTIONS = [
|
|
|
- { label: '普通用户', value: 'normal' },
|
|
|
- { label: 'VIP用户', value: 'vip' },
|
|
|
- { label: '高级VIP', value: 'svip' },
|
|
|
- { label: '企业用户', value: 'enterprise', disabled: true }
|
|
|
- ]
|
|
|
-
|
|
|
- const GENDER_OPTIONS = [
|
|
|
- { label: '男', value: '1' },
|
|
|
- { label: '女', value: '2' }
|
|
|
- ]
|
|
|
-
|
|
|
- const DATE_SHORTCUTS = [
|
|
|
- { text: '今日', value: new Date() },
|
|
|
- { text: '昨日', value: () => new Date(Date.now() - 86400000) },
|
|
|
- { text: '一周前', value: () => new Date(Date.now() - 604800000) }
|
|
|
- ]
|
|
|
-
|
|
|
- // 创建表单项的工厂函数
|
|
|
- const createFormItem = (config: any) => config
|
|
|
-
|
|
|
- // 基础表单项配置
|
|
|
- const baseFormItems = {
|
|
|
- username: createFormItem({
|
|
|
- label: '用户名',
|
|
|
- key: 'name',
|
|
|
- type: 'input',
|
|
|
- placeholder: '请输入用户名',
|
|
|
- clearable: true
|
|
|
- }),
|
|
|
- phone: createFormItem({
|
|
|
- label: '手机号',
|
|
|
- key: 'phone',
|
|
|
- type: 'input',
|
|
|
- props: { placeholder: '请输入手机号', maxlength: '11' }
|
|
|
- }),
|
|
|
- level: createFormItem({
|
|
|
- label: '用户等级',
|
|
|
- key: 'level',
|
|
|
- type: 'select',
|
|
|
- props: { placeholder: '请选择等级', options: LEVEL_OPTIONS }
|
|
|
- }),
|
|
|
- address: createFormItem({
|
|
|
- label: '地址',
|
|
|
- key: 'address',
|
|
|
- type: 'input',
|
|
|
- placeholder: '请输入地址'
|
|
|
- }),
|
|
|
- date: createFormItem({
|
|
|
- label: '日期',
|
|
|
- key: 'date',
|
|
|
- type: 'datetime',
|
|
|
- props: {
|
|
|
- style: { width: '100%' },
|
|
|
- placeholder: '请选择日期',
|
|
|
- type: 'date',
|
|
|
- valueFormat: 'YYYY-MM-DD',
|
|
|
- shortcuts: DATE_SHORTCUTS
|
|
|
- }
|
|
|
- }),
|
|
|
- gender: createFormItem({
|
|
|
- label: '性别',
|
|
|
- key: 'userGender',
|
|
|
- type: 'radiogroup',
|
|
|
- props: {
|
|
|
- options: GENDER_OPTIONS
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- const userItem = ref<SearchFormItem>({
|
|
|
- label: '用户名',
|
|
|
- key: 'name',
|
|
|
- type: 'input',
|
|
|
- props: {
|
|
|
- placeholder: '请输入用户名',
|
|
|
- clearable: true
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- // 控制用户名字段是否显示
|
|
|
- const showUserName = ref(true)
|
|
|
- // 表单配置
|
|
|
- const formItems = computed(() => [
|
|
|
- ...(showUserName.value ? [userItem.value] : []),
|
|
|
- {
|
|
|
- ...baseFormItems.phone
|
|
|
- },
|
|
|
- {
|
|
|
- ...baseFormItems.level,
|
|
|
- props: { placeholder: '请选择等级', options: levelOptions.value }
|
|
|
- },
|
|
|
- baseFormItems.address,
|
|
|
- baseFormItems.date,
|
|
|
-
|
|
|
- {
|
|
|
- ...baseFormItems.gender
|
|
|
- },
|
|
|
-
|
|
|
- {
|
|
|
- label: '是否启用',
|
|
|
- key: 'isEnabled',
|
|
|
- type: 'switch',
|
|
|
- props: {
|
|
|
- placeholder: '请选择是否启用'
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- label: '年龄',
|
|
|
- key: 'age',
|
|
|
- type: 'number',
|
|
|
- slots: {
|
|
|
- suffix: () => h('span', { style: 'color: #909399; font-size: 12px' }, '岁')
|
|
|
- }
|
|
|
- },
|
|
|
- // 文件上传示例 - 使用 h 函数渲染
|
|
|
- {
|
|
|
- label: '文件上传',
|
|
|
- key: 'multipleFiles',
|
|
|
- span: 12,
|
|
|
- type: () =>
|
|
|
- h(
|
|
|
- ElUpload,
|
|
|
- {
|
|
|
- multiple: true,
|
|
|
- limit: 5,
|
|
|
- action: '#',
|
|
|
- autoUpload: false,
|
|
|
- showFileList: true,
|
|
|
- accept: '.pdf,.mp4,.txt',
|
|
|
- beforeUpload: (file: File) => {
|
|
|
- console.log('准备上传文件:', file.name)
|
|
|
- return true
|
|
|
- },
|
|
|
- onChange: (file: UploadFile, fileList: UploadFiles) => {
|
|
|
- console.log('多文件变化:', file, fileList)
|
|
|
- formData.value.multipleFiles = fileList as UploadUserFile[]
|
|
|
- },
|
|
|
- onRemove: (file: UploadFile, fileList: UploadFiles) => {
|
|
|
- console.log('删除文件:', file, fileList)
|
|
|
- formData.value.multipleFiles = fileList as UploadUserFile[]
|
|
|
- },
|
|
|
- onExceed: (files: File[], fileList: UploadUserFile[]) => {
|
|
|
- ElMessage.warning(`最多只能上传 5 个文件,当前选择了 ${files.length + fileList.length} 个文件`)
|
|
|
- }
|
|
|
- },
|
|
|
- { default: () => [h(ElButton, { type: 'primary' }, () => '点击上传')] }
|
|
|
- )
|
|
|
- }
|
|
|
- ])
|
|
|
-
|
|
|
- // 表单处理函数
|
|
|
- const handleReset = () => {
|
|
|
- console.log('重置表单')
|
|
|
- emit('reset')
|
|
|
- }
|
|
|
-
|
|
|
- const handleSubmit = async () => {
|
|
|
- await formRef.value.validate()
|
|
|
- emit('search', formData.value)
|
|
|
- console.log('表单数据', formData.value)
|
|
|
- }
|
|
|
-</script>
|
|
|
-
|
|
|
-<style scoped lang="scss">
|
|
|
- .form-example {
|
|
|
- padding-bottom: 20px;
|
|
|
-
|
|
|
- .title {
|
|
|
- margin-bottom: 5px;
|
|
|
- font-size: 18px;
|
|
|
- font-weight: 500;
|
|
|
-
|
|
|
- &.m-15 {
|
|
|
- margin-top: 15px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .code {
|
|
|
- padding: 15px;
|
|
|
- margin-top: 15px;
|
|
|
- font-size: 14px;
|
|
|
- background-color: var(--art-main-bg-color);
|
|
|
- border: 1px solid var(--art-border-color);
|
|
|
- border-radius: var(--el-border-radius-base);
|
|
|
- }
|
|
|
-
|
|
|
- .button-group {
|
|
|
- margin-top: 15px;
|
|
|
- }
|
|
|
- }
|
|
|
-</style>
|