<template> <q-form ref="myForm" class="my-form row fit"> <div :class="['item', item.col || 'col-12']" v-for="(item, index) in state.config" :key="index" > <template v-if="item.solt"> <div> <slot :name="item.solt"></slot> </div> </template> <template v-else> <q-input v-if="item.type !== 'select'" :type="item.type" v-model="formValue[item.fild]" v-bind="item.bind" :disable=" item.bind.disable === undefined ? state.disable : item.bind.disable " :readonly=" item.bind.readonly === undefined ? state.readonly : item.bind.readonly " /> <q-select v-if="item.type === 'select'" v-bind="item.bind" v-model="formValue[item.fild]" :disable=" item.bind.disable === undefined ? state.disable : item.bind.disable " :readonly=" item.bind.readonly === undefined ? state.readonly : item.bind.readonly " /> </template> </div> </q-form> </template> <script lang="ts" setup> import { onMounted, reactive, ref, watch } from 'vue'; import { cloneDeep, isObjEqual } from 'src/common/utils'; interface Props { config: any; modelValue: any; disable?: boolean; readonly?: boolean; } const props = withDefaults(defineProps<Props>(), { config: () => { return {}; }, modelValue: () => { return {}; }, disable: false, readonly: false, }); defineExpose({ validate, reset, }); const emit = defineEmits<{ (e: 'update:modelValue', value: any): void; }>(); const myForm = ref<any>(null); const state = reactive({ config: cloneDeep(props.config), disable: props.disable, readonly: props.readonly, }); const formValue = ref<any>(cloneDeep(props.modelValue)); watch( () => props.config, (val) => { state.config = cloneDeep(val); }, { deep: true, } ); watch( () => props.modelValue, (val: any) => { if (!isObjEqual(val, formValue.value)) { formValue.value = val; } }, { deep: true, } ); watch( formValue.value, (val) => { emit('update:modelValue', val); }, { deep: true } ); onMounted(() => { // }); async function validate() { return await myForm.value.validate().then((success: any) => { if (success) { return true; } else { return false; } }); } function reset() { myForm.value.resetValidation(); } </script> <style lang="scss" scoped> .item { padding: $padding-sm; } </style>