1.展示效果
2.html代码
<el-form>里的 :model="registerForm" 绑定为一个对象, :rules="rules"要配合<el-form-item> 里的:prop一起使用进行表单验证,:prop要动态绑定数组的值,因此可以写为:prop="`processData.${index}.jurisdictionName`
<el-dialog :visible.sync="dialogRegister" width="1200px" :close-on-click-modal="false">
<div>
<div class="el-dialog-register-top">资产登记</div>
<div style="padding: 10px" class="row-col-columns">
<div class="row-col-columns-1">序号</div>
<div class="row-col-columns-2">
<span class="register-star">*</span>主机序列
</div>
<div class="row-col-columns-3">
<span class="register-star">*</span>辖区
</div>
<div class="row-col-columns-2">
<span class="register-star">*</span>型号
</div>
<div class="row-col-columns-2">
<span class="register-star">*</span>资产名称
</div>
<div class="row-col-columns-3">
<span class="register-star">*</span>所属厂家/品牌
</div>
<div class="row-col-columns-2">
<span class="register-star">*</span>使用单位
</div>
</div>
<el-form style="width: 100%;" size="medium" :model="registerForm" ref="ruleFormProp" :rules="rules">
// 循环表单里的数组
<div v-for="(item, index) in registerForm.processData" :key="index" class="row-col-columns">
<div class="row-col-columns-1 number">{{ index + 1 }}</div>
<div class="row-col-columns-2">
<el-input v-model="item.alarmSerialNumber" disabled></el-input>
</div>
<div class="row-col-columns-3">
<!-- 辖区 -->
<el-form-item :prop="`processData.${index}.jurisdictionName`" :rules="rules.jurisdictionName">
<el-input v-model="item.jurisdictionName" disabled></el-input>
</el-form-item>
</div>
<div class="row-col-columns-2">
<!-- 型号 -->
<el-form-item :prop="`processData.${index}.model`" :rules="rules.model">
<el-input v-model="item.model" disabled></el-input>
</el-form-item>
</div>
<div class="row-col-columns-2">
<el-form-item :prop="'processData.' + index + '.assetsName'" :rules="rules.assetsName">
<el-input placeholder="请输入" class="addinput" v-model="item.assetsName">
</el-input>
</el-form-item>
</div>
<div class="row-col-columns-3">
<el-form-item :prop="`processData.${index}.belongBrandId`" :rules="rules.belongBrandId">
<el-cascader v-model.trim="item.belongBrandId" ref="cascaderList" @change="handleChange($event, index)"
:props="{
lazy: true,
lazyLoad: lazyLoadAdd
}">
</el-cascader>
</el-form-item>
</div>
<div class="row-col-columns-2">
<!-- 使用单位 -->
<el-form-item :prop="`processData.${index}.useId`" :rules="rules.useId">
<el-select v-model="item.useId" clearable placeholder="使用单位" class="inputSelect">
<el-option v-for="item2 in item.useOptions" :key="item2.value" :label="item2.label" :value="item2.value"></el-option>
</el-select>
</el-form-item>
</div>
<!--<div class="row-col-columns-1 number" @click="clearItem(item)">
<svg class="iconfont" aria-hidden="true" style="width: 18px; height: 18px">
<use xlink:href="#el-icon-myshanchu" />
</svg>
</div>-->
</div>
</el-form>
<div class="footer-btn">
<el-button @click="onCancel" class="btnSizeStyle">取 消</el-button>
<el-button type="primary" @click="onSubmit" class="btnSizeStyle">确 定</el-button>
</div>
</div>
</el-dialog>
3.表单验证
表单里绑定的值写在data;表单验证必须使用validator,不然很可能验证不成功
data() {
var checkassetsName = (rule, value, callback) => {
if (!value) {
return callback(new Error('请输入资产名称'));
} else {
callback();
}
};
var checkbelongBrandId = (rule, value, callback) => {
if (value.length === 0) {
return callback(new Error('请选择所属厂家'));
} else if (value[0] === 'ditto' && value[1] === 0) {
return callback(new Error('第一条数据不能为同上'));
} else if (value.length === 2 && value[0] !== 'ditto') {
return callback(new Error('请选择品牌'));
} else {
callback();
}
};
var checkuseId = (rule, value, callback) => {
if (!value) {
return callback(new Error('请选择使用单位'));
} else {
callback();
}
};
return {
dialogRegister: false, // 批量资产登记弹窗
registerLoading: false,
registerForm: { // 表单
processData: [] // 用于接收后端数组
},
rules: {
assetsName: [{ validator: checkassetsName, trigger: 'blur' }],
belongBrandId: [{ validator: checkbelongBrandId, trigger: 'change' }],
useId: [{ validator: checkuseId, trigger: 'change' }],
}
}
}
4. 获取使用单位
获取使用单位,使用resolve将异步操作成功的数据传参给第7步
// 使用单位
getUse() {
return new Promise((resolve, reject) => {
organizationApiManagement('GET', '', 'find').then(res => {
const arr = [] // 全部
if (res.code !== '0000') {
resolve(arr)
} else {
res.data.list.forEach(item => {
const k = {
serialNo: item.serialNo,
value: item.id,
label: item.organizationName
}
arr.push(k)
resolve(arr)
})
}
})
})
},
// 使用单位数据结构为
// [
// {label: "华为",serialNo: "1519863055532449792",value: 42},
// {label: "浙江大华技术股份有限公司",serialNo: "1460855692123456896",value: 2}
// ]
5.根据厂家选择品牌
项目需要根据厂家选择品牌,因此使用联级选择器,看不懂得可以注释相关代码
import { belongBrand } from '@/utils/manufacturerBrand' // 为js文件
// 获取厂家及品牌
async lazyLoadAdd(node, resolve) {
console.log(node)
if (node.level === 0) {
return resolve(await belongBrand(node.level + 1))
} else if (node.level === 1) {
return resolve(await belongBrand(node.level + 1, node.value))
}
},
// 即选择厂家也选择品牌,才能给数组push下标,进行rules验证
handleChange(e, index) {
e.push(index)
},
6. manufacturerBrand.js文件
import { organizationApiManagement } from '@/api/property/pointInterface'
import { getBrandApi } from '@/api/property/assets'
const belongBrand = async (level, id) => {
return new Promise((resolve) => {
console.log(level)
if (level === 1) {
const organizationArr = []
// 获取所属厂家
organizationApiManagement('GET', '', 'findList').then(res => {
if (res.code === '0000') {
res.data.forEach((item) => {
const k = {
value: item.id,
label: item.organizationName,
children: []
}
organizationArr.push(k)
})
// 同上数据不加children代表下一级没值了
const ditto = {value: "ditto" , label: '同上'}
organizationArr.push(ditto)
resolve(organizationArr)
} else {
resolve(organizationArr)
}
})
} else if (level === 2) {
const arr = []
const params = {
factoryId: id
}
// 获取品牌
getBrandApi(params).then(res => {
if (res.code === '0000') {
res.data.forEach(item => {
const k = {
value: item.id,
label: item.typeName,
children: [],
leaf: true // 这个代表联级选择到此结束
}
arr.push(k)
})
resolve(arr)
} else {
resolve(arr)
}
})
// }
}
})
}
export { belongBrand }
// 所属厂家数据结构
// [
// {children: [], label: "华为", value: 42},
// {children: [], label: "浙江宇视科技有限公司", value: 15},
// {label: "同上",value: "ditto"}
// ]
// 选择华为获得的品牌
// [
// {children: [], label: "华为",leaf: true, value: 12}
// ]
7. 或取表单数组,赋值渲染页面
获取后台数组,本来后端这部没写接口,但是不写接口我的inpurt和select都选择不了,我以为要写异步,我将选中行列表的数据放到promis里面使用,但还是不行,所有又麻烦后端写接口
// 批量资产登记
async assetsRegister() {
this.registerLoading = true
// 因为除了第一个都要有同上选项,因此放在了这里
const useOptions = await this.getUse() // 使用单位列表
// 根据主机序列号获取详情信息
const host = ['188720045', '450022554']
// this.selectList为选中行的数据,因为你们没有,我写默认值
//this.selectList.forEach(item => {
// host.push(item.alarmSerialNumber)
//})
const params = { alarmSerialNumber: host }
alarmRecordApiManagement('GET', 'findDetail', params).then(res => {
switch (res.code) {
case '0000':
res.data.forEach((item, index) => {
item.assetsName = '' // 资产名称
item.jurisdictionCode = '43010413' // 银盆岭编码,传给后台
item.jurisdictionName = '湖南省长沙市岳麓区银盆岭街道' // 前端显示
item.model = '其他'
item.belongBrandId = [] // 同时绑定所属厂家(数组第一个值)和品牌(第二个值)绑定的值
item.useId = '' // 使用单位
item.useOptions = useOptions // 使用单位下拉数组
const dittoVal = [{ value: "ditto", label: '同上' }]
if (index !== 0) { // 不是第一条,都同上
item.useId = 'ditto'
// 此方法不改变原数组添加数据,从第二条开始数据包含同上
item.useOptions = item.useOptions.concat(dittoVal)
}
})
this.registerForm.processData = res.data
this.dialogRegister = true
this.registerLoading = false
break
default:
this.$message.error(res.message)
this.registerLoading = false
break
}
})
},
// 因为不写接口,前端会有问题,所有这个接口里面没什么值,有用的只有
//[
// {alarmSerialNumber:"188720045"},
// {alarmSerialNumber:"450022554"}
//]
8. 取消和确定事件
// 取消
onCancel() {
this.registerForm.processData = []
this.dialogRegister = false
},
// 确定
onSubmit() {
this.$refs.ruleFormProp.validate((valid) => {
if (valid) {
console.log('执行操作')
}
})
}
9. css样式
.el-dialog-register-top {
margin-top: -30px;
padding: 10px;
font-size: 18px;
color: #333;
border-bottom: 1px solid #E4E7ED;
}
.row-col-columns {
color: #333;
display: flex;
margin-left: 8px;
div {
padding-right: 5px;
}
::v-deep .el-input.is-disabled .el-input__inner {
color: #333;
}
.number {
padding: 10px 0 0 15px;
}
.row-col-columns-1 {
width: 40px;
}
.row-col-columns-2 {
width: 180px;
}
.row-col-columns-3 {
width: 240px;
}
.register-star {
color: #F56C6C;
}
}
10. 每个接口后端返回的值我都写在后面了,你们可以进行替换,相关注释也写在代码中