vue复杂表单需求的实现改进

259 阅读3分钟

萌新版

<el-form>
    <el-form-item v-if="">
        <el-input/>
    </el-form-item>
    <el-form-item v-else-if="">
        <el-select/>
    </el-form-item>
    ....若干条件
    <el-form-item v-else="">
        <el-radio/>
    </el-form-item>
</el-form>

优点: 直观,能实现灵活的布局,能实现复杂的表单项

缺点: 逻辑一旦复杂多变起来,会像机房里混杂在一起的网线,剪不断理还乱。

萌新优化版

<template>
    <el-form>
        <template v-for="item in itemArr">
            <template v-if="是否渲染">
                <el-form-item>
                    <complex-input></complex-input>
                </el-form-item>
            </template>
        </template>
    </el-form>
<template>
<script setup>
const itemArr = ref([表单项配置])
</script>

将所有的表单项组件,封装到一个组件中complex-input,在这一个组件中,实现不同判断渲染不同组件

优点:

缺点:

  1. 和萌新版一样,只是将代码逻辑从主文件,转移到了complex-input组件
  2. 无法实现灵活布局

错误演化版

<template>
    <el-form>
        <template v-for="item">
            <template v-if="是否渲染">
                <el-form-item>
                    <markErrorComp>
                        <component is=""></component>
                    </markErrorComp>
                </el-form-item>
            </template>
        </template>
    </el-form>
</template>
<script setup>
const itemArr = ref([表单项配置])
</script>

优点: 将表单项的逻辑从主文件分离出来了

缺点:

  1. 这种方式,原本是为了复用markErrorComp,但造成的结果是, markErrorComp组件难以扩展,并且markErrorComp中难以处理select这类组件的显示值
  2. 无法实现灵活的布局,对于复杂布局,可能需要多表单组合使用

正确演化版

<template>
    <el-form>
        <template v-for="item">
            <template v-if="是否渲染">
                <el-form-item>
                    <component v-if="纯显示" is=""></component>
                    <component v-else is=""></component>
                </el-form-item>
            </template>
        </template>
    </el-form>
</template>
<script setup>
const itemArr = ref([表单项配置])
</script>

优点: 将表单项的逻辑从主文件分离出来了,并且不同状态可以使用不同的自定义组件

缺点: 无法实现灵活的布局,对于复杂布局,可能需要多表单组合使用

布局优化改进版

<template>
    <el-form>
        <template v-for="item">
            <template v-if="item是一个包装项">
                <div class="wrapper" v-if="包装项是否需要渲染">
                    <!-- 包装项的children是真正的表单项配置,遍历children渲染 -->
                    <template v-for="item.children">
                        <template v-if="child item是否渲染">
                            <el-form-item>
                                <component v-if="纯显示" is=""></component>
                                <component v-else is=""></component>
                            </el-form-item>
                        </template>
                    </template>
                </div>
            </template>
            <template v-else>
                <!-- item是一个普通表单项 -->
                <template v-if="item是否渲染">
                    <el-form-item>
                        <component v-if="纯显示" is=""></component>
                        <component v-else is=""></component>
                    </el-form-item>
                </template>
            </template>
        </template>
    </el-form>
</template>
<script setup>
const itemArr = ref([表单项配置])
</script>

优点:

  1. 将表单项的逻辑从主文件分离出来了,并且不同状态可以使用不同的自定义组件
  2. 可以实现相对灵活的布局

缺点: 无法实现复杂表单项(如单值数组,数组对象,table)

复杂表单项改进版

<template>
    <el-form>
        <template v-for="item">
            <template v-if="item是一个包装项">
                <div class="wrapper" v-if="包装项需要渲染">
                    <!-- 包装项的children是真正的表单项配置,遍历children渲染 -->
                    <template v-for="item.children">
                        <el-form-item-wrapper></el-form-item-wrapper>
                    </template>
                </div>
            </template>
            <template v-else>
                <!-- item是一个表单项 -->
                <el-form-item-wrapper></el-form-item-wrapper>
            </template>
        </template>
    </el-form>
</template>
<script setup>
const itemArr = ref([表单项配置])
</script>

el-form-item-wrapper.vue

<template v-if="非嵌套表单项">
    <template v-if="是否需要渲染">
        <el-form-item :prop="复杂判断设置prop值">
            <component v-if="纯显示" is=""></component>
            <component v-else is=""></component>
        </el-form-item>
    </template>
</template>
<template v-else-if="是嵌套表单项">
    <template v-else-if="是嵌套表单项">
        <template v-form="childItem in item.chilren">
            <el-form-item-wrapper></el-form-item-wrapper>
        </template>
    </template>
</template>

优点:

  1. 将表单项的逻辑从主文件分离出来了,并且不同状态可以使用不同的自定义组件
  2. 可以实现相对灵活的布局
  3. 可以实现复杂表单项(如单值数组,数组对象,table)

缺点: 表单写法有点绕,但只要有人讲解一遍,那新接手的人,应该能很快理解原理