1.表单校验数组对象的方法
使用 elementUI的表单,在数据为对象嵌套数组对象时检验内部对象为必填项时应该这样写
data(){
form: {
name:'sznal',
age:18,
List: [{ a: "", b: "", c: "" }],
},
}
<el-form-item
:label="'姓名:'"
:prop="`List[${index}].name`" //重点
:rules="rules.name"
>
<el-input
v-model="item.name"
clearable
filterable
class="form-item-box"
>
</el-input>
</el-form-item>
:prop="`List[${index}].name`"
prop前加冒号(:) 等号后面,引号内使用 ` ` 拼接 加上[${index}]
rules这样写
rules:{
name: [
{
required: true,
message: "不能为空",
trigger: "blur",
},
],
age: [
{
required: true,
message: "不能为空",
trigger: "blur",
},
],
a: [
{
required: true,
message: "不能为空",
trigger: "blur",
},
],
b: [
{
required: true,
message: "不能为空",
trigger: "blur",
},
],
}
2.表单嵌套表格必填校验
在form表单中添加table,并在table中添加一列输入框,对输入框进行校验,已勾选才进行校验,未勾选的不进行校验
<template>
<div>
<el-form
ref="formData"
:model="form"
:rules="rules"
label-width="80px"
label-position="top"
>
<div v-if="isShowPage === 'batchExchange'">
<blockTitle
:title="$t('shoppingCart.selectMatchOrgMarket')"
:color="'blue'"
/>
<el-row :gutter="30">
<el-col :xs="8" :sm="8" :md="6" :lg="6">
<el-form-item :label="$t('shoppingCart.targetOrg')" prop="orgCode">
<el-select
v-model="form.orgCode"
:placeholder="$t('common.select')"
clearable
filterable
@change="setMarketCodeSelect"
class="form-item-box"
>
<el-option
v-for="item in initData.OrgSelect"
:key="item.labelValue"
:label="item.labelText"
:value="item.labelValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="8" :sm="8" :md="6" :lg="6">
<el-form-item
:label="$t('shoppingCart.targetMarket')"
prop="marketCode"
>
<el-select
v-model="form.marketCode"
:placeholder="$t('common.select')"
clearable
filterable
class="form-item-box"
>
<el-option
v-for="item in initData.MarketSelect"
:key="item.labelValue"
:label="item.labelText"
:value="item.labelValue"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</div>
<blockTitle :title="$t('shoppingCart.selectCart')" :color="'blue'" />
<div>
<el-row :gutter="30">
<el-col :xs="8" :sm="8" :md="6" :lg="6">
<el-input
v-model.number="queryParams.deviceNum"
:placeholder="$t('shoppingCart.deviceNum')"
clearable
:maxlength="5"
class="form-item-box"
/>
</el-col>
<el-col :xs="8" :sm="8" :md="6" :lg="6">
<MaskedInput
class="form-item-box wifi"
v-model="queryParams.authCode"
mask="##:##:##:##:##:##"
placeholder="WifiMac"
/>
</el-col>
<div class="SearchResetBtn">
<el-button class="btn_purple" @click="getChooseDeviceList">
{{ this.$t('system.search') }}
</el-button>
<el-button class="btn_noColor" @click="resetChooseDeviceList">
{{ this.$t('system.reset') }}
</el-button>
</div>
</el-row>
</div>
<el-table
v-if="
(this.form.marketCode !== undefined && this.form.marketCode !== '') ||
this.isShowPage === 'statusChange'
"
:data="form.cartList"
style="width: 100%"
@selection-change="handleSelectionChange"
height="350px"
ref="tableRef"
@row-click="handleRowClick"
>
<el-table-column type="selection" width="50" align="center" />
<template
v-for="(item, index) in isShowPage === 'statusChange'
? statusChangeColumns
: batchExchangeColumns"
>
<el-table-column
:key="index"
:index="index"
:label="item.label"
:align="'center'"
min-width="155"
:prop="item.code"
:show-overflow-tooltip="true"
>
<template slot-scope="scope">
<template v-if="item.render">
<span>
<RenderDom
:row="scope.row"
:index="index"
:render="item.render"
/>
</span>
</template>
<template v-else-if="item.code === 'matchCartNum'">
<el-form-item
class="matchNumItem"
:prop="
scope.row.flag == true
? 'cartList.' + scope.$index + '.matchCartNum'
: 'aa'
"
:rules="scope.row.flag == true ? rules.matchCartNum : 'aa'"
>
<el-input
maxlength="5"
v-model="scope.row.matchCartNum"
:placeholder="$t('common.input')"
:disabled="scope.row.flag == true ? false : true"
:key="scope.row.index"
></el-input>
</el-form-item>
</template>
<!-- 启用状态 -->
<template v-else-if="item.code === 'status'">
<div class="statusFlex">
<div
:class="[
'statusCircle',
{ statusCirclePurple: scope.row[item.code] === '0' },
{ statusCircleGray: scope.row[item.code] === '1' },
]"
></div>
<span v-if="scope.row[item.code] === '0'">
{{ $t('system.enable') }}
</span>
<span v-else-if="scope.row[item.code] === '1'">
{{ $t('system.disable') }}
</span>
<span v-else>-</span>
</div>
</template>
<template v-else>
<span>{{ scope.row[item.code] }}</span>
</template>
</template>
</el-table-column>
</template>
</el-table>
</el-form>
<div class="selectedText">
{{ $t('shoppingCart.selectedCartNum', [form.ids.length]) }}
</div>
</div>
</template>
<script>
import { getOrgSelect, getMarketSelect } from '@/api/common/common';
import {
chooseDeviceList,
batchChangeStatus,
batchExchange, //批量调拨
beforeBatchExchange, //调拨前的验证
} from '@/api/cart/deviceCart.js';
import { validNum } from '@/utils/validate';
export default {
name: 'statusChange',
dicts: [],
components: {},
data() {
const validCartNum = async (rule, value, callback) => {
if (value !== undefined && value !== '' && !validNum(value)) {
callback(new Error(window.vm.$i18n.t('validate.positive_number')));
} else {
// 补足5位
if (
(this.form.cartList[this.rowData.index].matchCartNum + '').length < 5
) {
const num =
5 -
(this.form.cartList[this.rowData.index].matchCartNum + '').length;
let element = '';
for (let j = 0; j < num; j++) {
element += 0;
}
this.form.cartList[this.rowData.index].matchCartNum =
element + this.form.cartList[this.rowData.index].matchCartNum;
}
// 将已填写的目标车辆编号放入数组
this.matchCartNumList = [];
this.form.cartList.forEach((item) => {
if (item.matchCartNum) {
this.matchCartNumList.push(item.matchCartNum);
}
});
// 判断本地列表中是否有重复车辆编号 -true 有重复 -false 无重复
function hasDuplicates(array) {
return new Set(array).size !== array.length;
}
let repeat = hasDuplicates(this.matchCartNumList);
if (repeat) {
console.log('check:', hasDuplicates(this.matchCartNumList)); // 输出 true
return callback(
new Error(
this.$t('shoppingCart.cartSn') +
'-列表' +
this.$t('validate.exists')
)
);
} else {
console.log('res-check');
let data = {
orgCode: this.form.orgCode,
marketCode: this.form.marketCode,
chooseList: [
{
deviceId: this.rowData.deviceId,
deviceNum: this.rowData.matchCartNum,
},
],
};
await beforeBatchExchange(data).then((response) => {
if (response.code === 200) {
if (response.data.existDevice !== null) {
return callback(
new Error(
this.$t('shoppingCart.cartSn') + this.$t('validate.exists')
)
);
}
}
});
}
}
};
return {
matchCartNumList: [], //已选择的车辆
rowData: undefined, //点击行数据
form: {
ids: [],
orgCode: undefined,
marketCode: undefined,
cartList: [],
},
initData: {
OrgSelect: [], // 所属超市
MarketSelect: [], // 所属门店
},
queryParams: {
orgCode: undefined,
marketCode: undefined,
deviceNum: undefined,
authCode: undefined,
},
statusChangeColumns: [
{
label: this.$t('common.marketCode'),
code: `marketName`,
visible: true,
},
{
label: this.$t('shoppingCart.deviceNum'),
code: `deviceNum`,
visible: true,
},
{
label: this.$t('common.authCode'),
code: `authCode`,
visible: true,
},
],
batchExchangeColumns: [
{
label: this.$t('shoppingCart.deviceNum'),
code: `matchCartNum`,
visible: true,
},
{
label: this.$t('shoppingCart.oldDeviceNum'),
code: `deviceNum`,
visible: true,
},
{
label: this.$t('shoppingCart.deviceNum'),
code: `deviceNum`,
visible: true,
},
{
label: this.$t('common.authCode'),
code: `authCode`,
visible: true,
},
{
label: this.$t('common.enableStatus'),
code: `status`,
visible: true,
},
{
label: this.$t('common.marketCode'),
code: `marketName`,
visible: true,
},
],
rules: {
orgCode: [
{
required: true,
message: this.$t('validate.required', {
field: this.$t('common.orgCode'),
}),
trigger: 'change',
},
],
marketCode: [
{
required: true,
message: this.$t('validate.required', {
field: this.$t('common.marketCode'),
}),
trigger: 'change',
},
],
matchCartNum: [
{
required: true,
message: this.$t('validate.required', {
field: this.$t('shoppingCart.deviceNum'),
}),
trigger: 'blur',
},
{ validator: validCartNum, trigger: 'blur' },
],
},
};
},
watch: {},
props: {
isShowPage: {
type: String,
},
status: {
type: Number,
},
},
created() {
let cache = JSON.parse(window.localStorage.getItem('queryParams'));
this.queryParams.orgCode = cache.orgCode;
this.queryParams.marketCode = cache.marketCode;
this.getOrgSelect();
this.getChooseDeviceList();
},
mounted() {},
methods: {
// 获取车辆列表
getChooseDeviceList() {
this.form.cartList = [];
chooseDeviceList(this.queryParams).then((res) => {
if (res.code == 200) {
this.form.cartList = res.data.map((item, index) => {
return { ...item, flag: false, index: index };
});
// this.$refs.tableRef.toggleAllSelection();
}
});
},
// 车辆搜索重置
resetChooseDeviceList() {
this.queryParams.deviceNum = undefined;
this.queryParams.authCode = undefined;
this.getChooseDeviceList();
},
// 复选框操作
handleSelectionChange(selection) {
if (this.isShowPage === 'statusChange') {
this.form.ids = selection.map((item) => item.id);
} else if (this.isShowPage === 'batchChange') {
this.form.ids = selection.map((item) => item.deviceId);
}
// 选中的行flag-> true,未未选中的行flag-> false
const idsInB = new Set(this.form.ids);
this.form.cartList.forEach((item) => {
item.flag = idsInB.has(item.deviceId);
});
},
// 禁用启用-提交
handleStatusChangeConfirm() {
let data = {
marketCode: this.queryParams.marketCode,
status: this.status,
ids: this.form.ids,
};
batchChangeStatus(data).then((res) => {
if (res.code == 200) {
this.$message({
message: this.$t('common.success'),
type: 'success',
});
this.$emit('cancel');
}
});
},
// 调拨-提交
handleBatchExchangeConfirm() {
this.$refs.formData.validate((valid) => {
if (valid) {
let data = {
orgCode: this.form.orgCode,
marketCode: this.form.marketCode,
chooseList: this.form.cartList.filter((item) => item.flag),
};
batchExchange(data).then((res) => {
if (res.code == 200) {
this.$message({
message: this.$t('common.success'),
type: 'success',
});
this.$emit('cancel');
}
});
}
});
},
// 点击存储行数据
handleRowClick(row) {
this.rowData = undefined;
this.rowData = row;
},
// 获取所属超市信息
getOrgSelect() {
// let param = { flag: 1 };
getOrgSelect().then((response) => {
if (response.code == 200) {
// 所属超市
this.initData.OrgSelect = response.data;
}
});
},
// 获取所属门店信息
getMarketSelect(parentValue) {
if (parentValue !== '') {
let param = { parentValue: parentValue };
getMarketSelect(param).then((response) => {
if (response.code == 200) {
// 所属门店
this.initData.MarketSelect = response.data;
}
});
} else {
// 所属门店
this.initData.MarketSelect = [];
}
},
// 超市变更时,级联门店下拉选项
setMarketCodeSelect() {
// 获取所属门店信息
this.form.marketCode = '';
this.getMarketSelect(this.form.orgCode);
},
},
};
</script>
<style lang="scss" scoped>
.matchNumItem {
margin-bottom: 15px !important;
}
.selectedText {
font-weight: 400;
color: #333333;
}
::v-deep .el-table__body {
-webkit-border-vertical-spacing: 1px;
}
</style>