赞
踩
用了一年多antd组件,发现需要做动态表单的场景可真不少!今天就来整理一下vue版的动态表单该如何实现吧!~效果图如下:
官方的案例如下,一行只有一个表单项且没有赋初始值。
基于官网最朴实无华的例子,做了一下延伸。封装的组件,支持一下功能:
模板的部分和样式的部分按需进行调整,js部分可以完全照搬!
<template> <div> <div class="dynamic-wrap" :style="{ maxHeight: wrapHeight + 'px' }"> <div v-for="item in keysList" :key="item"> <a-row :gutter="24"> <a-col :span="6"> <a-form-item label="名称" :labelCol="{span: 8}" :wrapperCol="{span: 16}"> <a-input placeholder="请填写名称" v-decorator="[ `${title}Name[${item}]`, { initialValue: arr[item] ? arr[item].name : undefined, rules: [{ required: true, message: '请填写名称!' }] } ]" /> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="性别" :labelCol="{span: 9}" :wrapperCol="{span: 15}"> <a-select placeholder="请选择性别" v-decorator="[ `${title}Gender[${item}]`, { initialValue: arr[item] ? arr[item].gender : 'male', rules: [{ required: true, message: '请选择性别!' }] } ]" > <a-select-option value="male">男</a-select-option> <a-select-option value="female">女</a-select-option> </a-select> </a-form-item> </a-col> <a-col :span="6"> <a-form-item label="年龄" :labelCol="{span: 8}" :wrapperCol="{span: 16}"> <a-input placeholder="请填年龄" v-decorator="[ `${title}Age[${item}]`, { initialValue: arr[item] ? arr[item].age : undefined, rules: [{ required: true, message: '请填年龄' }] } ]" /> </a-form-item> </a-col> <a-col :span="2" style="padding-left: 0px"> <a-form-item :labelCol="{span: 0}" :wrapperCol="{span: 24}"> <template v-if="keysList.length > 1"> <a-button type="dashed" icon="minus" @click="removeRow(item)" class="minusRowBtn"></a-button> </template> </a-form-item> </a-col> </a-row> </div> <a-button type="dashed" icon="plus" @click="addRow" class="addRowBtn"> 新增一行 </a-button> </div> </div> </template> <script> export default { name: 'DynamicForm', props: { title: { type: String, default: '' }, wrapHeight: { // 表单容器的高度 type: Number, default: 120 }, arr: { type: Array, default: function () { return [] } } }, data () { return { id: 0, keysList: [] } }, created () { this.form = this.$form.createForm(this) this.init() }, methods: { // 初始化 init () { const arr = [0] if (this.arr.length !== 0) { for (let i = 1; i < (this.arr).length; i++) { arr.push(i) this.id = this.id + 1 } } this.keysList = arr }, // 移除某行 removeRow (k) { if (this.keysList.length === 1) { // 如果存在可以移除所有行的情况,把条件改为this.keysList.length === 0即可 return } this.keysList = this.keysList.filter(item => item !== k) }, // 新增一行 addRow () { this.id = this.id + 1 this.keysList = this.keysList.concat(this.id) } } } </script> <style lang="less" scoped> .dynamic-wrap { padding-top: 10px; background-color: white; overflow-y: scroll; overflow-x: hidden; &::-webkit-scrollbar { width: 7px; } &::-webkit-scrollbar-thumb { background: #d8d8d8; border-radius: 10px; } &::-webkit-scrollbar-track-piece { background: transparent; } } .minusRowBtn { color: #f5222d; background: #fff1f0; border-color: #ffa39e; padding-right: 7px; padding-left: 7px; height: 29px; margin-left: 10px; } .addRowBtn { width: 70%; color: #1890ff; border-color: #91d5ff; margin: 0px 0px 20px 70px; } </style>
API
title:用于Form的字段绑定,如果多次使用了该组件,需要设置不同的值。
wrapHeight:容器的高度,超过多少px则显示滚动条
arr:数据源(如编辑场景从接口获取到的初始数据显示在表单项里)
<template> <div class="padding: 20px;"> <a-form :form="form"> <a-divider>动态表单演示 -- author by Emily</a-divider> <dynamic-form :title="`${PARTONE}`" :wrapHeight="360" :arr="arr" /> </a-form> <a-button style="margin-top: 25px;" type="primary" @click="handleSubmit"> 提交 </a-button> <div style="margin-top: 15px;">{{ param.field }}</div> </div> </template> <script> import DynamicForm from './DynamicForm' const PARTONE = 'partOne' export default { name: 'DynamicFormWrap', components: { DynamicForm }, data () { return { form: this.$form.createForm(this), arr: [ // 模拟从接口获取到的数据(如编辑场景) { name: 'Tom', age: 20, gender: 'male' }, { name: 'Emily', age: 22, gender: 'female' } ], PARTONE, param: { field: '' // 模拟接口接收的参数 } } }, methods: { // 提交 handleSubmit () { const { form: { validateFields } } = this validateFields((errors, values) => { if (!errors) { const partOneArr = []; (values[`${PARTONE}Name`]).forEach((item, index) => { const obj = { name: item, age: values[`${PARTONE}Age`][index], gender: values[`${PARTONE}Gender`][index] } partOneArr.push(obj) }) this.param.field = JSON.stringify(partOneArr) } }) } } } </script>
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。