概述
最近在做后台管理系统,遇到一个需求,就是根据下拉选择框多选,选中的内容在表格中展示,每一行都可以添加多个分类标签。
效果图如上:
分析需求:
1.select
组件多选功能实现
<el-select v-model="checks" multiple placeholder="请选择物料分类" @change="checkChange" size="mini" @remove-tag="removeTag">
<el-option v-for="(cate) in productCategorymenu" :key="cate.id" :label="cate.name" :value="cate.id">
</el-option>
</el-select>
分析上面的代码:
1.checks是v-model双向数据绑定的结果,多选时,checks是一个数组,数组中的每一项就是选中的option中的value值
2.@change是监听select组件的选中与取消选中操作
3.@remove-tag是监听select组件,不触发下拉弹窗,直接删除tag时触发的函数
4.option是循环渲染的,v-for循环的数据中,key是唯一值,label是展示的文本,value就是v-model中的每一项值了
2.监听select
组件的选中与取消选中等方法
change
监听组件选中与取消
checkChange(val) {
//这个val就是v-model绑定的数组格式
this.checks = val;
//判断右侧的表格中是否有数据,如果没有或者没有此字段,则给此字段赋值为一个空数组
if (!this.supplierObj.supplierChecks) {
this.supplierObj.supplierChecks = [];
}
var arr = this.supplierObj.supplierChecks;
if (val.length > arr.length) {
this.checks.forEach(check => {
var list = arr.filter(a => a.topCategoryId == check);
if (list.length) {
//console.log('找到数据');
} else {
//console.log('没有找到数据');
var nameArr = this.productCategorymenu.filter(cate => cate.id == check);
arr.push({
"topCategoryId": check,
"topCateogryName": nameArr && nameArr[0] && nameArr[0].name,
"cateogryName": []
})
}
})
} else {
var list = [];
this.checks.forEach(check => {
var lis = arr.filter(a => a.topCategoryId == check);
lis && lis.forEach(l => {
list.push(l);
})
})
this.supplierObj.supplierChecks = list;
}
},
分析上面的代码:
如果此次操作是选中一项,则左侧的数组长度要多于右侧的数组长度,因此可以循环遍历,找到多出来的一项,也就是本次添加的一项,给右侧数组添加。
如果找到两个数组中的不同项,这个问题我遇到过两次了。。。
思路如下:
对第一个数组进行循环遍历,针对数组的每一项,都跟第二个数组filter
筛选,如果有筛选值,则表示有数据,否则表示第二个数组中没有此项。
this.checks.forEach(check=>{
var list = arr.filter(a=> a.topCategoryId == check);
//此处的List就是筛选出来的数组,如果有长度,则表示第二个数组含有此项,否则表示第二个数组没有此项
if (list.length) {
//console.log('找到数据');找到数据后一般不做处理,
} else {
//console.log('没有找到数据');
//没有找到此项,则根据此项的value找到对应的名称,可以通过for循环,也可以通过filter筛选
var nameArr = this.productCategorymenu.filter(cate => cate.id == check);
arr.push({
"topCategoryId": check,
"topCateogryName": nameArr && nameArr[0] && nameArr[0].name,
"cateogryName": []
})
}
})
如果此次操作是取消选中一项,则左侧的数组长度要小于右侧的数组长度,因此可以循环遍历,找到少出来的一项,也就是本次去掉的一项,给右侧数组删除。
最后的关键还是归结到:找两个数组的不同之项。还是可以通过筛选的方式
//定义一个空数组,遍历左侧数组,如果右侧数据有某一项,则直接push到空数组中,这样遍历完成后,拿到的跟左侧数据保持一致的右侧数据了。
var list = [];
this.checks.forEach(check => {
var lis = arr.filter(a => a.topCategoryId == check);
lis && lis.forEach(l => {
list.push(l);
})
})
this.supplierObj.supplierChecks = list;//将list数组赋值给右侧数组即可完成
3.直接删除tag
形式的多选项,触发removeTag
方法
removeTag(val) {
//此时的参数val就是移除的value值
var arr = this.supplierObj.supplierChecks;
var list = arr.filter(a => a.topCategoryId != val);
this.supplierObj.supplierChecks = list;
},
4.右侧表格的添加多项tag
标签问题
<el-table :data="supplierObj.supplierChecks" border stripe style="width:800px">
<el-table-column prop="topCateogryName"
label="物料名称">
</el-table-column>
<el-table-column prop="cateogryName"
label="分类">
<template slot-scope="scope">
<el-tag :key="tag" size="mini" :closable="!disabled"
v-for="tag in scope.row.cateogryName"
:disable-transitions="false"
@close="handleClose(tag,scope.row.cateogryName)">
{{tag}}
</el-tag>
<el-input type="text" style="display:inline-block;width:80px;"
v-if="scope.row.inputVisible"
v-bind:value="scope.row.inputValue"
:ref="scope.$index+'saveTagInput'"
size="small"
@input="handleTagChange($event,scope)" @blur="handleInputConfirm(scope)" @keyup.enter.native="$event.target.blur">
</el-input>
<el-button v-else size="mini" class="button-new-tag" @click="showInput(scope)" :disabled="disabled">+ 添加分类</el-button>
</template>
</el-table-column>
</el-table>
注意:官网上给出的动态tag
标签是这样的:
官网上的的输入框,有两个触发保存的操作:回车事件
和失去焦点事件
,但是在实际操作过程中,单纯的失去焦点事件并无问题,但是回车事件本身也会触发失去焦点事件,因此会导致页面出现问题。
回车事件与失去焦点事件冲突的解决方法
@keyup.enter.native="$event.target.blur"
触发回车后,通过$event.target.blur
用来触发失去焦点事件即可。
使用v-model
无法给input
组件添加双向绑定时,则需要拆解为value+input
的方式来处理
可能是因为我这边的需求是表格渲染的input
动态添加tag
,在实际操作中,并不能用v-model
对组件进行双向绑定,因此改为以下的处理方式:
<el-input type="text" style="display:inline-block;width:80px;"
v-if="scope.row.inputVisible"
v-bind:value="scope.row.inputValue"
:ref="scope.$index+'saveTagInput'"
size="small"
@input="handleTagChange($event,scope)" @blur="handleInputConfirm(scope)" @keyup.enter.native="$event.target.blur">
</el-input>
监听input
组件的input
输入方法,用于实现双向数据绑定
handleTagChange(val,scope) {
var row = scope.row;
row.inputValue = val;
var index = scope.$index;
this.supplierObj.supplierChecks[index].inputValue = row.inputValue;
this.$set(this.supplierObj.supplierChecks,index,row);
},
监听添加标签按钮,用于展示input
组件,并获取焦点
showInput(scope) {
var index = scope.$index;
var row = this.supplierObj.supplierChecks[index];
row.inputVisible = true;
row.inputValue = null;
this.$forceUpdate();
this.$set(this.supplierObj.supplierChecks,index,row);
this.$nextTick(_ => {
this.$refs[`${scope.$index}saveTagInput`].$refs.input.focus();
});
},
移除tag
标签的操作,触发的是close
方法
handleClose(tag, arr) {
arr.splice(arr.indexOf(tag), 1);
},
input
输入框组件失去焦点事件
handleInputConfirm(scope) {
var index = scope.$index;
var value = scope.row.inputValue;
if (value && !this.supplierObj.supplierChecks[index].cateogryName.includes(value)) {
this.supplierObj.supplierChecks[index].cateogryName.push(value);
} else {
this.$message.error('请输入名称且名称不能重复');
return;
}
scope.row.inputValue = "";
scope.row.inputVisible = false;
this.$set(this.supplierObj.supplierChecks,index,scope.row);
this.$forceUpdate();
},
完成!!!
最后
以上就是听话哑铃为你收集整理的elementUi——select下拉多选后触发表格更改——js技能提升1.select组件多选功能实现2.监听select组件的选中与取消选中等方法3.直接删除tag形式的多选项,触发removeTag方法4.右侧表格的添加多项tag标签问题的全部内容,希望文章能够帮你解决elementUi——select下拉多选后触发表格更改——js技能提升1.select组件多选功能实现2.监听select组件的选中与取消选中等方法3.直接删除tag形式的多选项,触发removeTag方法4.右侧表格的添加多项tag标签问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复