<template>
<div class="form">
<yu-form
ref="yuForm"
:basic-purchase-desc="basicPurchaseDesc"
:purchasing-information="purchasingInformation"
:is-show-add-btn="true"
@removeInquiry="removeInquiry"
@addInquiry="addInquiry"
/>
<el-button @click="next">提交</el-button>
</div>
</template>
<script>
import YuForm from './components/yuForm'
import {
basicPurchaseDesc,
purchasingInformation,
addStockOrder
} from './helper'
export default {
components: {
YuForm
},
data() {
return {
basicPurchaseDesc: basicPurchaseDesc(), // elm基础表单描述
purchasingInformation: purchasingInformation() // 采购表单信息数据
}
},
methods: {
// 调用ele-form内部校验,和封装yu-form表单校验
next() {
// 校验采购表单
this.$refs.yuForm.validate((valid) => {
// 校验eleForm表单
if (valid) {
console.log(this.purchasingInformation)
}
})
},
// 添加操作
addInquiry() {
// 添加表单
this.purchasingInformation.push({
material: '', // 物料名称
brand: '', // 品牌
specification: '', // 规格/型号
amount: '', // 采购量
unit: '', // 单位
remark: '' // 备注
})
// 向采购中添加描述渲染另一个表单
this.basicPurchaseDesc.push(addStockOrder())
},
// 删除操作
removeInquiry(formIndex) {
// 判断数据是否有多条
if (this.purchasingInformation.length > 1) {
// 把基础数据中的purchasingInformation的数组当前下标删除
this.purchasingInformation.splice(formIndex, 1)
// 向采购中删除当前下标描述
this.basicPurchaseDesc.splice(formIndex, 1)
this.$message({
message: '删除成功',
type: 'success'
})
} else {
this.$message({
message: '只剩一条了',
type: 'error'
})
}
}
}
}
</script>
// yu-form添加采购表单字段
const addStockOrder = () => {
return {
material: {
type: 'input',
field: 'material',
label: '物料名称',
rules: { required: true, message: '请输入物料信息', trigger: 'blur' }
},
brand: {
type: 'input',
field: 'brand',
label: '品牌',
rules: { required: true, message: '请输入品牌', trigger: 'blur' }
},
specification: {
type: 'input',
field: 'specification',
label: '规格/型号',
rules: { required: true, message: '请输入规格型号', trigger: 'blur' }
},
amount: {
type: 'input',
field: 'amount',
label: '采购量',
rules: { required: true, message: '请输入采购量', trigger: 'blur' }
},
unit: {
type: 'select',
field: 'unit',
label: '单位',
rules: { required: true, message: '请选择单位', trigger: 'change' },
options: [
{
label: '吨',
value: 0
},
{
label: '米',
value: 1
},
{
label: '件',
value: 2
}
]
},
remark: {
type: 'input',
label: '备注'
}
}
}
// 采购表单数据
const purchasingInformation = () => {
return [ // 采购信息
{
material: '', // 物料名称
brand: '', // 品牌
specification: '', // 规格/型号
amount: '', // 采购量
unit: '', // 单位
remark: '' // 备注
}
]
}
// 基础采购描述
const basicPurchaseDesc = () => {
return [{
material: {
type: 'input',
field: 'material',
label: '物料名称',
rules: { required: true, message: '请输入物料信息', trigger: 'blur' }
},
brand: {
type: 'input',
field: 'brand',
label: '品牌',
rules: { required: true, message: '请输入品牌', trigger: 'blur' }
},
specification: {
type: 'input',
field: 'specification',
label: '规格/型号',
rules: { required: true, message: '请输入规格型号', trigger: 'blur' }
},
amount: {
type: 'input',
field: 'amount',
label: '采购量',
rules: { required: true, message: '请输入采购量', trigger: 'blur' }
},
unit: {
type: 'select',
field: 'unit',
label: '单位',
rules: { required: true, message: '请选择单位', trigger: 'change' },
options: [
{
label: '吨',
value: 0
},
{
label: '米',
value: 1
},
{
label: '件',
value: 2
}
]
},
remark: {
type: 'input',
label: '备注'
}
}]
}
export {
basicPurchaseDesc,
addStockOrder,
purchasingInformation
}
<template>
<div class="yu-form">
<div class="add-inquiry-btn">
<el-button v-if="isShowAddBtn" @click="addInquiry">添加询价单</el-button>
</div>
<transition-group class="content" tag="form" name="fade-list">
<el-form
v-for="(formInfo, formIndex) in basicPurchaseDesc"
ref="rulesForm"
:key="formIndex"
:inline="true"
:model="purchasingInformation[formIndex]"
label-position="top"
>
<el-form-item
v-for="(info, infoIndex) in formInfo"
:key="info.field"
:label="info.label"
:prop="infoIndex"
:rules="info.rules"
>
<el-input
v-if="info.type === 'input'"
v-model="purchasingInformation[formIndex][infoIndex]"
:placeholder="'请输入'+info.label"
/>
<el-select
v-else
v-model="purchasingInformation[formIndex][infoIndex]"
:placeholder="'请选择'+info.label"
>
<el-option
v-for="option in info.options"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
<el-form-item class="delete">
<el-button type="danger" @click="removeInquiry(formIndex)">删除</el-button>
</el-form-item>
</el-form>
</transition-group>
</div>
</template>
<script>
// 对el-form二次封装
export default {
name: 'YuForm',
props: {
// 多组校验
basicPurchaseRules: {
type: Array,
default() {
return []
}
},
// 基础信息描述
basicPurchaseDesc: {
type: Array,
default() {
return []
}
},
// 基础数据
purchasingInformation: {
type: Array,
default() {
return {}
}
},
isShowAddBtn: {
type: Boolean,
default: false
}
},
data() {
return {
isValidate: null
}
},
methods: {
// 删除对应表单
removeInquiry(formIndex) {
this.$emit('removeInquiry', formIndex)
},
// 校验表单
validate(cb) {
this.isValidate = null
this.purchasingInformation.forEach((item, index) => {
this.$refs['rulesForm'][index].validate((valid) => {
this.isValidate += valid
if (this.purchasingInformation.length === this.isValidate) {
cb(valid)
}
})
})
},
// 添加询价单
addInquiry() {
this.$emit('addInquiry')
}
}
}
</script>
<style scoped lang="scss">
.add-inquiry-btn {
margin: 20px 0;
}
.delete {
margin: 0;
::v-deep .el-form-item__content {
height: 125px;
display: flex;
flex-direction: column;
justify-content: space-around;
}
}
.fade-list-enter-active {
opacity: 0;
transform: translateY(100%);
transition: all .6s;
}
.fade-list-enter-to {
opacity: 1;
transform: translateY(0);
}
.fade-list-leave-to {
opacity: 0;
transform: translateY(0);
transition: all .6s;
}
</style>
首先对el-form使用v-for指令对basicPurchaseDesc数组进行循环,这个basicPurchaseDesc中的数据格式我会放在下方,这下方的这个格式是个数组对象,默认只有一条数据,当使用v-for对其循环时,会渲染出一个表单。我们再看内层的el-form-item,这里也是使用v-for对el-form遍历的之后的数据在进行遍历,(v-for不仅仅可以遍历数组也遍历对象,遍历对象的时候第一个值是返回的当前对象,第二个值就是当前对象的键),遍历之后可以通过type来判断是input还是select(我这里之处理了两种),这里的数据包括了校验规则。
// 表单描述信息
[{
material: {
type: 'input',
field: 'material',
label: '物料名称',
rules: { required: true, message: '请输入物料信息', trigger: 'blur' }
},
brand: {
type: 'input',
field: 'brand',
label: '品牌',
rules: { required: true, message: '请输入品牌', trigger: 'blur' }
},
specification: {
type: 'input',
field: 'specification',
label: '规格/型号',
rules: { required: true, message: '请输入规格型号', trigger: 'blur' }
},
amount: {
type: 'input',
field: 'amount',
label: '采购量',
rules: { required: true, message: '请输入采购量', trigger: 'blur' }
},
unit: {
type: 'select',
field: 'unit',
label: '单位',
rules: { required: true, message: '请选择单位', trigger: 'change' },
options: [
{
label: '吨',
value: 0
},
{
label: '米',
value: 1
},
{
label: '件',
value: 2
}
]
},
remark: {
type: 'input',
label: '备注'
}
}]
在下面就是说purchasingInformation这个保存数据的问题,这个数据也是一个数组对象格式的,el-form和el-form-item中的mode就是绑定这个数据el-form通过遍历的返回的formIndex下标
<el-form
v-for="(formInfo, formIndex) in basicPurchaseDesc"
ref="rulesForm"
:key="formIndex"
:inline="true"
:model="purchasingInformation[formIndex]"
label-position="top"
>el-form>
// purchasingInformation数组内容
[ // 采购信息
{
material: '', // 物料名称
brand: '', // 品牌
specification: '', // 规格/型号
amount: '', // 采购量
unit: '', // 单位
remark: '' // 备注
}
]
<el-form-item
v-for="(info, infoIndex) in formInfo"
:key="infoIndex"
:label="info.label"
:prop="infoIndex"
:rules="info.rules"
>
<el-input
v-if="info.type === 'input'"
v-model="purchasingInformation[formIndex][infoIndex]"
:placeholder="'请输入'+info.label"
/>
<el-select
v-else
v-model="purchasingInformation[formIndex][infoIndex]"
:placeholder="'请选择'+info.label"
>
<el-option
v-for="option in info.options"
:key="option.value"
:label="option.label"
:value="option.value"
/>
el-select>
el-form-item>
<el-form-item class="delete">
<el-button type="danger" @click="removeInquiry(formIndex)">删除el-button>
el-form-item>
下面这些是逻辑这块的yuForm.vue
<script>
// 对el-form二次封装
export default {
name: 'YuForm',
// 这里的数据是接收父组件传递的数据
props: {
// 基础信息描述
basicPurchaseDesc: {
type: Array,
default() {
return []
}
},
// 基础数据
purchasingInformation: {
type: Array,
default() {
return {}
}
},
// 是否显示添加按钮
isShowAddBtn: {
type: Boolean,
default: false
}
},
data() {
return {
isValidate: null
}
},
methods: {
// 删除对应表单
removeInquiry(formIndex) {
this.$emit('removeInquiry', formIndex)
},
// 校验表单
validate(cb) {
this.isValidate = null
// 由于有多个表单需要进行校验所以直接遍历数据让来校验是否有没有填写的字段
this.purchasingInformation.forEach((item, index) => {
this.$refs['rulesForm'][index].validate((valid) => {
// vaild这个返回的数据如果当前index下标的表单有校验字段的内容为空就会返回false反之true,
// 这里通过这个来进行累加判断如果返回的有一个是false都是校验不通过
this.isValidate += valid
if (this.purchasingInformation.length === this.isValidate) {
// 如果都是所有的字段都填写了这时候通过校验callback返回给父组件处理
cb(valid)
}
})
})
},
// 添加询价单
addInquiry() {
this.$emit('addInquiry')
}
}
}
</script>
<template>
<div class="form">
<yu-form
ref="yuForm"
:basic-purchase-desc="basicPurchaseDesc"
:purchasing-information="purchasingInformation"
:is-show-add-btn="true"
@removeInquiry="removeInquiry"
@addInquiry="addInquiry"
/>
<el-button @click="next">提交el-button>
div>
template>
<script>
// 使用封装的组件
import YuForm from './components/yuForm'
// 从./hepler.js导出所需要的数据
import {
basicPurchaseDesc,
purchasingInformation,
addStockOrder
} from './helper'
export default {
components: {
YuForm
},
data() {
return {
basicPurchaseDesc: basicPurchaseDesc(), // elm基础表单描述
purchasingInformation: purchasingInformation() // 采购表单信息数据
}
},
methods: {
// 调用ele-form内部校验,和封装yu-form表单校验
next() {
// 校验采购表单
this.$refs.yuForm.validate((valid) => {
// 校验eleForm表单
if (valid) {
console.log(this.purchasingInformation)
}
})
},
// 添加操作
addInquiry() {
// 添加表单
this.purchasingInformation.push({
material: '', // 物料名称
brand: '', // 品牌
specification: '', // 规格/型号
amount: '', // 采购量
unit: '', // 单位
remark: '' // 备注
})
// 向采购中添加描述渲染另一个表单
this.basicPurchaseDesc.push(addStockOrder())
},
// 删除操作
removeInquiry(formIndex) {
// 判断数据是否有多条
if (this.purchasingInformation.length > 1) {
// 把基础数据中的purchasingInformation的数组当前下标删除
this.purchasingInformation.splice(formIndex, 1)
// 向采购中删除当前下标描述
this.basicPurchaseDesc.splice(formIndex, 1)
this.$message({
message: '删除成功',
type: 'success'
})
} else {
this.$message({
message: '只剩一条了',
type: 'error'
})
}
}
}
}
script>