feat: Add form demo
This commit is contained in:
parent
dbf3b0f5a3
commit
7795d2a4fe
|
@ -1,8 +1,14 @@
|
||||||
import Form from './src/Form.vue'
|
import Form from './src/Form.vue'
|
||||||
|
import { ElForm } from 'element-plus'
|
||||||
|
|
||||||
export interface FormExpose {
|
export interface FormExpose {
|
||||||
setValues: (data: FormSetValuesType[]) => void
|
setValues: (data: Recordable) => void
|
||||||
|
setProps: (props: Recordable) => void
|
||||||
|
delSchema: (field: string) => void
|
||||||
|
addSchema: (formSchema: FormSchema, index?: number) => void
|
||||||
|
setSchema: (schemaProps: FormSetPropsType[]) => void
|
||||||
formModel: Recordable
|
formModel: Recordable
|
||||||
|
getElFormRef: () => ComponentRef<typeof ElForm>
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Form }
|
export { Form }
|
||||||
|
|
|
@ -16,6 +16,8 @@ import { useRenderSelect } from './components/useRenderSelect'
|
||||||
import { useRenderRadio } from './components/useRenderRadio'
|
import { useRenderRadio } from './components/useRenderRadio'
|
||||||
import { useRenderChcekbox } from './components/useRenderChcekbox'
|
import { useRenderChcekbox } from './components/useRenderChcekbox'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
|
import { findIndex } from '@/utils'
|
||||||
|
import { set } from 'lodash-es'
|
||||||
|
|
||||||
const { getPrefixCls } = useDesign()
|
const { getPrefixCls } = useDesign()
|
||||||
|
|
||||||
|
@ -27,7 +29,6 @@ export default defineComponent({
|
||||||
// 生成Form的布局结构数组
|
// 生成Form的布局结构数组
|
||||||
schema: {
|
schema: {
|
||||||
type: Array as PropType<FormSchema[]>,
|
type: Array as PropType<FormSchema[]>,
|
||||||
required: true,
|
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
// 是否需要栅格布局
|
// 是否需要栅格布局
|
||||||
|
@ -42,43 +43,73 @@ export default defineComponent({
|
||||||
// 是否自定义内容
|
// 是否自定义内容
|
||||||
isCustom: propTypes.bool.def(false),
|
isCustom: propTypes.bool.def(false),
|
||||||
// 表单label宽度
|
// 表单label宽度
|
||||||
labelWidth: propTypes.oneOfType([String, Number]).def(130)
|
labelWidth: propTypes.oneOfType([String, Number]).def('auto')
|
||||||
},
|
},
|
||||||
emits: ['register'],
|
emits: ['register'],
|
||||||
setup(props, { slots, expose, emit }) {
|
setup(props, { slots, expose, emit }) {
|
||||||
// element form 实例
|
// element form 实例
|
||||||
const elFormRef = ref<ComponentRef<typeof ElForm>>()
|
const elFormRef = ref<ComponentRef<typeof ElForm>>()
|
||||||
const getProps = computed(() => props)
|
|
||||||
|
// useForm传入的props
|
||||||
|
const outsideProps = ref<Recordable>({})
|
||||||
|
|
||||||
|
const getProps = computed(() => Object.assign({ ...props }, unref(outsideProps)))
|
||||||
|
|
||||||
const { schema, isCol, isCustom, autoSetPlaceholder } = unref(getProps)
|
const { schema, isCol, isCustom, autoSetPlaceholder } = unref(getProps)
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const formModel = ref<Recordable>({})
|
const formModel = ref<Recordable>({})
|
||||||
watch(
|
|
||||||
() => formModel.value,
|
|
||||||
(formModel: Recordable) => {
|
|
||||||
console.log(formModel)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
emit('register', elFormRef.value?.$parent, elFormRef.value)
|
emit('register', elFormRef.value?.$parent, elFormRef.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 对表单赋值
|
// 对表单赋值
|
||||||
const setValues = (data: FormSetValuesType[]) => {
|
const setValues = (data: Recordable = {}) => {
|
||||||
if (!data.length) return
|
formModel.value = Object.assign(unref(formModel), data)
|
||||||
const formData: Recordable = {}
|
}
|
||||||
for (const v of data) {
|
|
||||||
formData[v.field] = v.value
|
const setProps = (props: Recordable) => {
|
||||||
|
outsideProps.value = props
|
||||||
|
}
|
||||||
|
|
||||||
|
const delSchema = (field: string) => {
|
||||||
|
const index = findIndex(schema, (v: FormSchema) => v.field === field)
|
||||||
|
if (index > -1) {
|
||||||
|
schema.splice(index, 1)
|
||||||
}
|
}
|
||||||
formModel.value = Object.assign(unref(formModel), formData)
|
}
|
||||||
|
|
||||||
|
const addSchema = (formSchema: FormSchema, index?: number) => {
|
||||||
|
if (index !== void 0) {
|
||||||
|
schema.splice(index, 0, formSchema)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
schema.push(formSchema)
|
||||||
|
}
|
||||||
|
|
||||||
|
const setSchema = (schemaProps: FormSetPropsType[]) => {
|
||||||
|
for (const v of schema) {
|
||||||
|
for (const item of schemaProps) {
|
||||||
|
if (v.field === item.field) {
|
||||||
|
set(v, item.path, item.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getElFormRef = (): ComponentRef<typeof ElForm> => {
|
||||||
|
return unref(elFormRef) as ComponentRef<typeof ElForm>
|
||||||
}
|
}
|
||||||
|
|
||||||
expose({
|
expose({
|
||||||
setValues,
|
setValues,
|
||||||
formModel
|
formModel,
|
||||||
|
setProps,
|
||||||
|
delSchema,
|
||||||
|
addSchema,
|
||||||
|
setSchema,
|
||||||
|
getElFormRef
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听表单结构化数组,重新生成formModel
|
// 监听表单结构化数组,重新生成formModel
|
||||||
|
|
|
@ -29,17 +29,19 @@ export const useForm = () => {
|
||||||
|
|
||||||
// 一些内置的方法
|
// 一些内置的方法
|
||||||
const methods: {
|
const methods: {
|
||||||
setValues: (data: FormSetValuesType[]) => void
|
setProps: (props: Recordable) => void
|
||||||
getFormData: () => Promise<Recordable | undefined>
|
setValues: (data: Recordable) => void
|
||||||
setSchema: (schemaProps: FormSetValuesType[]) => void
|
getFormData: <T = Recordable | undefined>() => Promise<T>
|
||||||
|
setSchema: (schemaProps: FormSetPropsType[]) => void
|
||||||
addSchema: (formSchema: FormSchema, index?: number) => void
|
addSchema: (formSchema: FormSchema, index?: number) => void
|
||||||
delSchema: (index: number) => void
|
delSchema: (field: string) => void
|
||||||
} = {
|
} = {
|
||||||
/**
|
setProps: async (props: Recordable = {}) => {
|
||||||
* @param field 字段
|
const form = await getForm()
|
||||||
* @param value 值
|
form?.setProps(props)
|
||||||
*/
|
},
|
||||||
setValues: async (data: FormSetValuesType[]) => {
|
|
||||||
|
setValues: async (data: Recordable) => {
|
||||||
const form = await getForm()
|
const form = await getForm()
|
||||||
form?.setValues(data)
|
form?.setValues(data)
|
||||||
},
|
},
|
||||||
|
@ -62,19 +64,19 @@ export const useForm = () => {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param index 删除哪个数据
|
* @param field 删除哪个数据
|
||||||
*/
|
*/
|
||||||
delSchema: async (index: number) => {
|
delSchema: async (field: string) => {
|
||||||
const form = await getForm()
|
const form = await getForm()
|
||||||
form?.delSchema(index)
|
form?.delSchema(field)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns form data
|
* @returns form data
|
||||||
*/
|
*/
|
||||||
getFormData: async (): Promise<Recordable | undefined> => {
|
getFormData: async <T = Recordable>(): Promise<T> => {
|
||||||
const form = await getForm()
|
const form = await getForm()
|
||||||
return form?.formModel || undefined
|
return form?.formModel as T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,9 @@ export default {
|
||||||
watermark: 'Watermark',
|
watermark: 'Watermark',
|
||||||
qrcode: 'Qrcode',
|
qrcode: 'Qrcode',
|
||||||
highlight: 'Highlight',
|
highlight: 'Highlight',
|
||||||
infotip: 'Infotip'
|
infotip: 'Infotip',
|
||||||
|
form: 'Form',
|
||||||
|
defaultForm: 'All examples'
|
||||||
},
|
},
|
||||||
analysis: {
|
analysis: {
|
||||||
newUser: 'New user',
|
newUser: 'New user',
|
||||||
|
@ -193,7 +195,24 @@ export default {
|
||||||
timePicker: 'Time Picker',
|
timePicker: 'Time Picker',
|
||||||
timeSelect: 'Time Select',
|
timeSelect: 'Time Select',
|
||||||
inputPassword: 'input Password',
|
inputPassword: 'input Password',
|
||||||
passwordStrength: 'Password Strength'
|
passwordStrength: 'Password Strength',
|
||||||
|
defaultForm: 'All examples',
|
||||||
|
formDes:
|
||||||
|
'The secondary encapsulation of form components based on ElementPlus realizes data-driven and supports all Form parameters',
|
||||||
|
example: 'example',
|
||||||
|
operate: 'Operate',
|
||||||
|
change: 'Change',
|
||||||
|
restore: 'Restore',
|
||||||
|
disabled: 'Disabled',
|
||||||
|
disablement: 'Disablement',
|
||||||
|
delete: 'Delete',
|
||||||
|
add: 'Add',
|
||||||
|
setValue: 'Set value',
|
||||||
|
resetValue: 'Reset value',
|
||||||
|
set: 'Set',
|
||||||
|
subitem: 'Subitem',
|
||||||
|
formValidation: 'Form validation',
|
||||||
|
verifyReset: 'Verify reset'
|
||||||
},
|
},
|
||||||
guideDemo: {
|
guideDemo: {
|
||||||
guide: 'Guide',
|
guide: 'Guide',
|
||||||
|
|
|
@ -93,7 +93,9 @@ export default {
|
||||||
watermark: '水印',
|
watermark: '水印',
|
||||||
qrcode: '二维码',
|
qrcode: '二维码',
|
||||||
highlight: '高亮',
|
highlight: '高亮',
|
||||||
infotip: '信息提示'
|
infotip: '信息提示',
|
||||||
|
form: '表单',
|
||||||
|
defaultForm: '全部示例'
|
||||||
},
|
},
|
||||||
analysis: {
|
analysis: {
|
||||||
newUser: '新增用户',
|
newUser: '新增用户',
|
||||||
|
@ -193,7 +195,23 @@ export default {
|
||||||
timePicker: '时间选择器',
|
timePicker: '时间选择器',
|
||||||
timeSelect: '时间选择',
|
timeSelect: '时间选择',
|
||||||
inputPassword: '密码输入框',
|
inputPassword: '密码输入框',
|
||||||
passwordStrength: '密码强度'
|
passwordStrength: '密码强度',
|
||||||
|
defaultForm: '全部示例',
|
||||||
|
formDes: '基于 ElementPlus 的 Form 组件二次封装,实现数据驱动,支持所有 Form 参数',
|
||||||
|
example: '示例',
|
||||||
|
operate: '操作',
|
||||||
|
change: '更改',
|
||||||
|
restore: '还原',
|
||||||
|
disabled: '禁用',
|
||||||
|
disablement: '解除禁用',
|
||||||
|
delete: '删除',
|
||||||
|
add: '添加',
|
||||||
|
setValue: '设置值',
|
||||||
|
resetValue: '重置值',
|
||||||
|
set: '设置',
|
||||||
|
subitem: '子项',
|
||||||
|
formValidation: '表单验证',
|
||||||
|
verifyReset: '验证重置'
|
||||||
},
|
},
|
||||||
guideDemo: {
|
guideDemo: {
|
||||||
guide: '引导页',
|
guide: '引导页',
|
||||||
|
|
|
@ -96,6 +96,41 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
|
||||||
alwaysShow: true
|
alwaysShow: true
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
path: 'form',
|
||||||
|
component: getParentLayout(),
|
||||||
|
name: 'Form',
|
||||||
|
meta: {
|
||||||
|
title: t('router.form'),
|
||||||
|
alwaysShow: true
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'default-form',
|
||||||
|
component: () => import('@/views/Components/Form/DefaultForm.vue'),
|
||||||
|
name: 'DefaultForm',
|
||||||
|
meta: {
|
||||||
|
title: t('router.defaultForm')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'use-form',
|
||||||
|
component: () => import('@/views/Components/Form/UseFormDemo.vue'),
|
||||||
|
name: 'UseForm',
|
||||||
|
meta: {
|
||||||
|
title: 'useForm'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'ref-form',
|
||||||
|
component: () => import('@/views/Components/Form/RefForm.vue'),
|
||||||
|
name: 'RefForm',
|
||||||
|
meta: {
|
||||||
|
title: 'refForm'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'icon',
|
path: 'icon',
|
||||||
component: () => import('@/views/Components/Icon.vue'),
|
component: () => import('@/views/Components/Icon.vue'),
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,249 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Form, FormExpose } from '@/components/Form'
|
||||||
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { reactive, unref, ref } from 'vue'
|
||||||
|
import { ElButton } from 'element-plus'
|
||||||
|
import { required } from '@/utils/formRules'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const schema = reactive<FormSchema[]>([
|
||||||
|
{
|
||||||
|
field: 'field1',
|
||||||
|
label: t('formDemo.input'),
|
||||||
|
component: 'Input',
|
||||||
|
formItemProps: {
|
||||||
|
rules: [required]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field2',
|
||||||
|
label: t('formDemo.select'),
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'option1',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option2',
|
||||||
|
value: '2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field3',
|
||||||
|
label: t('formDemo.radio'),
|
||||||
|
component: 'Radio',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'option-1',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option-2',
|
||||||
|
value: '2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field4',
|
||||||
|
label: t('formDemo.checkbox'),
|
||||||
|
component: 'Checkbox',
|
||||||
|
value: [],
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'option-1',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option-2',
|
||||||
|
value: '2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option-3',
|
||||||
|
value: '3'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field5',
|
||||||
|
component: 'DatePicker',
|
||||||
|
label: t('formDemo.datePicker'),
|
||||||
|
componentProps: {
|
||||||
|
type: 'date'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field6',
|
||||||
|
component: 'TimeSelect',
|
||||||
|
label: t('formDemo.timeSelect')
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const formRef = ref<FormExpose>()
|
||||||
|
|
||||||
|
const changeLabelWidth = (width: number | string) => {
|
||||||
|
unref(formRef)?.setProps({
|
||||||
|
labelWidth: width
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeSize = (size: string) => {
|
||||||
|
unref(formRef)?.setProps({
|
||||||
|
size
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeDisabled = (bool: boolean) => {
|
||||||
|
unref(formRef)?.setProps({
|
||||||
|
disabled: bool
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeSchema = (del: boolean) => {
|
||||||
|
if (del) {
|
||||||
|
unref(formRef)?.delSchema('field2')
|
||||||
|
} else if (!del && schema[1].field !== 'field2') {
|
||||||
|
unref(formRef)?.addSchema(
|
||||||
|
{
|
||||||
|
field: 'field2',
|
||||||
|
label: t('formDemo.select'),
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'option1',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option2',
|
||||||
|
value: '2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const setValue = (reset: boolean) => {
|
||||||
|
const elFormRef = unref(formRef)?.getElFormRef()
|
||||||
|
if (reset) {
|
||||||
|
elFormRef?.resetFields()
|
||||||
|
} else {
|
||||||
|
unref(formRef)?.setValues({
|
||||||
|
field1: 'field1',
|
||||||
|
field2: '2',
|
||||||
|
field3: '2',
|
||||||
|
field4: ['1', '3'],
|
||||||
|
field5: '2022-01-27',
|
||||||
|
field6: '17:00'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = ref(7)
|
||||||
|
|
||||||
|
const setLabel = () => {
|
||||||
|
unref(formRef)?.setSchema([
|
||||||
|
{
|
||||||
|
field: 'field2',
|
||||||
|
path: 'label',
|
||||||
|
value: `${t('formDemo.select')} ${index.value}`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field2',
|
||||||
|
path: 'componentProps.options',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
label: 'option-1',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option-2',
|
||||||
|
value: '2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option-3',
|
||||||
|
value: '3'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
index.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
const addItem = () => {
|
||||||
|
if (unref(index) % 2 === 0) {
|
||||||
|
unref(formRef)?.addSchema({
|
||||||
|
field: `field${unref(index)}`,
|
||||||
|
label: `${t('formDemo.input')}${unref(index)}`,
|
||||||
|
component: 'Input'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
unref(formRef)?.addSchema(
|
||||||
|
{
|
||||||
|
field: `field${unref(index)}`,
|
||||||
|
label: `${t('formDemo.input')}${unref(index)}`,
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
unref(index)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
index.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
const formValidation = () => {
|
||||||
|
const elFormRef = unref(formRef)?.getElFormRef()
|
||||||
|
elFormRef?.validate()?.catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
const verifyReset = () => {
|
||||||
|
const elFormRef = unref(formRef)?.getElFormRef()
|
||||||
|
elFormRef?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ContentWrap :title="`refForm${t('formDemo.operate')}`">
|
||||||
|
<ElButton @click="changeLabelWidth(150)">{{ t('formDemo.change') }} labelWidth</ElButton>
|
||||||
|
<ElButton @click="changeLabelWidth('auto')">{{ t('formDemo.restore') }} labelWidth</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="changeSize('large')">{{ t('formDemo.change') }} size</ElButton>
|
||||||
|
<ElButton @click="changeSize('default')">{{ t('formDemo.restore') }} size</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="changeDisabled(true)">{{ t('formDemo.disabled') }}</ElButton>
|
||||||
|
<ElButton @click="changeDisabled(false)">{{ t('formDemo.disablement') }}</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="changeSchema(true)">
|
||||||
|
{{ t('formDemo.delete') }} {{ t('formDemo.select') }}
|
||||||
|
</ElButton>
|
||||||
|
<ElButton @click="changeSchema(false)">
|
||||||
|
{{ t('formDemo.add') }} {{ t('formDemo.select') }}
|
||||||
|
</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="setValue(false)">{{ t('formDemo.setValue') }}</ElButton>
|
||||||
|
<ElButton @click="setValue(true)">{{ t('formDemo.resetValue') }}</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="setLabel">
|
||||||
|
{{ t('formDemo.set') }} {{ t('formDemo.select') }} label
|
||||||
|
</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="addItem"> {{ t('formDemo.add') }} {{ t('formDemo.subitem') }} </ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="formValidation"> {{ t('formDemo.formValidation') }} </ElButton>
|
||||||
|
<ElButton @click="verifyReset"> {{ t('formDemo.verifyReset') }} </ElButton>
|
||||||
|
</ContentWrap>
|
||||||
|
<ContentWrap :title="`useForm${t('formDemo.example')}`">
|
||||||
|
<Form :schema="schema" ref="formRef" />
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
|
@ -0,0 +1,256 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Form } from '@/components/Form'
|
||||||
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { useForm } from '@/hooks/web/useForm'
|
||||||
|
import { reactive, unref, ref } from 'vue'
|
||||||
|
import { ElButton } from 'element-plus'
|
||||||
|
import { required } from '@/utils/formRules'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const schema = reactive<FormSchema[]>([
|
||||||
|
{
|
||||||
|
field: 'field1',
|
||||||
|
label: t('formDemo.input'),
|
||||||
|
component: 'Input',
|
||||||
|
formItemProps: {
|
||||||
|
rules: [required]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field2',
|
||||||
|
label: t('formDemo.select'),
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'option1',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option2',
|
||||||
|
value: '2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field3',
|
||||||
|
label: t('formDemo.radio'),
|
||||||
|
component: 'Radio',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'option-1',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option-2',
|
||||||
|
value: '2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field4',
|
||||||
|
label: t('formDemo.checkbox'),
|
||||||
|
component: 'Checkbox',
|
||||||
|
value: [],
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'option-1',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option-2',
|
||||||
|
value: '2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option-3',
|
||||||
|
value: '3'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field5',
|
||||||
|
component: 'DatePicker',
|
||||||
|
label: t('formDemo.datePicker'),
|
||||||
|
componentProps: {
|
||||||
|
type: 'date'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field6',
|
||||||
|
component: 'TimeSelect',
|
||||||
|
label: t('formDemo.timeSelect')
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const { register, methods, elFormRef } = useForm()
|
||||||
|
|
||||||
|
const changeLabelWidth = (width: number | string) => {
|
||||||
|
const { setProps } = methods
|
||||||
|
setProps({
|
||||||
|
labelWidth: width
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeSize = (size: string) => {
|
||||||
|
const { setProps } = methods
|
||||||
|
setProps({
|
||||||
|
size
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeDisabled = (bool: boolean) => {
|
||||||
|
const { setProps } = methods
|
||||||
|
setProps({
|
||||||
|
disabled: bool
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeSchema = (del: boolean) => {
|
||||||
|
const { delSchema, addSchema } = methods
|
||||||
|
if (del) {
|
||||||
|
delSchema('field2')
|
||||||
|
} else if (!del && schema[1].field !== 'field2') {
|
||||||
|
addSchema(
|
||||||
|
{
|
||||||
|
field: 'field2',
|
||||||
|
label: t('formDemo.select'),
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: 'option1',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option2',
|
||||||
|
value: '2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const setValue = (reset: boolean) => {
|
||||||
|
const { setValues } = methods
|
||||||
|
if (reset) {
|
||||||
|
unref(elFormRef)?.resetFields()
|
||||||
|
} else {
|
||||||
|
setValues({
|
||||||
|
field1: 'field1',
|
||||||
|
field2: '2',
|
||||||
|
field3: '2',
|
||||||
|
field4: ['1', '3'],
|
||||||
|
field5: '2022-01-27',
|
||||||
|
field6: '17:00'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = ref(7)
|
||||||
|
|
||||||
|
const setLabel = () => {
|
||||||
|
const { setSchema } = methods
|
||||||
|
setSchema([
|
||||||
|
{
|
||||||
|
field: 'field2',
|
||||||
|
path: 'label',
|
||||||
|
value: `${t('formDemo.select')} ${index.value}`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'field2',
|
||||||
|
path: 'componentProps.options',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
label: 'option-1',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option-2',
|
||||||
|
value: '2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'option-3',
|
||||||
|
value: '3'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
index.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
const addItem = () => {
|
||||||
|
const { addSchema } = methods
|
||||||
|
if (unref(index) % 2 === 0) {
|
||||||
|
addSchema({
|
||||||
|
field: `field${unref(index)}`,
|
||||||
|
label: `${t('formDemo.input')}${unref(index)}`,
|
||||||
|
component: 'Input'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
addSchema(
|
||||||
|
{
|
||||||
|
field: `field${unref(index)}`,
|
||||||
|
label: `${t('formDemo.input')}${unref(index)}`,
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
unref(index)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
index.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
const formValidation = () => {
|
||||||
|
unref(elFormRef)
|
||||||
|
?.validate()
|
||||||
|
?.catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
const verifyReset = () => {
|
||||||
|
unref(elFormRef)?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ContentWrap :title="`useForm${t('formDemo.operate')}`">
|
||||||
|
<ElButton @click="changeLabelWidth(150)">{{ t('formDemo.change') }} labelWidth</ElButton>
|
||||||
|
<ElButton @click="changeLabelWidth('auto')">{{ t('formDemo.restore') }} labelWidth</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="changeSize('large')">{{ t('formDemo.change') }} size</ElButton>
|
||||||
|
<ElButton @click="changeSize('default')">{{ t('formDemo.restore') }} size</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="changeDisabled(true)">{{ t('formDemo.disabled') }}</ElButton>
|
||||||
|
<ElButton @click="changeDisabled(false)">{{ t('formDemo.disablement') }}</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="changeSchema(true)">
|
||||||
|
{{ t('formDemo.delete') }} {{ t('formDemo.select') }}
|
||||||
|
</ElButton>
|
||||||
|
<ElButton @click="changeSchema(false)">
|
||||||
|
{{ t('formDemo.add') }} {{ t('formDemo.select') }}
|
||||||
|
</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="setValue(false)">{{ t('formDemo.setValue') }}</ElButton>
|
||||||
|
<ElButton @click="setValue(true)">{{ t('formDemo.resetValue') }}</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="setLabel">
|
||||||
|
{{ t('formDemo.set') }} {{ t('formDemo.select') }} label
|
||||||
|
</ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="addItem"> {{ t('formDemo.add') }} {{ t('formDemo.subitem') }} </ElButton>
|
||||||
|
|
||||||
|
<ElButton @click="formValidation"> {{ t('formDemo.formValidation') }} </ElButton>
|
||||||
|
<ElButton @click="verifyReset"> {{ t('formDemo.verifyReset') }} </ElButton>
|
||||||
|
</ContentWrap>
|
||||||
|
<ContentWrap :title="`useForm${t('formDemo.example')}`">
|
||||||
|
<Form :schema="schema" @register="register" />
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
|
@ -172,14 +172,14 @@ const { t } = useI18n()
|
||||||
|
|
||||||
<ElRow class="mt-20px" :gutter="20" justify="space-between">
|
<ElRow class="mt-20px" :gutter="20" justify="space-between">
|
||||||
<ElCol :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-20px">
|
<ElCol :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-20px">
|
||||||
<ElSkeleton :loading="loading" animated>
|
<ElCard shadow="never">
|
||||||
<ElCard shadow="never">
|
<template #header>
|
||||||
<template #header>
|
<div class="flex justify-between">
|
||||||
<div class="flex justify-between">
|
<span>{{ t('workplace.project') }}</span>
|
||||||
<span>{{ t('workplace.project') }}</span>
|
<ElLink type="primary" :underline="false">{{ t('workplace.more') }}</ElLink>
|
||||||
<ElLink type="primary" :underline="false">{{ t('workplace.more') }}</ElLink>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
<ElSkeleton :loading="loading" animated>
|
||||||
<ElRow>
|
<ElRow>
|
||||||
<ElCol
|
<ElCol
|
||||||
v-for="(item, index) in projects"
|
v-for="(item, index) in projects"
|
||||||
|
@ -203,17 +203,17 @@ const { t } = useI18n()
|
||||||
</ElCard>
|
</ElCard>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
</ElRow>
|
</ElRow>
|
||||||
</ElCard>
|
</ElSkeleton>
|
||||||
</ElSkeleton>
|
</ElCard>
|
||||||
|
|
||||||
<ElSkeleton :loading="loading" animated>
|
<ElCard shadow="never" class="mt-20px">
|
||||||
<ElCard shadow="never" class="mt-20px">
|
<template #header>
|
||||||
<template #header>
|
<div class="flex justify-between">
|
||||||
<div class="flex justify-between">
|
<span>{{ t('workplace.dynamic') }}</span>
|
||||||
<span>{{ t('workplace.dynamic') }}</span>
|
<ElLink type="primary" :underline="false">{{ t('workplace.more') }}</ElLink>
|
||||||
<ElLink type="primary" :underline="false">{{ t('workplace.more') }}</ElLink>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
<ElSkeleton :loading="loading" animated>
|
||||||
<div v-for="(item, index) in dynamics" :key="`dynamics-${index}`">
|
<div v-for="(item, index) in dynamics" :key="`dynamics-${index}`">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img
|
<img
|
||||||
|
@ -234,15 +234,15 @@ const { t } = useI18n()
|
||||||
</div>
|
</div>
|
||||||
<ElDivider />
|
<ElDivider />
|
||||||
</div>
|
</div>
|
||||||
</ElCard>
|
</ElSkeleton>
|
||||||
</ElSkeleton>
|
</ElCard>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
<ElCol :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-20px">
|
<ElCol :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-20px">
|
||||||
<ElSkeleton :loading="loading" animated>
|
<ElCard shadow="never">
|
||||||
<ElCard shadow="never">
|
<template #header>
|
||||||
<template #header>
|
<span>{{ t('workplace.shortcutOperation') }}</span>
|
||||||
<span>{{ t('workplace.shortcutOperation') }}</span>
|
</template>
|
||||||
</template>
|
<ElSkeleton :loading="loading" animated>
|
||||||
<ElCol
|
<ElCol
|
||||||
v-for="item in 9"
|
v-for="item in 9"
|
||||||
:key="`card-${item}`"
|
:key="`card-${item}`"
|
||||||
|
@ -257,23 +257,23 @@ const { t } = useI18n()
|
||||||
{{ t('workplace.operation') }}{{ item }}
|
{{ t('workplace.operation') }}{{ item }}
|
||||||
</ElLink>
|
</ElLink>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
</ElCard>
|
</ElSkeleton>
|
||||||
</ElSkeleton>
|
</ElCard>
|
||||||
|
|
||||||
<ElSkeleton :loading="loading" animated>
|
<ElCard shadow="never" class="mt-20px">
|
||||||
<ElCard shadow="never" class="mt-20px">
|
<template #header>
|
||||||
<template #header>
|
<span>xx{{ t('workplace.index') }}</span>
|
||||||
<span>xx{{ t('workplace.index') }}</span>
|
</template>
|
||||||
</template>
|
<ElSkeleton :loading="loading" animated>
|
||||||
<Echart :options="radarOptionData" :height="400" />
|
<Echart :options="radarOptionData" :height="400" />
|
||||||
</ElCard>
|
</ElSkeleton>
|
||||||
</ElSkeleton>
|
</ElCard>
|
||||||
|
|
||||||
<ElSkeleton :loading="loading" animated>
|
<ElCard shadow="never" class="mt-20px">
|
||||||
<ElCard shadow="never" class="mt-20px">
|
<template #header>
|
||||||
<template #header>
|
<span>{{ t('workplace.team') }}</span>
|
||||||
<span>{{ t('workplace.team') }}</span>
|
</template>
|
||||||
</template>
|
<ElSkeleton :loading="loading" animated>
|
||||||
<ElRow>
|
<ElRow>
|
||||||
<ElCol v-for="item in team" :key="`team-${item.name}`" :span="12" class="mb-20px">
|
<ElCol v-for="item in team" :key="`team-${item.name}`" :span="12" class="mb-20px">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
|
@ -284,8 +284,8 @@ const { t } = useI18n()
|
||||||
</div>
|
</div>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
</ElRow>
|
</ElRow>
|
||||||
</ElCard>
|
</ElSkeleton>
|
||||||
</ElSkeleton>
|
</ElCard>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
</ElRow>
|
</ElRow>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -117,7 +117,7 @@ const signIn = async () => {
|
||||||
if (validate) {
|
if (validate) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const { getFormData } = methods
|
const { getFormData } = methods
|
||||||
const formData = (await getFormData()) as UserLoginType
|
const formData = await getFormData<UserLoginType>()
|
||||||
|
|
||||||
const res = await loginApi(formData)
|
const res = await loginApi(formData)
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
|
|
|
@ -84,11 +84,6 @@ declare global {
|
||||||
hidden?: boolean
|
hidden?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
declare type FormSetValuesType = {
|
|
||||||
field: string
|
|
||||||
value: FormValueType
|
|
||||||
}
|
|
||||||
|
|
||||||
declare type FormSetPropsType = {
|
declare type FormSetPropsType = {
|
||||||
field: string
|
field: string
|
||||||
path: string
|
path: string
|
||||||
|
|
Loading…
Reference in New Issue