123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- <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 { ref } from 'vue'
- 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',
- },
- })
- 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 submit = () => {
- emits('submit', modelValue)
- }
- const validate = (): Promise<{ valid: boolean; errors: any[] }> => form.value?.validate()
- defineExpose({
- validate,
- })
- </script>
- <template>
- <wd-form ref="form" :model="modelValue">
- <template
- v-for="([prop, { type, label, props }], index) in Object.entries(schema)"
- :key="index"
- >
- <div class="grid mb-4">
- <label
- v-if="type !== 'Submit' && direction === 'vertical'"
- class="text-black/40 text-sm font-normal font-['PingFang SC'] leading-relaxed mb-1"
- :for="prop"
- >
- {{ label || prop }}
- </label>
- <!-- #ifdef H5 -->
- <component :is="types[type]" :name="prop" v-bind="defaultProps[type]">
- <span v-if="type === 'Submit'">提交</span>
- </component>
- <!-- #endif -->
- <!-- #ifdef MP-WEIXIN -->
- <wd-input
- v-if="type === 'TextField'"
- v-bind="{
- ...(direction === 'vertical' ? verticalDefaultProps[type] : {}),
- ...props,
- }"
- v-model="modelValue[prop]"
- ></wd-input>
- <wd-picker
- v-if="type === 'Select'"
- v-bind="{ label, ...props }"
- v-model="modelValue[prop]"
- ></wd-picker>
- <wd-radio-group
- v-if="type === 'Radio'"
- v-bind="{ label, ...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>
- <!-- #endif -->
- </div>
- </template>
- </wd-form>
- </template>
|