浏览代码

表单组件

774078984@qq.com 3 月之前
父节点
当前提交
0c58829ca9
共有 2 个文件被更改,包括 145 次插入0 次删除
  1. 141 0
      src/components/Form/index.vue
  2. 4 0
      src/views/tariffManagement/index.vue

+ 141 - 0
src/components/Form/index.vue

@@ -0,0 +1,141 @@
+<template>
+    <a-form ref="formRef" :model="formData" :rules="formRules" @submit="handleSubmit">
+        <template v-for="(item, index) in formConfig" :key="`field-${index}`">
+            <a-col :span="item.layout === 1 ? 24 : 12" v-if="isVisibleShow(item, formData)">
+                <a-form-item :label="item.label" :rules="item.rules" :field="item.field"
+                    :validate-trigger="rulesTagse(item?.rules)">
+                    <component :is="'a-' + item.type" v-model="formData[item.field]" v-bind="item.props"
+                        @change="(e) => handelChange(e, item)">
+                        <template v-if="item.type == 'select'">
+                            <a-option v-for="option in item.options" :key="option.value" :value="option.value">
+                                {{ option.label }}
+                            </a-option>
+                        </template>
+                        <!-- 渲染插槽 必须先渲染一次 在传递给父组件 不然为空 -->
+                        <template v-if="item.slot" #[item.slot]>
+                            <slot :name="item.slot" :item="item"></slot>
+                        </template>
+                    </component>
+                </a-form-item>
+            </a-col>
+        </template>
+        <a-form-item>
+            <a-button type="primary" html-type="submit">提交</a-button>
+        </a-form-item>
+    </a-form>
+</template>
+
+<script setup>
+import { ref, defineProps, toRefs, defineEmits, onMounted, watchEffect } from 'vue';
+import service from '@/utils/axios.js'
+import { Getdictionary } from '@/mixins/index'
+
+// 使用
+// const formConfig = ;
+const props = defineProps({
+    formConfig: {
+        type: Array,
+        default: () => [
+            {
+                field: 'username',
+                type: 'input',
+                label: '用户名',
+                value: '',
+                rules: [
+                    { required: true, message: '请输入用户名', trigger: 'blur' },
+                ],
+            },
+            {
+                field: 'gender',
+                type: 'select',
+                label: '性别',
+                value: '',
+                options: [],
+                dict: 'cardType',
+                isVisible: false
+            },
+            {
+                field: 'a',
+                type: 'select',
+                label: '6666',
+                value: '',
+                options: [],
+                isVisible: async (item, e) => {
+                    return e.gender == 1
+                }
+            }
+        ]
+    },
+
+});
+const emits = defineEmits(['submit', 'change']);
+
+const { formConfig } = toRefs(props)
+
+const formData = ref({}); // 存储表单数据
+const formRules = ref({}); // 存储表单验证规则
+
+const isVisibleShow = async (item, formData) => {
+    if (item && item.isVisible && typeof item.isVisible === 'function') {
+        let distShow = await item.isVisible(item, formData);
+        return distShow
+    }
+};
+// 加载字典数据
+const loadDictOptions = async (index, dict, api) => {
+    if (dict) {
+        const res = await Getdictionary(dict);
+        formConfig.value[index].options = res
+    }
+    if (api) {
+        const res = await service[api.method](api.url, api.data || {});
+        if (res.code === 200) {
+            formConfig.value[index].options = res.data
+        }
+    }
+};
+
+
+
+const handelChange = (e, item) => {
+    emits('change', e)
+    isVisibleShow(item, formData.value)
+}
+
+// 表单提交方法
+const handleSubmit = () => {
+    emits('submit', formData.value)
+};
+
+const rulesTagse = (item) => {
+    if (!item) return ''
+    return item[0]?.trigger
+}
+
+onMounted(() => {
+    formConfig.value.forEach(async (res, key) => {
+        if (res.dict) {
+            await loadDictOptions(key, res.dict); // 加载字典数据
+        }
+        if (res.api) {
+            await loadDictOptions(key, false, res.api); // 加载字典数据
+        }
+    })
+    // 初始化 formData 和 formRules
+    formData.value = formConfig.value.reduce((acc, item) => {
+        acc[item.field] = item.value || ''; // 使用传入的 value 或空字符串
+        return acc;
+    }, {});
+
+    // 初始化 formRules
+    formRules.value = formConfig.value.reduce((acc, item) => {
+        if (item.rules) {
+            acc[item.field] = item.rules; // 根据传入的 rules 初始化验证规则
+        }
+        return acc;
+    }, {});
+})
+
+</script>
+
+<style scoped></style>

+ 4 - 0
src/views/tariffManagement/index.vue

@@ -59,6 +59,8 @@
 
     <Meal v-model:model-value="modealShow" :traffIds="ids" @submit="initData()" />
     <Add v-model:model-value="visible" :type-index="typeCurrent" ref="addDetaile" @submit="initData()"></Add>
+
+    <FormSet></FormSet>
   </div>
 </template>
 
@@ -74,6 +76,8 @@ import Add from './Management/add.vue'
 import Search from '@/components/Search/index.vue'
 import { useI18n } from 'vue-i18n'
 import { Message } from '@arco-design/web-vue'
+import FormSet from '@/components/Form/index.vue'
+
 const { t } = useI18n();
 const role = useSystemStore()
 const { proxy } = getCurrentInstance()