element穿梭框点击后异步
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了element穿梭框点击后异步相关的知识,希望对你有一定的参考价值。
对于您这个element穿梭框点击后异步问题解答,Element穿梭框点击后异步,一般有如下几种实现方式:1. 使用Ajax异步请求:将穿梭框的点击事件进行绑定,触发后发起Ajax异步请求,请求后台接口获取数据,再做相应的处理,用于展示或者其他操作。
2. 使用Promise异步函数:将穿梭框的点击事件绑定,触发后执行Promise异步函数,在函数内部调用后台接口,获取数据后再做相应处理,以便展示或者其他操作。 参考技术A 1. 摒弃elementui框架自带的穿梭框,之前也有遇到改造elementui穿梭框的数据格式,前提是,展示的label就应该作为选中的key,这样如果移到右边就可以通过处理数据,将选中的非当前页的数据拼接到左侧的当前页列表中,这样就可以做到数据的反显了,不过这里也存在bug,规定一页展示10条,这样的话当前页的数据肯定是在10条之上的。所以考虑自己手动实现穿梭框的功能;
2. 由于需要勾选操作,采用elementui框架中的table实现,左右两个table,中间填充两个移动的按钮,通过点击确定添加、移除,更新两个table的数据、选中状态;
3. 这样的好处是,左右两侧数据独立,左边的翻页操作,对右边不会带来任何影响,都只涉及添加、移除等操作,不会有过多的处理数据、逻辑;
4. 为了能更好的呈现穿梭框的功能,这里考虑在对左侧移除、添加时,添加标识,动态控制当前行的显示与隐藏。即在table中定义 :row-class-name="rowClassName",通过动态复制,添加样式类名,控制行的显示隐藏,这样只要左边选择的数据移到右侧后,视觉上会有一种隐藏的效果 参考技术B element穿梭框点击后异步获取数据
<el-transfer
v-model="value"
:data="data"
:props="props"
@change="handleChange"
>
</el-transfer>
data()
return
value: [],
data: [],
props:
key: 'id',
label: 'name',
,
methods:
// 点击穿梭框时触发
handleChange()
this.$axios.get('/api/data').then(res =>
this.data = res.data
)
参考技术C 由于需要勾选操作,采用elementui框架中的table实现,左右两个table,中间填充两个移动的按钮,通过点击确定添加、移除,更新两个table的数据、选中状态;
数据量庞大的分页穿梭框实现
昨天偶然看到评论区一位老哥的需求,一时兴起,就答应了当天写好源码写个博客
回来的晚,第二天才写好。。
写个分页的穿梭框,从而解决数据量庞大的问题
我之前写过一篇博客:关于 Element 组件的穿梭框的重构 介绍并实现的方法
但是第二个分页的 demo 没有,在上一家公司匆匆解决后,没有写入自己的 GitHub,有点可惜...
当时可是在上班,而且太忙了,不过既然答应了这位老哥写个 demo,就要做到,也是给自己一个挑战
进入正题
看实现效果图
既然之前博客谈过,这里就不仔细谈了,主要放主要的源码
问题
Element 官方组件目前(==18年==)明显对于多选==三级联动的穿梭框==没有解决方案,也对==数据量庞大的穿梭框==没有结局方案(各位看官可以试一下,放入几千条数据到穿梭框,卡到爆...),遂只能自己重写组件,完成业务需求
功能
- 实现分页
- 搜索,做成在所有数据里搜索,不是在当前分页的数据里搜索,这样就不用在每个分页都搜索一次了。搜索后的结果也会自动分页。(全部数据和仅作展示的数据存都是存放在不同变量)
- 全选只在当前页里的全选
- 穿梭框左右两个框的联动
关键点
- 每个框作为一个子组件(组件化思想)
- 分页关键判断临界点
- 搜索,监听 keyword 的变化,传递到父组件搜索,从全局数据搜索
- 把备选的数据当做已选的过滤数组,把已选的数据当做备选的过滤数组,在全局 data 进行过滤,最后再进行一次搜索(备选、已选)(考虑到是在搜索过后点击的)
- 中间的左右箭头(加入已选和移除已选)放在父组件控制数据流动
- 数据流动:子备选框 -> 父组件 -> 子已选框 (移除已选相反)
源码
- Districts.vue(包裹两个穿梭框的父组件)
export default {
props: {
data: {
type: Array,
},
},
data () {
return {
dataList: [], // 未选中(已过滤出已选)的数据
selectList: [], // 已选中的数据,传递到子组件的数据
dataListNoCheck: [], // 未选中的(或已搜索)传递到子组件的数据
selectListCheck: [], // 已选中的(或已搜索)传递到子组件的数据
checkData: [], // 已勾选的数据(待添加或删除数据)
noSelectkeyword: ‘‘,
haSelectkeyword: ‘‘,
disablePre: true,
disableNex: true,
};
},
created () {
this.getDistrict();
},
methods: {
// 分页数据
getDistrict () {
this.dataList = this.data;
this.dataListNoCheck = this.dataList;
},
searchWord (keyword, titleId) {
// 过滤掉数据,保留搜索的数据
if (titleId === 0) {
this.noSelectkeyword = keyword;
this.dataListNoCheck = this.dataList.filter(val => val.name.includes(keyword));
} else {
this.haSelectkeyword = keyword;
this.selectListCheck = this.selectList.filter(val => val.name.includes(keyword));
}
let refsName = titleId === 0 ? ‘noSelect‘ : ‘hasSelect‘;
// 延迟执行
setTimeout(() => {
this.$refs[refsName].getDistrict();
}, 0);
},
// 检查左右按钮可用性
checkDisable (data, id) {
if (id === 0) {
data.length > 0 ? (this.disableNex = false) : (this.disableNex = true);
} else {
data.length > 0 ? (this.disablePre = false) : (this.disablePre = true);
}
},
// 选择
checkSelect (val) {
this.checkData = val;
},
// 关键:把未选择的数据当做已选择的过滤数组,把已选择的数据当做未选择的过滤数组,在全局data进行过滤,最后进行一次搜索
// 添加至已选
addData () {
let dataFilter = [
...this.selectList,
...this.checkData,
];
this.dataList = this.data.filter(item1 => {
return dataFilter.every(item2 => item2 !== item1);
});
this.selectList = this.data.filter(item1 => {
return this.dataList.every(item2 => item2 !== item1);
});
// 搜索一次
this.searchWord(this.noSelectkeyword, 0);
this.searchWord(this.haSelectkeyword, 1);
},
// 从已选中删除
deleteData () {
let dataFilter = [
...this.dataList,
...this.checkData,
];
this.selectList = this.data.filter(item1 => {
return dataFilter.every(item2 => item2 !== item1);
});
this.dataList = this.data.filter(item1 => {
return this.selectList.every(item2 => item2 !== item1);
});
// 搜索一次
this.searchWord(this.noSelectkeyword, 0);
this.searchWord(this.haSelectkeyword, 1);
},
},
components: {
Transfer,
},
};
</script>
- Transfer.vue(穿梭框子组件)
export default {
props: {
titleId: {
type: Number,
},
districtList: { // 父组件传递的数据
type: Array,
},
},
data () {
return {
title: [‘渠道‘, ‘已选中‘],
districtListMock: [], // 展示的数据 (搜索和分页会自动修改这个数组)
checkedCities: [], // 已选择,数据格式:[id,id,id...]
isIndeterminate: false,
checkAll: false,
searchWord: ‘‘,
len: 0,
total: 0,
pageIndex: 0,
disabledPre: true,
disabledNex: false,
};
},
created () {
this.getDistrict();
},
watch: {
// 搜索框的监听器
searchWord (newWord) {
this.$emit(‘search-word‘, newWord, this.titleId);
},
// districtListMock 和 checkAll 的监听器
districtListMock () {
// 当方框中无已选择的数据时,不能勾选checkBox
if (this.checkedCities.length === 0) {
this.checkAll = false;
this.isIndeterminate = false;
}
},
checkedCities (newWord) {
this.$emit(‘check-disable‘, newWord, this.titleId);
},
// 当列表中无数据时,不能勾选checkBox
checkAll () {
this.checkAll = this.districtListMock.length === 0 ? false : this.checkAll;
},
},
methods: {
// 分页数据
getDistrict () {
this.len = this.districtList.length;
this.total = Math.ceil(this.len / 200);
this.pageIndex = 0;
this.pageData();
},
pageData () {
this.checkedCities = [];
if (this.total > 1 && this.pageIndex < (this.total - 1)) {
this.pageIndex === 0 ? this.disabledPre = true : this.disabledPre = false;
this.disabledNex = false;
this.districtListMock = this.districtList.slice(this.pageIndex \* 200, this.pageIndex \* 200 + 200);
} else {
this.total > 1 ? this.disabledPre = false : this.disabledPre = true;
this.disabledNex = true;
this.districtListMock = this.districtList.slice(this.pageIndex \* 200, this.len);
}
},
// 上一页
prev () {
this.pageIndex > 0 && --this.pageIndex;
this.pageData();
},
// 下一页
next () {
this.pageIndex <= (this.total - 1) && ++this.pageIndex;
this.pageData();
},
// 单选
handleCheckedChange (value) {
let checkedCount = value.length;
this.checkAll = checkedCount === this.districtListMock.length;
this.isIndeterminate = checkedCount > 0 && checkedCount < this.districtListMock.length;
// 子传父
this.$emit(‘check-district‘, value);
},
// 全选
handleCheckAllChange (val) {
this.checkedCities = val ? this.districtListMock.map(val => val) : [];
this.isIndeterminate = false;
// 子传父
this.$emit(‘check-district‘, this.checkedCities);
},
},
};
</script>
具体源码可前往 Github:https://github.com/Krryxa/my-transfer
欢迎 start
呼呼,双休好好休息了~~
以上是关于element穿梭框点击后异步的主要内容,如果未能解决你的问题,请参考以下文章