当前位置: 首页 > news >正文

vue实现穿梭框,ctrl多选,shift多选

效果图

 代码

<template><div class="container"><!--左侧--><div><div class="title">{{ titles[0] }}</div><div class="layerContainer"><div v-for="item in leftLayerArray":key="getKey(item)":ref="getRefKey(item)"@click="e =>layerClicked(e,item,true)"><el-tooltip effect="light" :content="item.key" placement="top" v-if="item.key.length > 10"><div>{{ item.key }}</div></el-tooltip><div v-else>{{ item.key }}</div></div></div></div><!--中间按钮--><div class="centerButton"><div @click="transferToRight">&gt;</div><div @click="transferAllToRight">&gt;&gt;</div><div @click="transferToLeft">&lt;</div><div @click="transferAllToLeft">&lt;&lt;</div></div><!--右侧--><div><div class="title">{{ titles[1] }}</div><div class="layerContainer"><div v-for="item in rightLayerArray":key="getKetRight(item)":ref="getRefKeyRight(item)"@click="e =>layerClicked(e,item, false)"><el-tooltip effect="light" :content="item.key" placement="top" v-if="item.key.length > 10"><div>{{ item.key }}</div></el-tooltip><div v-else>{{ item.key }}</div></div></div></div><!--  上下移动的按钮  --><div class="transfer-right-buttons"><div :class="upClass" @click="moveMoreStep('up')"><img src="图片地址"alt=""></div><div :class="upClass" @click="moveOneStep('up')"><img src="图片地址"alt=""></div><div :class="downClass" @click="moveOneStep('down')"><img src="图片地址"alt=""></div><div :class="downClass" @click="moveMoreStep('down')"><img src="图片地址"alt=""></div></div></div>
</template>
<script>export default {name: "ha-transfer",props: {titles: {type: Array,default: () => ['地图图层', '图例项']},originData: {type: Array,default: () => [{key: '点图层',id: 1},{key: '线图层',id: 2},{key: '面图层',id: 3},{key: '多点图层',id: 4},{key: '多线图层',id: 5},{key: '多面图层',id: 6}]},selectedData: {type: Array,default: () => [{key: '图例项1',id: 7},{key: '图例项2',id: 8},{key: '图例项3',id: 9},{key: '图例项4',id: 10},{key: '图例项5',id: 11},{key: '图例项6',id: 12}]}},data() {return {leftLayerArray: [...this.originData],leftCurrentSelectedLayer: [],rightLayerArray: [...this.selectedData],rightCurrentSelectedLayer: []}},computed: {upClass() {if (this.rightCurrentSelectedLayer.length === 0) {return 'disabled'}for (let item of this.rightCurrentSelectedLayer) {if (item.id === this.rightLayerArray[0].id) {return 'disabled'}}return ''},downClass() {if (this.rightCurrentSelectedLayer.length === 0) {return 'disabled'}for (let item of this.rightCurrentSelectedLayer) {if (item.id === this.rightLayerArray[this.rightLayerArray.length - 1].id) {return 'disabled'}}return ''},},methods: {getRefKey(item) {return `layer-${item.id}`},getKey(item) {return `layer-${item.id}`},getRefKeyRight(item) {return `layer-right-${item.id}`},getKetRight(item) {return `layer-right-${item.id}`},/*** 单击穿梭框列表项,选中或取消选中* @param e 事件对象* @param item  当前项* @param isLeft  是否是左侧*/layerClicked(e, item, isLeft) {let currentLayer, layerArray, refFunctionif (isLeft) {currentLayer = [...this.leftCurrentSelectedLayer]layerArray = [...this.leftLayerArray]refFunction = this.getRefKey} else {currentLayer = [...this.rightCurrentSelectedLayer]layerArray = [...this.rightLayerArray]refFunction = this.getRefKeyRight}const refElement = this.$refs[refFunction(item)][0];if (e.ctrlKey || e.metaKey) {const isSelected = currentLayer.includes(item);if (isSelected) {refElement.classList.remove('active');currentLayer.splice(currentLayer.indexOf(item), 1);} else {refElement.classList.add('active');currentLayer.push(item);}} else if (e.shiftKey) {const firstIndex = layerArray.indexOf(currentLayer[0]);const lastIndex = layerArray.indexOf(item);const [startIndex, endIndex] = [firstIndex, lastIndex].sort();currentLayer = layerArray.slice(startIndex, endIndex + 1);layerArray.forEach((item, index) => {const refElement = this.$refs[refFunction(item)][0];if (index >= startIndex && index <= endIndex) {refElement.classList.add('active');} else {refElement.classList.remove('active');}})} else {currentLayer = [item];layerArray.forEach(item => {this.$refs[refFunction(item)][0].classList.remove('active');})refElement.classList.add('active');}if (isLeft) {this.leftCurrentSelectedLayer = [...currentLayer];this.leftLayerArray = [...layerArray];} else {this.rightCurrentSelectedLayer = [...currentLayer];this.rightLayerArray = [...layerArray];}},/*** 把选中的图层移动到右侧*/transferToRight() {this.rightLayerArray.push(...this.leftCurrentSelectedLayer)this.leftLayerArray = this.leftLayerArray.filter(item => {return this.leftCurrentSelectedLayer.indexOf(item) === -1})this.leftCurrentSelectedLayer = []},/*** 把所有的图层移动到右侧*/transferAllToRight() {this.rightLayerArray.push(...this.leftLayerArray)this.leftCurrentSelectedLayer = []this.leftLayerArray = []},/*** 把选中的图层移动到左侧*/transferToLeft() {this.leftLayerArray.push(...this.rightCurrentSelectedLayer)this.rightLayerArray = this.rightLayerArray.filter(item => {return this.rightCurrentSelectedLayer.indexOf(item) === -1})this.rightCurrentSelectedLayer = []},/*** 把所有的图层移动到左侧*/transferAllToLeft() {this.leftLayerArray.push(...this.rightLayerArray)this.rightCurrentSelectedLayer = []this.rightLayerArray = []},/*** 向上或向下移动一步* @param status*/moveOneStep(status) {if (status === 'up' && this.upClass === 'disabled') returnif (status === 'down' && this.downClass === 'disabled') returnlet temp = []for (let item of this.rightLayerArray) {if (this.rightCurrentSelectedLayer.indexOf(item) === -1) {temp.push(item)}}this.rightCurrentSelectedLayer.sort((a, b) => {return this.rightLayerArray.indexOf(a) - this.rightLayerArray.indexOf(b)})let index = this.rightLayerArray.indexOf(this.rightCurrentSelectedLayer[0])status === 'up' ? index-- : index++this.rightLayerArray = [...temp.slice(0, index), ...this.rightCurrentSelectedLayer, ...temp.slice(index)]},/*** 向上或向下移动多步到顶或者到底* @param status*/moveMoreStep(status) {if (status === 'up' && this.upClass === 'disabled') returnif (status === 'down' && this.downClass === 'disabled') returnlet temp = []for (let item of this.rightLayerArray) {if (this.rightCurrentSelectedLayer.indexOf(item) === -1) {temp.push(item)}}this.rightLayerArray = status === 'up' ?[...this.rightCurrentSelectedLayer, ...temp] :[...temp, ...this.rightCurrentSelectedLayer]},}
}
</script><style scoped lang="less">
.disabled() {cursor: not-allowed !important;background-color: #999 !important;border: #333 solid 1px !important;
}.hover() {background-color: #eee;border: #409eff solid 1px;cursor: default;
}.buttonContainer() {height: 200px;display: flex;flex-direction: column;justify-content: space-between;align-items: center;
}.active() {background-color: #409eff;color: #fff;
}.container {display: flex;justify-content: space-between;align-items: center;user-select: none;.layerContainer {width: 200px;height: 250px;border: #999 solid 1px;box-sizing: border-box;padding: 10px;white-space: nowrap;overflow-x: hidden;overflow-y: auto;div {&:hover {cursor: default;}}.active {.active()}}.centerButton {.buttonContainer();div {width: 30px;height: 30px;border: #666 solid 1px;background-color: #ddd;text-align: center;line-height: 30px;&:hover {.hover()}}}.transfer-right-buttons {.buttonContainer();div {width: 30px;height: 30px;border: #666 solid 1px;background-color: #ddd;img {width: 100%;height: 100%;}&:hover {.hover()}}.disabled {.disabled()}}
}
</style>

http://www.lryc.cn/news/131892.html

相关文章:

  • Win11中zookeeper的下载与安装
  • ubuntu22.04 找不到串口,串口ttyusb时断时续的问题(拔插以后能检测到,过会儿就检测不到了)
  • Pinia基础教程
  • 【NOIP】标题统计
  • BOXTRADE-天启量化分析平台 系统功能预览
  • 解决Kibana(OpenSearch)某些字段无法搜索问题
  • 代码随想录训练营day15|102.层序遍历 226.翻转二叉树 101.对称二叉树
  • Nginx 配置https以及wss
  • Log4net在.Net Winform项目中的使用
  • 从零到一制作扫雷游戏——C语言
  • Python 数据挖掘与机器学习教程
  • 排序小白必读:掌握插入排序的基本原理
  • html常见兼容性问题
  • Docker实战:docker compose 搭建Redis
  • Debian11 Crontab
  • css 文字排版-平铺
  • 把握潮流:服装定制小程序的发展与趋势
  • Go 安装配置
  • 镜像底层原理详解和基于Docker file创建镜像
  • k8s扩缩容与滚动更新
  • 4.小程序的运行机制
  • 基于 Vercel TiDB Serverless 的 chatbot
  • Android 多渠道打包及VasDolly使用
  • LeetCode 42题:接雨水
  • spring boot 提示:程序包不存在,解决方法总结
  • docker项目实战
  • 银行客户关系管理系统springboot财务金融进销存java jsp源代码
  • Maven 插件 maven-antrun-plugin 执行 ant 脚本
  • 【仿写框架之仿写Tomact】四、封装HttpRequest对象(属性映射http请求报文)、HttpResponse对象(属性映射http响应报文)
  • LeetCode 41题:缺失的第一个正数