123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- <script setup lang="ts">
- import WdButton from 'wot-design-uni/components/wd-button/wd-button.vue'
- import WdInput from 'wot-design-uni/components/wd-input/wd-input.vue'
- import WdPicker from 'wot-design-uni/components/wd-picker/wd-picker.vue'
- import { ConfigProviderThemeVars } from 'wot-design-uni'
- const modelValue = defineModel({
- type: Object,
- default: () => ({}),
- })
- // defineProps({
- // schema: {
- // type: Object as PropType<{
- // [key: string | symbol]: { type: 'TextField' | 'Submit' | string; label?: string; props?: any }
- // }>,
- // required: true,
- // default: () => ({}),
- // },
- // direction: {
- // type: String as PropType<'horizontal' | 'vertical'>,
- // default: 'vertical',
- // },
- // })
- withDefaults(
- defineProps<{
- schema: {
- [key: symbol]: {
- type: 'TextField' | 'Select' | 'Radio' | 'Submit'
- label?: string
- existing?: boolean
- props?: any
- }
- }
- direction?: 'horizontal' | 'vertical'
- }>(),
- { direction: 'vertical' },
- )
- const emits = defineEmits(['submit'])
- const form = ref()
- const types = {
- TextField: WdInput,
- Submit: WdButton,
- Select: WdPicker,
- // Radio: WdRadioGroup,
- }
- const defaultProps = {
- TextField: {
- noBorder: true,
- style: {},
- customClass: 'rounded border border-[#e1e1e1] border-solid p-1',
- placeholder: ' ',
- },
- Submit: {
- customClass: 'w-full! rounded-lg! my-4!',
- block: true,
- },
- }
- const verticalDefaultProps = {
- TextField: {
- noBorder: true,
- style: {},
- customClass: 'rounded border border-[#e1e1e1] border-solid p-1',
- placeholder: ' ',
- },
- Submit: {
- customClass: 'w-full! rounded-lg! my-4!',
- block: true,
- },
- }
- const horizontalDefaultProps = {
- TextField: {
- customClass: 'text-red!',
- placeholderClass: 'text-black/30',
- },
- Select: {
- customClass: 'text-black/30! border-b-1 border-b-[#e1e1e1] border-b-solid',
- },
- Radio: {
- customClass: 'my--4!',
- },
- }
- const themeVars: ConfigProviderThemeVars = {
- cellPadding: '0',
- cellWrapperPadding: '10rpx',
- radioButtonRadius: '8rpx',
- radioButtonBg: 'transparent',
- }
- const submit = () => {
- emits('submit', modelValue)
- }
- const validate = (): Promise<{ valid: boolean; errors: any[] }> => form.value?.validate()
- defineExpose({
- validate,
- })
- </script>
- <template>
- <wd-config-provider :theme-vars="themeVars">
- <wd-form ref="form" :model="modelValue" >
- <template
- v-for="([prop, { type, label, existing, props }], index) in Object.entries(schema)"
- :key="index"
- >
- <div
- v-if="existing ?? true"
- class="grid mb-4"
- :class="[direction === 'horizontal' ? 'items-center' : '']"
- :style="
- direction === 'horizontal'
- ? { 'grid-template-columns': `${props?.labelWidth} auto` }
- : {}
- "
- >
- <label
- v-if="type !== 'Submit'"
- class="text-sm font-normal leading-relaxed"
- :class="[direction === 'horizontal' ? 'text-black/60' : 'mb-1 text-black/40']"
- :for="prop"
- >
- {{ label || prop }}
- </label>
- <wd-input
- v-if="type === 'TextField'"
- v-bind="{
- ...(direction === 'vertical'
- ? verticalDefaultProps[type]
- : horizontalDefaultProps[type]),
- ...props,
- }"
- v-model="modelValue[prop]"
- ></wd-input>
- <wd-picker
- v-if="type === 'Select'"
- v-bind="{
- ...(direction === 'vertical'
- ? verticalDefaultProps[type]
- : horizontalDefaultProps[type]),
- cell: false,
- ...props,
- }"
- v-model="modelValue[prop]"
- ></wd-picker>
- <wd-radio-group
- v-if="type === 'Radio'"
- v-bind="{
- ...(direction === 'vertical'
- ? verticalDefaultProps[type]
- : horizontalDefaultProps[type]),
- ...props,
- cell: true,
- shape: 'button',
- }"
- v-model="modelValue[prop]"
- >
- <template v-for="{ label, value } of props.columns" :key="value">
- <wd-radio :value="value">{{ label }}</wd-radio>
- </template>
- </wd-radio-group>
- <wd-button
- v-if="type === 'Submit'"
- v-bind="{
- ...(direction === 'vertical' ? verticalDefaultProps[type] : {}),
- ...props,
- formType: 'submit',
- }"
- @click="submit"
- >
- <span v-if="type === 'Submit'">提交</span>
- </wd-button>
- </div>
- </template>
- </wd-form>
- </wd-config-provider>
- </template>
|