感谢动力暖暖的无私分享
源于:https://blog.csdn.net/poxiaomeng187/article/details/90752130
<template> <warmer-transfer :sourcedata="sourcedata" sourcetitle="源列表" :targetdata="targetData" targettitle="目标列表" > </warmer-transfer> </template> <script> import WarmerTransfer from './subs/transfer' export default { name: 'dataTransfer', components: { WarmerTransfer }, data() { return { sourcedata: [ {id: 1, name: 'HTML5', isSelected: false}, {id: 2, name: 'CSS3', isSelected: false}, {id: 3, name: 'Angular', isSelected: false}, {id: 4, name: 'Vue', isSelected: false}, {id: 5, name: 'Linux', isSelected: false}, {id: 6, name: 'JavaScript', isSelected: false}, {id: 7, name: 'springboot', isSelected: false}, {id: 8, name: 'java', isSelected: false}, {id: 9, name: 'mysql', isSelected: false}, {id: 10, name: 'postgresql', isSelected: false}, {id: 11, name: 'redis', isSelected: false}, {id: 12, name: 'Neo4j', isSelected: false}, {id: 13, name: 'spark', isSelected: false}, {id: 14, name: 'doubbo', isSelected: false}, ], targetData: [ {id: 11, name: 'redis', isSelected: false}, {id: 12, name: 'Neo4j', isSelected: false} ] } } } </script> <style scoped> </style>
子组件
<template> <div class="ty-transfer mt20 ml20"> <div class="fl ty-transfer-list transfer-list-left"> <div class="ty-transfer-list-head"> <div class="tyc-check-blue dib ml10"> <input :disabled="sourceList.length === 0" type="checkbox" @click="toggleAll(0)" :checked="selectedAllStatus(0)" class="transfer-all-check"> <span>全选</span> </div> <div class="dib fs14 fw ml5">{{sourcetitle}} {{selectSourceItemNumber}}/{{sourceList.length}}</div> </div> <div class="ty-transfer-list-body"> <ul class="ty-tree-select"> <li v-for="item in sourceList"> <div class="ty-tree-div"> <label class="tyue-checkbox-wrapper"> <span class="tyue-checkbox"> <input type="checkbox" v-model="item.isSelected" class="tyue-checkbox-input"> <span class="tyue-checkbox-circle"></span> </span> <span class="tyue-checkbox-txt">{{item.name}}</span> </label> </div> </li> </ul> </div> </div> <div class="fl ty-transfer-operation"> <span @click="toTarget" :class="[sourceList.length !== 0 && sourceRefNum !== 0 ? 'active' : 'disabled', 'ty-transfer-btn-toright to-switch']"></span> <span @click="toSource" :class="[targetList.length !== 0 && targetRefNum !== 0 ? 'active' : 'disabled', 'ty-transfer-btn-toleft to-switch']"></span> </div> <div class="fl ty-transfer-list transfer-list-right"> <div class="ty-transfer-list-head"> <div class="tyc-check-blue dib ml10"> <input :disabled="targetList.length === 0" type="checkbox" @click="toggleAll(1)" :checked="selectedAllStatus(1)" class="transfer-all-check"> <span>全选</span> </div> <div class="dib fs14 fw ml5">{{targettitle}} {{selectTargetItemNumber}}/{{targetList.length}}</div> </div> <div class="ty-transfer-list-body"> <ul class="ty-tree-select"> <li v-for="item in targetList"> <div class="ty-tree-div"> <label class="tyue-checkbox-wrapper"> <span class="tyue-checkbox"> <input type="checkbox" v-model="item.isSelected" class="tyue-checkbox-input"> <span class="tyue-checkbox-circle"></span> </span> <span class="tyue-checkbox-txt">{{item.name}}</span> </label> </div> </li> </ul> </div> </div> <div class="fl ty-transfer-operation four-icon"> <span @click="moveItems(4)" :class="[targetList.length !== 0 && targetRefNum !== 0? 'active' : 'disabled', 'ty-transfer-btn-zhiding to-switch normal']"></span> <span @click="moveItems(0)" :class="[targetList.length !== 0 && targetRefNum !== 0? 'active' : 'disabled', 'ty-transfer-btn-totop to-switch']"></span> <span @click="moveItems(1)" :class="[targetList.length !== 0 && targetRefNum !== 0? 'active' : 'disabled', 'ty-transfer-btn-tobottom to-switch']"></span> <span @click="moveItems(3)" :class="[targetList.length !== 0 && targetRefNum !== 0? 'active' : 'disabled', 'ty-transfer-btn-zhidi to-switch normal']"></span> </div> <div class="clearboth"></div> </div> </template> <script> export default { name: 'transfer', props: ['sourcedata', 'sourcetitle', 'targetdata', 'targettitle'], data: function () { return { sourceList: [], targetList: [] } }, filters: {}, computed: { // 源数据中选中的数量 sourceRefNum() { return this.sourceList.filter(item => item.isSelected).length; }, // 目标数据中选中的数量 targetRefNum() { return this.targetList.filter(item => item.isSelected).length; }, // 选择的源记录数量 selectSourceItemNumber() { return this.sourceList.filter(item => item.isSelected).length; }, // 选择目标记录数量 selectTargetItemNumber() { return this.targetList.filter(item => item.isSelected).length; }, }, created() { if (this.targetdata === null || this.targetdata.length === 0) { this.sourceList = this.formatData(val); return; } var source = []; var target = this.targetdata; this.sourcedata.forEach(function (item) { let data = target.filter(n => n.name === item.name); if (data == null || data.length === 0) { source.push(item); } }) this.sourceList = this.formatData(source); this.targetList = this.formatData(this.targetdata); }, watch: {}, mounted() { }, methods: { formatData(dataList) { let data = dataList.map(item => { return { ...item, isSelected: false }; }); return data; }, moveItems(direction) { let selectedItem = this.targetList.filter(item => item.isSelected).map(item => { return item.name; }); // 下移 if (direction === 1) { for (var i = selectedItem.length - 1; i >= 0; i--) { let index = this.targetList.map(item => { return item.name; }).indexOf(selectedItem[i]); if (index >= this.targetList.length - 1) return; this.targetList[index] = this.targetList.splice(index + 1, 1, this.targetList[index])[0]; } } // 上移 if (direction === 0) { for (var i = 0; i < selectedItem.length; i++) { let index = this.targetList.map(item => { return item.name; }).indexOf(selectedItem[i]); if (index <= 0) return; this.targetList[index] = this.targetList.splice(index - 1, 1, this.targetList[index])[0]; } } // 置底 if (direction === 3) { for (var i = 0; i < selectedItem.length; i++) { let index = this.targetList.map(item => { return item.name; }).indexOf(selectedItem[i]); if (index >= this.targetList.length - 1) return; this.targetList.push(this.targetList[index]); this.targetList.splice(index, 1); } } // 置顶 if (direction === 4) { for (var i = selectedItem.length - 1; i >= 0; i--) { let index = this.targetList.map(item => { return item.name; }).indexOf(selectedItem[i]); if (index <= 0) return; this.targetList.unshift(this.targetList[index]); this.targetList.splice(index + 1, 1); } } }, exchange(fd, td) { let selectedItem = fd.filter(item => item.isSelected).map(item => { return { ...item, isSelected: false }; }); td.push(...selectedItem); var selectedlist = fd.filter(item => !item.isSelected); return selectedlist; }, // 全选状态 selectedAllStatus(type) { if (type === 0) { if (this.selectSourceItemNumber === this.sourceList.length && this.selectSourceItemNumber !== 0) { return true; } else { return false; } } else { if (this.selectTargetItemNumber === this.targetList.length && this.selectTargetItemNumber !== 0) { return true; } else { return false; } } }, // 全选及反选 toggleAll(type) { if (type === 0) { let len = this.sourceList.length; let slen = this.sourceList.filter(item => item.isSelected).length; if (len !== slen) { this.sourceList.map(item => (item.isSelected = true)); } else { this.sourceList.map(item => (item.isSelected = false)); } } else { let len = this.targetList.length; let slen = this.targetList.filter(item => item.isSelected).length; if (len !== slen) { this.targetList.map(item => (item.isSelected = true)); } else { this.targetList.map(item => (item.isSelected = false)); } } }, // 把选择数据转移到目标(右框) toTarget() { this.sourceList = this.exchange(this.sourceList, this.targetList); }, // 把选择数据转回到源(左框) toSource() { this.targetList = this.exchange(this.targetList, this.sourceList); } } } </script> <style scoped> .tyue-checkbox { vertical-align: middle; display: inline-block; position: relative; white-space: nowrap; } .tyue-checkbox-txt { margin-left: 6px; margin-right: 8px; } .tyue-checkbox-txt.active { color: #00A0E8; } /*过滤*/ .ty-transfer-list { float: left; 200px; height: 350px; border: 1px solid #e8e8e8; border-radius: 3px; background: #fff; box-shadow: 0 0 5px #e8e8e8 } .ty-transfer-list-head { height: 32px; line-height: 32px; font-size: 14px; color: #666; background-color: #f5f7fc; } .ty-transfer-list-serach { auto; padding: 0 15px 8px; position: relative; } .ty-transfer-list-serach input { display: block; 100%; height: 28px; line-height: 28px; padding-left: 30px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } .ty-transfer-list-serach input { transition: all .3s linear; -webkit-transition: all .3s linear; -o-transition: all .3s linear; -moz-transition: all .3s linear; } .ty-transfer-list-serach > input:focus, .ty-transfer-list-serach > input:hover { border-color: #57c5f7; border: 1px solid #57c5f7; outline: 0; box-shadow: 0 0 0 2px rgba(45, 183, 245, .2); } .ty-tree-select { margin-top: 10px; } .ty-transfer-list-serach-icon { 17px; height: 17px; display: block; position: absolute; top: 4px; left: 22px; z-index: 10; } .ty-transfer-list-body { border-top: 1px solid #e8e8e8; padding: 4px 10px; height: 318px; overflow-y: auto; box-sizing: border-box; } .ty-transfer .ty-tree-arrow-right span, .ty-transfer .ty-tree-arrow-bottom span { margin-left: 0; } .ty-transfer .ty-tree-select-ul { padding-left: 38px; } .ty-transfer .ty-tree-div .tyc-check-blue { margin: 8px 6px; } .ty-transfer .ty-tree-div { height: 30px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .ty-transfer .ty-tree-text { height: 30px; line-height: 30px; cursor: pointer; } .ty-transfer .ty-tree-switcher { height: 28px; } .ty-transfer-list-foot { background: #f1f1f1; } .ty-transfer-list-serach + .ty-transfer-list-body { height: 230px; } .ty-transfer-operation { padding: 107px 20px 0 40px; } .ty-transfer-operation span { display: block; 34px; height: 34px; text-align: center; position: relative; cursor: pointer; border: 1px solid #d9d9d9; border-radius: 50%; background-image: url("../../../assets/images/icon-little.png"); background-repeat: no-repeat; background-color: #f3f3f3; transition: background-color 0.3s linear; -moz-transition: background-color 0.3s linear; -webkit-transition: background-color 0.3s linear; -o-transition: background-color 0.3s linear; } .ty-transfer-operation span i { font-size: 2em; color: #bbb; } .ty-transfer-operation span + span { margin-top: 25px; } .ty-transfer-operation span:hover { border: 1px solid #3dadf2; background-color: #7AC7F8; } .ty-transfer-operation span:hover i { color: #fff; } .ty-transfer-btn-toright, .ty-transfer-btn-toright.disabled:hover { background-position: 8px 2px; } .ty-transfer-btn-toright:hover, .ty-transfer-btn-toright.active, .ty-transfer-btn-toright.active:hover { background-position: 8px -23px; } .ty-transfer-btn-toleft, .ty-transfer-btn-toleft.disabled:hover { background-position: 6px -54px; } .ty-transfer-btn-toleft:hover, .ty-transfer-btn-toleft.active, .ty-transfer-btn-toleft.active:hover { background-position: 6px -79px; } .ty-transfer-operation span.active { border: 1px solid #3dadf2; background-color: #00A0E8; } .ty-transfer-operation span.active i { color: #fff; } .ty-transfer-btn-toleft.disabled:hover, .ty-transfer-btn-toright.disabled:hover { cursor: not-allowed; border: 1px solid #d9d9d9;; background-color: #f3f3f3; } .ty-transfer-operation .active:hover { background-color: #7AC7F8; } .ty-transfer-btn-totop, .ty-transfer-btn-totop.disabled:hover { background-position: 8px 2px; transform: rotate(-90deg); } .ty-transfer-btn-tobottom, .ty-transfer-btn-tobottom.disabled:hover { background-position: 8px 2px; transform: rotate(90deg); } .ty-transfer-btn-totop.disabled:hover, .ty-transfer-btn-tobottom.disabled:hover { cursor: not-allowed; border: 1px solid #d9d9d9; background-color: #f3f3f3; } .ty-transfer-btn-totop:hover, .ty-transfer-btn-totop.active, .ty-transfer-btn-totop.active:hover, .ty-transfer-btn-tobottom:hover, .ty-transfer-btn-tobottom.active, .ty-transfer-btn-tobottom.active:hover { background-position: 8px -23px; } .transfer-all-check { vertical-align: middle; } .show .ty-tabs { 460px; } .ty-tabs-nav { height: 38px; border-bottom: 2px solid #d9d9d9; position: relative; } .ty-tabs-nav > div { height: 40px; overflow: hidden; position: relative; } .ty-tabs-nav-scroll > div { auto; margin: 0 40px; } .ty-tabs-ul { 100%; height: 38px; position: absolute; top: 0; left: 0; z-index: 10; } .tabs-nav-scroll-ul { 1300px; } .ty-tabs-ul li { float: left; padding: 0 15px; height: 38px; line-height: 38px; font-size: 14px; color: #666; cursor: pointer; } .ty-tabs-ul li.current { color: #00a0e8; } .ty-tabs-icon-prev, .ty-tabs-icon-next { 38px; height: 38px; display: block; border-bottom: 2px solid #d9d9d9; cursor: pointer; position: absolute; top: 0; z-index: 100; } .ty-tabs-icon-prev { background-position: 15px -368px; left: 0; } .ty-tabs-icon-prev:hover { background-position: 15px -396px; } .ty-tabs-icon-next { background-position: 15px -424px; right: 0; } .ty-tabs-icon-next:hover { background-position: 15px -454px; } .ty-tabs-line { 86px; height: 2px; background: #00a0e8; position: absolute; bottom: -2px; left: 0; z-index: 101; } .ty-tabs-nav-scroll .ty-tabs-line { left: 40px; } .show .ty-tabs-card { 460px; } .ty-tabs-card-nav { height: 32px; position: relative; } .ty-tabs-card-nav > div { height: 32px; position: relative; } .ty-tabs-card-nav-scroll > div { auto; margin: 0 40px; } .ty-tabs-card-ul { 100%; height: 32px; position: absolute; top: 1px; left: 0; z-index: 10; } .ty-tabs-card-ul li { float: left; min- 48px; height: 30px; line-height: 30px; text-align: center; padding: 0 15px; font-size: 12px; color: #666; border: 1px solid #f1f1f1; border-bottom: 0; background: #f1f1f1; border-radius: 4px 4px 0 0; cursor: pointer; } .ty-tabs-card-ul li + li { margin-left: 8px; } .ty-tabs-card-ul li.current { color: #00a0e8; border: 1px solid #d9d9d9; border-bottom: 1px solid #fff; background: #fff; } .ty-tabs-card-con { border: 1px solid #d9d9d9; } .tabbox { 100%; height: 140px; margin: auto; } .tabbox .content { overflow: hidden; auto; height: auto; position: relative; } .tabbox .content ul { position: relative; left: 0; top: 0; height: auto; } .tabbox .content li { 1500px; height: auto; float: left; padding: 50px; } .tabbox .content li p { padding: 10px; } /*.ty-tabs-card-con{height:100px;padding-top:80px;}*/ .ty-tabs-card-con > .mt20 { text-align: center; } .ty-tabs-card .ty-tabs-icon-prev, .ty-tabs-card .ty-tabs-icon-next { 32px; height: 32px; display: block; border-bottom: 0; cursor: pointer; position: absolute; top: 0; z-index: 100; } .ty-tabs-card .ty-tabs-icon-prev { background-position: 15px -371px; left: 0; } .ty-tabs-card .ty-tabs-icon-prev:hover { background-position: 15px -399px; } .ty-tabs-card .ty-tabs-icon-next { background-position: 15px -427px; right: 0; } .ty-tabs-card .ty-tabs-icon-next:hover { background-position: 15px -457px; } .ty-breadcrumb { height: 24px; } .ty-breadcrumb li { float: left; height: 24px; line-height: 24px; font-size: 14px; color: #999; } .ty-breadcrumb span { padding: 0 10px; color: #ccc; font-size: 14px; } .ty-breadcrumb a { color: #666; font-size: 14px; } .ty-breadcrumb a:hover { text-decoration: none; color: #00a0e8; } .ty-breadcrumb a:hover { font-weight: bold; } .ty-breadcrumb a.current:hover { color: #666; font-weight: bold; cursor: default; } .ty-breadcrumb a.current { font-weight: bold; } .four-icon.ty-transfer-operation { padding-top: 70px; } .ty-transfer-operation .ty-transfer-btn-zhiding, .ty-transfer-operation .ty-transfer-btn-zhidi { background-image: url(../../../assets/images/zhiding-zhidi.png); background-size: 27px 108px; background-repeat: no-repeat; } .ty-transfer-operation .ty-transfer-btn-zhiding:hover, .ty-transfer-operation .ty-transfer-btn-zhiding.active, .ty-transfer-operation .ty-transfer-btn-zhiding.active:hover { background-position: 4px -50px; } .ty-transfer-operation .ty-transfer-btn-zhidi:hover, .ty-transfer-operation .ty-transfer-btn-zhidi.active, .ty-transfer-operation .ty-transfer-btn-zhidi.active:hover { background-position: 4px -78px; } .ty-transfer-operation .ty-transfer-btn-zhiding.normal { background-position: 4px 4px; } .ty-transfer-operation .ty-transfer-btn-zhidi.normal { background-position: 4px -25px; } .ty-transfer-operation .ty-transfer-btn-zhiding.normal.active, .ty-transfer-operation .ty-transfer-btn-zhiding.normal:hover { background-position: 4px -50px; } .ty-transfer-operation .ty-transfer-btn-zhidi.normal.active, .ty-transfer-operation .ty-transfer-btn-zhidi.normal:hover { background-position: 4px -78px; } .ty-transfer-operation .ty-transfer-btn-zhiding.normal.disabled, .ty-transfer-operation .ty-transfer-btn-zhidi.normal.disabled { cursor: not-allowed; border: 1px solid #d9d9d9; background-color: #f3f3f3; } .clearboth { clear: both; } .dib { display: inline-block; } .fl { float: left; } .fr { float: right; } .ml5 { margin-left: 5px; } .ml10 { margin-left: 10px; } .mt20 { margin-top: 13px; } .mt50 { margin-top: 20px; } .mt10 { margin-top: 10px; } .ml20 { margin-left: 20px; } .div-h, .ty-p { line-height: 1.5; } .color9 { color: #999; } .color-blue { color: #00a0e8; } .p16 { padding: 16px; } .p24 { padding: 24px; } .bgf7 { padding: 10px; background: #f7f7f7; } .bg999 { padding: 10px; background: #999; } .ty-relative { position: relative; } .fs14 { font-size: 14px; } .fw { font-weight: 600; } </style>