shannon-transfer.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. <template>
  2. <div class="shannon-transfer">
  3. <div class="shannon-transfer-panel">
  4. <div class="shannon-transfer-panel__header">
  5. <div class="item-flex justify">
  6. <div class="item-flex justify cursor" @click="leftAllf">
  7. <span class="label-block" :class="leftAll ? 'is-checked' : ''"></span>
  8. <span class="label-name">{{ title[0] }}</span>
  9. </div>
  10. <span class="label-number">{{ leftSelectArr.length }}/{{ leftArr.length }}</span>
  11. </div>
  12. </div>
  13. <div class="shannon-transfer-panel__body">
  14. <el-input placeholder="请输入内容" prefix-icon="el-icon-search shannon-transfer-panel__filter"></el-input>
  15. <div class="shannon-transfer-panel__list is-filterable">
  16. <div class="shannon-transfer-panel__item" v-for="(item, index) in newArr[0]" :key="item.id">
  17. <div class="item-flex cursor" @click="leftThis(item, index)">
  18. <span class="label-block" :class="item.isChecked ? 'is-checked' : ''"></span>
  19. <span class="label-name">{{ item.label }}</span>
  20. </div>
  21. <!-- <div>{{ newArr }}</div> -->
  22. </div>
  23. </div>
  24. <p class="shannon-transfer-panel__empty">无匹配数据</p>
  25. <p class="shannon-transfer-panel__empty">无数据</p>
  26. </div>
  27. </div>
  28. <div class="shannon-transfer__buttons">
  29. <el-button type="primary" class="shannon-transfer__button" @click="moveData('left')">
  30. <span><i class="el-icon-arrow-left"></i></span>
  31. </el-button>
  32. <el-button type="primary" class="shannon-transfer__button" @click="moveData('right')">
  33. <span><i class="el-icon-arrow-right"></i></span>
  34. </el-button>
  35. </div>
  36. <div class="shannon-transfer-panel">
  37. <div class="shannon-transfer-panel__header">
  38. <div class="item-flex justify">
  39. <div class="item-flex justify cursor" @click="rightAllf">
  40. <span class="label-block" :class="rightAll ? 'is-checked' : ''"></span>
  41. <span class="label-name">{{ title[0] }}</span>
  42. </div>
  43. <span class="label-number">{{ rightSelectArr.length }}/{{ rightArr.length }}</span>
  44. </div>
  45. </div>
  46. <div class="shannon-transfer-panel__body">
  47. <el-input placeholder="请输入内容" prefix-icon="el-icon-search shannon-transfer-panel__filter"></el-input>
  48. <div class="shannon-transfer-panel__list is-filterable">
  49. <div class="shannon-transfer-panel__item" v-for="item in newArr[1]" :key="item.id">
  50. <div class="item-flex cursor" @click="rightThis(item)">
  51. <span class="label-block" :class="item.isChecked ? 'is-checked' : ''"></span>
  52. <span class="label-name">{{ item.label }}</span>
  53. </div>
  54. <div></div>
  55. </div>
  56. </div>
  57. <p class="shannon-transfer-panel__empty">无匹配数据</p>
  58. <p class="shannon-transfer-panel__empty">无数据</p>
  59. </div>
  60. </div>
  61. </div>
  62. </template>
  63. <script>
  64. export default {
  65. props: {
  66. arr: {
  67. type: Array,
  68. default: () => [
  69. {
  70. id: 1,
  71. label: '测试一号',
  72. isChecked: false
  73. },
  74. {
  75. id: 2,
  76. label: '测试二号',
  77. isChecked: false
  78. }
  79. ]
  80. },
  81. title: {
  82. type: Array,
  83. default: () => ['待选列表', '已选列表']
  84. }
  85. },
  86. data() {
  87. return {
  88. //左右数据 左右勾选数据
  89. leftArr: [],
  90. rightArr: [],
  91. leftSelectArr: [],
  92. rightSelectArr: [],
  93. leftAll: false,
  94. rightAll: false
  95. };
  96. },
  97. watch: {
  98. rightSelectArr: {
  99. deep: true,
  100. handler(n) {
  101. console.log(n);
  102. }
  103. }
  104. },
  105. computed: {
  106. newArr() {
  107. let newData = [];
  108. if (this.rightArr.length == 0) {
  109. newData[0] = this.arr;
  110. this.leftArr = this.arr;
  111. } else {
  112. newData[0] = this.leftArr;
  113. this.rightArr = this.rightArr;
  114. }
  115. newData[1] = this.rightArr;
  116. return newData;
  117. }
  118. },
  119. methods: {
  120. leftAllf() {
  121. this.leftArr.map((item) => {
  122. if (!item.isChecked) {
  123. item.isChecked = true;
  124. } else {
  125. item.isChecked = false;
  126. }
  127. });
  128. this.allTrue(0);
  129. },
  130. rightAllf() {
  131. this.rightArr.map((item) => {
  132. if (!item.isChecked) {
  133. item.isChecked = true;
  134. } else {
  135. item.isChecked = false;
  136. }
  137. });
  138. this.allTrue(1);
  139. },
  140. leftThis(item, index) {
  141. item.isChecked = !item.isChecked;
  142. if (item.isChecked) {
  143. this.leftSelectArr.push(item.id);
  144. } else {
  145. this.leftSelectArr.map((its, inx) => {
  146. if (item.id == its) {
  147. this.leftSelectArr.splice(inx, 1);
  148. }
  149. });
  150. }
  151. this.allTrue(0);
  152. },
  153. rightThis(item) {
  154. item.isChecked = !item.isChecked;
  155. if (item.isChecked) {
  156. this.rightSelectArr.push(item.id);
  157. } else {
  158. this.rightSelectArr.map((its, inx) => {
  159. if (item.id == its) {
  160. this.rightSelectArr.splice(inx, 1);
  161. }
  162. });
  163. }
  164. this.allTrue(1);
  165. },
  166. moveData(direction) {
  167. if (direction == 'right' && this.leftSelectArr.length !== 0) {
  168. this.rightArr.push(this.leftSelectArr);
  169. let thisLeft = this.leftArr.filter((item, index) => {
  170. return this.leftSelectArr[index] !== item.id;
  171. });
  172. let thisRight = this.leftArr.filter((item, index) => {
  173. item.isChecked = false;
  174. return this.leftSelectArr[index] == item.id;
  175. });
  176. console.log(thisLeft);
  177. console.log(thisRight);
  178. this.leftArr = thisLeft;
  179. this.rightArr = thisRight;
  180. this.leftSelectArr = [];
  181. } else if (direction == 'left' && this.rightSelectArr.length !== 0) {
  182. this.leftArr.push(this.rightSelectArr);
  183. let thisRight = this.rightArr.filter((item, index) => {
  184. return this.rightSelectArr[index] !== item.id;
  185. });
  186. let thisLeft = this.rightArr.filter((item, index) => {
  187. item.isChecked = false;
  188. return this.rightSelectArr[index] == item.id;
  189. });
  190. console.log(thisLeft);
  191. console.log(thisRight);
  192. this.leftArr = thisLeft;
  193. this.rightArr = thisRight;
  194. this.rightSelectArr = [];
  195. }
  196. },
  197. allTrue(sun) {
  198. if (sun == 0) {
  199. let leftAll = false;
  200. this.newArr[0].map((item) => {
  201. leftAll = item.isChecked;
  202. if (leftAll == false) {
  203. this.leftAll = 'Multiple';
  204. } else {
  205. this.leftAll = 'all';
  206. }
  207. });
  208. this.leftAll = leftAll;
  209. } else {
  210. let rightAll = false;
  211. this.newArr[1].map((item) => {
  212. rightAll = item.isChecked;
  213. });
  214. this.rightAll = rightAll;
  215. }
  216. }
  217. }
  218. };
  219. </script>
  220. <style lang="scss" scoped>
  221. $name: shannon-transfer;
  222. $panelName: #{$name}-panel;
  223. $white: white;
  224. .backWhite {
  225. background: $white;
  226. }
  227. $eaeff: #0eaeff;
  228. .color0eaeff {
  229. color: $eaeff;
  230. }
  231. .cursor {
  232. cursor: pointer;
  233. }
  234. .#{$name} {
  235. &-panel {
  236. border: 1px solid #ebeef5;
  237. border-radius: 4px;
  238. overflow: hidden;
  239. @extend .backWhite;
  240. display: inline-block;
  241. vertical-align: middle;
  242. width: 200px;
  243. max-height: 100%;
  244. -webkit-box-sizing: border-box;
  245. box-sizing: border-box;
  246. position: relative;
  247. .#{$name}-panel__header {
  248. height: 40px;
  249. line-height: 40px;
  250. background: #f5f7fa;
  251. margin: 0;
  252. padding-left: 15px;
  253. border-bottom: 1px solid #ebeef5;
  254. -webkit-box-sizing: border-box;
  255. box-sizing: border-box;
  256. color: #000;
  257. }
  258. .#{$panelName}__body {
  259. height: 246px;
  260. .#{$panelName}__filter {
  261. text-align: center;
  262. margin: 15px;
  263. -webkit-box-sizing: border-box;
  264. box-sizing: border-box;
  265. display: block;
  266. width: auto;
  267. }
  268. .#{$panelName}__list {
  269. margin: 0;
  270. padding: 6px 0;
  271. list-style: none;
  272. height: 246px;
  273. overflow: auto;
  274. -webkit-box-sizing: border-box;
  275. box-sizing: border-box;
  276. }
  277. .#{$panelName}__item {
  278. line-height: 30px;
  279. margin: 0 15px;
  280. .label-block {
  281. margin-top: 8px;
  282. }
  283. }
  284. .el-input--prefix {
  285. margin: 15px;
  286. width: calc(100% - 30px);
  287. .el-input__inner {
  288. border-radius: 30px;
  289. }
  290. }
  291. }
  292. .item-flex {
  293. display: flex;
  294. &.justify {
  295. justify-content: space-between;
  296. }
  297. }
  298. .label-block {
  299. position: relative;
  300. height: 14px;
  301. width: 14px;
  302. border-radius: 3px;
  303. margin-top: 13px;
  304. border: 1px solid #dcdfe6;
  305. @extend .backWhite;
  306. cursor: pointer;
  307. &.is-checked {
  308. background: $eaeff;
  309. border-color: $eaeff;
  310. }
  311. &.is-checked {
  312. background: $eaeff;
  313. border-color: $eaeff;
  314. }
  315. &:hover {
  316. border-color: $eaeff;
  317. }
  318. &::after {
  319. content: '';
  320. position: absolute;
  321. left: 2px;
  322. top: 2px;
  323. width: 50%;
  324. height: 25%;
  325. border: 2px solid #fff;
  326. border-radius: 1px;
  327. border-top: none;
  328. border-right: none;
  329. background: transparent;
  330. transform: rotate(-45deg);
  331. }
  332. }
  333. .label-name {
  334. margin-left: 10px;
  335. }
  336. }
  337. &__buttons {
  338. display: inline-block;
  339. vertical-align: middle;
  340. padding: 0 30px;
  341. .#{$name}__button {
  342. &:first-child {
  343. margin-bottom: 10px;
  344. }
  345. span {
  346. font-size: 14px;
  347. }
  348. }
  349. }
  350. }
  351. </style>