vue element ui 表单验证规则需要从接口获取,所以rules就需要动态设置了。将自己遇到的问题和解决办法记录一下,方便后期遇到类似的问题可以直接拿来用。
使用
<template>
<div class="guidance">
<headers></headers>
<div class="guidancebody">
<div class="guidancebodyhead">
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/' }">业务办理</el-breadcrumb-item>
<el-breadcrumb-item>业务申请</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="applyTitle">
学历学位证书翻译申请单
</div>
<div class="instructions">
<div class="instructionsTitle">
<img src="../assets/tips.png" alt="">
办理须知
</div>
<div class="instructionsInfo">
<p>1.请上传毕业证书、学位证书扫描电子件;</p>
<p>2.请填写姓名、学号或班号、身份证号;</p>
</div>
</div>
<div class="formBody">
<el-form :label-position="labelPosition" label-width="80px">
<div class="formData">
<el-form-item label="办理方式">
<el-radio-group v-model="transactManner">
<el-radio :label="0">发送电子档</el-radio>
<el-radio :label="1">邮寄纸质档</el-radio>
<el-radio :label="2">现场领取</el-radio>
</el-radio-group>
</el-form-item>
</div>
</el-form>
</div>
<div class="formBody classFormBody">
<div class="formData noborder">
<div class="maxTitle">基本信息</div>
</div>
<div class="formBodyInner">
<vform class="formBodyInnerItem" :item="item" v-for="(item,index) in applyForms"
:key="index" :ref="'vform'+index"></vform>
</div>
</div>
<div v-if="transactManner===1" class="formBody classFormBody">
<el-form :label-position="labelPosition" label-width="80px">
<el-form-item label="邮寄地址" class="w100x mr0">
<el-input placeholder="请输入" v-model="mailAddress"></el-input>
</el-form-item>
</el-form>
</div>
<div class="formBody classFormBody">
<div class="formData noborder">
<div class="maxTitle">材料信息</div>
</div>
<div class="tablelist">
<el-table
:data="applyCosts"
highlight-current-row
stripe
border
style="width: 100%">
<el-table-column
prop="costName"
align="center"
width="100"
show-overflow-tooltip
label="材料名称">
</el-table-column>
<el-table-column
prop="baseCount"
label="办理份数"
show-overflow-tooltip
align="left">
<template slot-scope="scope">
<el-input-number :min="scope.row.minTransactCount" controls-position="right" v-model="scope.row.number"
:max="scope.row.maxTransactCount"></el-input-number>
</template>
</el-table-column>
<el-table-column
prop="name"
show-overflow-tooltip
label="总价(元)"
align="left">
<template slot-scope="scope">
<totalPrice :totalPrice.sync="scope.row.totalPrice" :row="scope.row"></totalPrice>
</template>
</el-table-column>
<el-table-column
prop="remark"
show-overflow-tooltip
label="备注"
align="left">
</el-table-column>
</el-table>
<div class="combined">
<p>合计:<span>{{ heji }}元</span></p>
</div>
</div>
</div>
<div class="formBody">
<el-form :label-position="labelPosition" label-width="80px">
<el-form-item label="请上传以下证明材料">
<uploadFile></uploadFile>
</el-form-item>
<el-form-item label="留言信息">
<el-input placeholder="请输入" type="textarea" v-model="remark"></el-input>
</el-form-item>
</el-form>
</div>
<div class="next">
<div class="nextBut" @click="saveData">
下一步
</div>
</div>
</div>
<footers></footers>
</div>
</template>
<script>
import headers from "@/components/header";
import footers from "@/components/footer";
import {getFormAndCost, transactSave} from "@/api/api/user";
import uploadFile from "@/components/uploadFile";
import totalPrice from "@/views/TotalPrice";
import vform from "@/views/apple/vform";
export default {
name: "home",
components: {headers, footers, uploadFile, totalPrice, vform},
props: {
id: {
type: String,
default() {
return ''
}
}
},
data() {
return {
list: [],
labelPosition: 'top',
businessId: this.$route.query.businessId,
applyCosts: [],
applyForms: [],
remark: '',
mailAddress: '',
transactManner: 0
}
},
watch: {},
mounted() {
new this.$wow.WOW().init()
this.getData()
},
// 合计
computed: {
heji() {
var list = this.applyCosts
var heji = 0
list.forEach((type) => {
heji = heji + type.totalPrice
});
return heji
}
},
methods: {
getData() {
var that = this
getFormAndCost({businessId: this.businessId, transactManner: 0}).then((res) => {
if (res.code == 1) {
that.applyForms = res.data.applyForms
that.applyCosts = []
var list = res.data.applyCosts
list.forEach((type) => {
var data = {
applyCost: type.applyCost,
number: 1,
totalPrice: 0,
baseCount: type.baseCount,
basePrice: type.basePrice,
costCode: type.costCode,
costInformation: type.costInformation,
costName: type.costName,
createDate: type.createDate,
createUserId: type.createUserId,
id: type.id,
isCost: type.isCost,
lastOperateUserId: type.lastOperateUserId,
maxTransactCount: type.maxTransactCount,
minTransactCount: type.minTransactCount,
pid: type.pid,
remark: type.remark,
removeDate: type.removeDate,
restoreDate: type.restoreDate,
scopes: type.scopes,
state: type.state,
unitPrice: type.unitPrice,
updateDate: type.updateDate,
version: type.version,
}
that.applyCosts.push(data)
});
}
})
},
goback() {
this.$router.go(-1)
},
// 保存
saveData() {
var that = this
var applyCosts = []
that.applyCosts.forEach((type) => {
var data = {
costName: type.costName,
costCode: type.costCode,
costCount: type.number,
totalPrice: type.totalPrice
}
applyCosts.push(data)
});
var applyBaseInfo = {}
// 校验数据
try {
var check = true
that.applyForms.forEach((type, index) => {
if (type.fieldValue) {
applyBaseInfo[type.id] = type.fieldValue
}
if (!that.$refs[`vform${index}`][0].submitForm('ruleForm')) {
check = false
}
});
} catch (e) {
console.log(e)
}
console.log(check)
if (!check) {
return
}
// 校验数据
that.applyForms.forEach((type, index) => {
applyBaseInfo[type.id] = that.$refs[`vform${index}`][0].getFormData() + ''
});
transactSave({
businessId: that.businessId,
transactManner: that.transactManner,
mailAddress: that.mailAddress,
applyFileIds: that.applyFileIds,
applyBaseInfo: applyBaseInfo,
applyCosts: applyCosts,
remark: that.remark
}).then((res) => {
if (res.code == 1) {
that.$message({
message: '提交成功',
type: 'success'
});
that.goback()
}
}
)
}
}
}
</script>
<style lang="scss" scoped>
.guidance {
background: #F4F5F8;
min-height: 100%;
padding-top: 24px;
padding-bottom: 50px;
width: 100%;
}
.guidancebodyhead {
width: 1144px;
margin: 0 auto;
height: 69px;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
border-bottom: 1px solid rgba(238, 238, 238, 1);
span {
font-size: 14px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 400;
}
::v-deep {
.el-breadcrumb__inner a, .el-breadcrumb__inner.is-link {
font-weight: 400;
}
}
}
.guidancebody {
width: 1200px;
position: relative;
background: #FFFFFF;
box-shadow: 0px 11px 58px 0px rgba(121, 129, 140, 0.06);
border-radius: 16px;
margin: 25px auto 16px auto;
}
.applyTitle {
height: 72px;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
margin-left: 28px;
align-content: flex-start;
font-size: 22px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.85);
}
.instructions {
background: rgba(#3379EF, 0.05);
border-radius: 4px;
margin: auto;
margin-left: 28px;
margin-right: 28px;
min-height: 100px;
padding: 20px;
.instructionsTitle {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
margin-bottom: 10px;
img {
width: 18px;
margin-right: 3px;
}
}
.instructionsInfo {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: rgba(0, 0, 0, 0.65);
line-height: 30px;
}
}
.next {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
.nextBut {
width: 320px;
height: 48px;
cursor: pointer;
background: #3379EF;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
font-size: 14px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #FFFFFF;
margin-top: 50px;
margin-bottom: 30px;
}
}
.formBody {
margin-left: 28px;
margin-right: 28px;
.formData {
width: 100%;
border-bottom: 1px solid rgba(238, 238, 238, 1);
}
}
.maxTitle {
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.85);
padding-top: 20px;
padding-bottom: 20px;
}
.classFormBody {
::v-deep {
.el-form {
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
flex-direction: row;
align-content: flex-start;
}
}
}
.combined {
border: 1px solid #F0F0F0;
border-top: 0;
height: 61px;
display: flex;
justify-content: flex-end;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
padding-right: 22px;
p {
color: rgba(106, 106, 106, 1);
span {
color: rgba(255, 65, 63, 1);
}
}
}
.formBodyInner {
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
flex-direction: row;
align-content: flex-start;
.formBodyInnerItem {
width: 33.33%;
}
}
</style>
组件
/**
* @Author: 858834013@qq.com
* @Name: vform
* @Date: 2022-05-30
* @Desc: 表单验证 vfor
*/
<template>
<div class="elForm">
<el-form v-if="show" :model="applyForm" :rules="rules" ref="ruleForm" label-position="top" label-width="80px">
<el-form-item :label="item.fieldName" prop="value">
<!-- 没有枚举值-->
<el-input v-if="item.isEnumeration==0" placeholder="请输入" v-model="applyForm.value"></el-input>
<!-- 有枚举值 下拉选择-->
<el-select class="w100x" v-model="applyForm.value" :multiple="item.isMulti?true:false"
v-if="item.isEnumeration==1"
placeholder="请选择">
<el-option
v-for="items in enumerationValue"
:key="items"
:label="items"
:value="items">
</el-option>
</el-select>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: "vform",
components: {},
props: {
item: {
type: Object,
default() {
return ''
}
}
},
data() {
return {
show: false,
enumerationValue: [],
rules: {
value: []
},
applyForm: {
value: ''
}
}
},
watch: {
item: {
handler(newVal) {
this.getdata()
},
deep: true
},
},
mounted() {
this.getdata()
},
methods: {
submitForm(formName) {
var that = this;
var data = false
that.$refs[formName].validate((valid) => {
if (valid) {
data = true
} else {
console.log('error submit!!');
data = false
}
});
return data
},
getFormData() {
return this.applyForm.value
},
getdata() {
var that = this;
that.show = false
// 如果有枚举值
if (that.item.enumerationValue) {
that.enumerationValue = that.item.enumerationValue.split(",")
}
// 校验规则
that.rules.value = []
// 必填校验
if (that.item.isMust && !that.item.isEnumeration) {
var rule = {required: true, message: '请输入' + that.item.fieldName}
that.rules.value.push(rule)
}
// 长度校验
if (that.item.minCharacterCount && that.item.maxCharacterCount) {
var rule = {
min: that.item.minCharacterCount,
max: that.item.maxCharacterCount,
message: '长度在 ' + that.item.minCharacterCount + ' 到 ' + that.item.maxCharacterCount + ' 个字符',
trigger: 'blur'
}
that.rules.value.push(rule)
}
if (that.item.minCharacterCount && !that.item.maxCharacterCount) {
var rule = {
min: that.item.minCharacterCount,
message: '长度不能小于 ' + that.item.minCharacterCount + ' 个字符',
trigger: 'blur'
}
that.rules.value.push(rule)
}
if (!that.item.minCharacterCount && that.item.maxCharacterCount) {
var rule = {
min: that.item.maxCharacterCount,
message: '长度不能大于 ' + that.item.maxCharacterCount + ' 个字符',
trigger: 'blur'
}
that.rules.value.push(rule)
}
that.$nextTick(() => {
that.show = true
})
}
}
}
</script>
<style lang="scss" scoped>
.elForm {
width: 100%;
.el-form-item {
width: calc(100% - 60px);
margin-right: 60px;
}
}
</style>