有时候工作需要某个字段实现批量查询,但是EXCEL又比较麻烦,可以使用动态批量查询
下面是我亲测可用的批量查询界面:
组件实现了字段校验,可使用空格、回车、分号、逗号、excel拷贝、进行输入下一个的能力
大家可以根据自己实际情况调整组件
外部引用批量查询组件:
<CompVin v-model="queryParams.vin" ref="vinRef" />
批量查询组件:
<template>
<div class="component-vin-input" label-position="top">
<el-form-item label="VIN">
<template #label>
<span>VIN码</span>
</template>
<div class="vin-input-wrapper">
<div v-for="(vin, index) in vinGroup" :key="index" :class="vin.result ? '' : 'input-error'" class="vin-edit">
<el-input v-model="vin.vin" maxlength="17" @input="value => handleVinItemChange(value, index)"
@blur="validate([], index)" />
<div class="error-tip">{{ vin.message }}</div>
</div>
<el-input v-model="vinInput" class="vin-input" placeholder="请输入或粘贴VIN码" @input="handleVinInput"
@blur="handleVinInputBlur" @keyup.enter.native="handleVinInputBlur" />
</div>
<div class="vin-tip">每个VIN码输入完成后,以分号(;)结束</div>
</el-form-item>
</div>
</template>
<script>
export default {
name: 'CompVin',
props: {
value: {
type: Array,
default: () => ([])
}
},
data() {
return {
vinGroup: [],
vinInput: '',
vinList: []
}
},
mounted() {
this.value.forEach(vin => {
this.vinGroup.push({
result: true,
vin,
message: ''
})
})
},
methods: {
/**
* 清空
*/
clearInput() {
this.vinGroup = []
this.vinInput = ''
this.vinList = []
},
/**
* 更新vin的页面显示
* @param vinList vin的列表
*/
updateVinGroup(vinList) {
// 先清空vin
this.vinGroup = []
// 遍历列表数据
vinList.forEach(vin => {
this.vinGroup.push({
result: true,
vin,
message: ''
})
})
},
/**
* vin改变的方法,将其格式化成数组
*/
handleVinInput() {
// 如果当前没有输入
if (!this.vinInput) {
return
}
// 替换中文的分号
const replaceChinessSemicolon = this.vinInput.replace(/[;,,\s\r\n]/g, ';')
// 按逗号分割
const vinList = replaceChinessSemicolon.split(';')
// 取出最后一个当成输入项目
this.vinInput = vinList.pop()
// 重新赋值vin的集合
this.vinList = [
...(this.vinList || []),
...vinList.filter(vin => !!vin)
]
// 先清空之前的数据
this.vinGroup = [
...this.vinGroup,
...vinList.filter(vin => !!vin).map(vin => ({
result: vin.length === 17,
vin,
message: vin.length === 17 ? '' : '请输入合法的vin号'
}))
]
// 双向绑定vinList
this.$emit('input', this.vinList)
},
/**
* vin输入框失去焦点的方法
*/
handleVinInputBlur() {
// 给vin加上;
this.vinInput = this.vinInput + ';'
// 将当前输入的vin初始化成需要校验的参数
this.handleVinInput()
},
/**
* vin输入的改变方法
*/
handleVinItemChange(value, index) {
// 如果当前没有输入值
if (!value) {
this.vinGroup.splice(index, 1)
} else {
// 替换中文的分号
const replaceChinessSemicolon = value.replace(/[;,,\s\r\n]/g, ';')
// 按逗号分割
const vinList = replaceChinessSemicolon.split(';').filter(vin => !!vin)
// 如果当前长度大于1个,说明输入了;
if (vinList.length >= 1) {
// 将当前输入的数据插到原来的对象中
vinList.forEach((vin, vIndex) => {
this.vinGroup.splice(index + vIndex, vIndex === 0 ? 1 : 0, {
result: vin.length === 17,
vin,
message: vin.length === 17 ? '' : '请输入合法的vin号'
})
})
}
}
// 重新赋值
this.vinList = this.vinGroup.map(vin => vin.vin)
// 双向绑定vinList
this.$emit('input', this.vinList)
},
/**
* 校验方法
* @param results 需要回显的校验结果
* @param index 当前需要校验的项目
*/
validate(results = [], index = -1) {
// 当前是否是错误
let isError = true
// 当前vin的集合
const vinList = []
// 写入错误信息
this.vinGroup.forEach((group, gIndex) => {
// 如果当前传入了需要校验的项目,则直接校验,如果没传,则全量校验
if (index === -1 || gIndex === index) {
// 如果当前vin输入的不合法
if (group.vin.length !== 17) {
isError = false
group.result = false
group.message = '请输入合法的vin号'
} else {
group.result = true
group.message = ''
}
// 现在开始校验输入的结果
results.forEach(result => {
if (group.vin === result.vin) {
group.result = result.checkResult
group.message = result.errorMsg
isError = isError && result.checkResult
}
})
vinList.push(group.vin)
}
})
// 如果校验有错误
if (!isError) {
throw new Error('请输入正确的VIN号')
}
return vinList
}
}
}
</script>
<style lang="scss">
.component-vin-input {
.el-textarea {
width: 836px;
height: 100px;
.el-textarea__inner {
padding: 12px;
}
}
.vin-input-wrapper {
border: 1px solid #DCDFE6;
border-radius: 4px;
width: 836px;
min-height: 100px;
.vin-edit {
display: inline-block;
width: 199px;
margin-left: 8px;
margin-top: 8px;
.el-input {
width: 100%;
height: 36px;
.el-input__inner {
background-color: #F7F8FA;
border-color: #ffffff;
box-shadow: none;
color: #212026;
font-size: 14px;
font-weight: 400;
padding: 0 10px;
}
}
.error-tip {
display: none;
color: #FF4D4F;
font-weight: 400;
font-size: 12px;
line-height: 18px;
height: 18px;
margin-top: 2px;
position: absolute;
}
&.input-error {
margin-bottom: 20px;
.el-input {
.el-input__inner {
border-color: #FF4D4F;
}
}
.error-tip {
display: block;
}
}
}
.vin-input {
display: inline-block;
width: 199px;
margin-left: 8px;
margin-top: 8px;
.el-input__inner {
background-color: #FFFFFF;
border-color: #ffffff;
box-shadow: none;
color: #212026;
font-size: 14px;
font-weight: 400;
padding: 0 10px;
}
}
}
.vin-tip {
color: rgba(132, 133, 138, 0.7);
font-size: 12px;
font-weight: 400;
line-height: 18px;
height: 18px;
margin-top: 10px;
}
}
</style>