main.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <template>
  2. <div class="flex pd-20">
  3. <el-card class="box-card flex1">
  4. <div slot="header" class="flex jc-sb">
  5. <span>{{leftNum}}项</span>
  6. <el-checkbox v-if="showAllCheck" v-model="allChecked" @change="checkChang">默认全部引用</el-checkbox>
  7. </div>
  8. <div v-loading="leftloading">
  9. <el-scrollbar :style="scrollbarStyle">
  10. <el-tree show-checkbox
  11. :data="leftTreeData" @check-change="checkChange('leftTree')"
  12. :props="defaultProps" :expand-on-click-node="false"
  13. highlight-current node-key="id"
  14. ref="leftTree" @node-expand="nodeExpand">
  15. </el-tree>
  16. </el-scrollbar>
  17. </div>
  18. </el-card>
  19. <div class="flex flex-d-c flex-center" style="width:50px;">
  20. <div style="width: 32px;"><el-button @click="addTree" :type="leftNum <= 0 ? '' : 'success'" :disabled="leftNum <= 0||isNoAdd" size="mini" icon="el-icon-arrow-right"></el-button></div>
  21. <div style="margin-top: 10px; width: 32px;"><el-button @click="delTree" :type="rightNum <= 0 ? '' : 'success'" :disabled="rightNum <= 0" size="mini" icon="el-icon-arrow-left"></el-button></div>
  22. </div>
  23. <el-card class="box-card flex1">
  24. <div slot="header" class="clearfix">
  25. <span>{{rightNum}}项</span>
  26. </div>
  27. <div v-loading="rightloading">
  28. <el-scrollbar :style="scrollbarStyle">
  29. <el-tree show-checkbox
  30. :data="rightTreeData" @check-change="checkChange('rightTree')"
  31. :props="rightProps?rightProps:defaultProps" :expand-on-click-node="false"
  32. highlight-current node-key="id"
  33. ref="rightTree" :default-expanded-keys="rightExpands">
  34. </el-tree>
  35. </el-scrollbar>
  36. </div>
  37. </el-card>
  38. </div>
  39. </template>
  40. <script>
  41. export default {
  42. name: "treeTree",
  43. props: {
  44. leftTreeData: {
  45. type: Array,
  46. default: function () {
  47. return [];
  48. }
  49. },
  50. scrollbarStyle:{
  51. type:String,
  52. default:'height:calc(100vh - 400px)'
  53. },
  54. showAllCheck:{
  55. type:Boolean,
  56. default:false
  57. },
  58. rightProps:{
  59. type:Object,
  60. default: function () {
  61. return null;
  62. }
  63. },
  64. leftloading:{
  65. type:Boolean,
  66. default:false,
  67. },
  68. rightloading:{
  69. type:Boolean,
  70. default:false,
  71. },
  72. isNoAdd:{
  73. type:Boolean,
  74. default:false,
  75. },//不准添加树
  76. },
  77. computed: {
  78. },
  79. data(){
  80. return{
  81. defaultProps: {
  82. children: 'children',
  83. label: 'title',
  84. },
  85. leftNum:0,
  86. rightTreeData:[],
  87. rightNum:0,
  88. rightExpands:[],
  89. allChecked:false,
  90. }
  91. },
  92. methods:{
  93. addTree(){
  94. console.log(11111,'添加');
  95. if(this.rightTreeData.length < 1){
  96. //直接把左边勾选的树复制到右侧
  97. //console.log(this.$refs.leftTree.getCheckedNodes())
  98. let allTree = JSON.parse(JSON.stringify(this.leftTreeData));
  99. //把半选和选中的数组key合并
  100. let keys = this.$refs.leftTree.getCheckedKeys().concat(this.$refs.leftTree.getHalfCheckedKeys());
  101. //console.log(keys,'keys');
  102. //console.log(allTree,'allTree');
  103. this.getRightTree(allTree,keys);
  104. this.rightTreeData = allTree;
  105. this.$emit('onAddTree',this.rightTreeData);
  106. }else{
  107. //只增加右侧树没有的节点,不会覆盖右侧树多余的节点
  108. let checkNodes = this.$refs.leftTree.getCheckedNodes(false,true);
  109. //console.log(checkNodes)
  110. let rIdMap = new Map();
  111. checkNodes.forEach((data)=>{
  112. rIdMap.set(data.id,data)
  113. })
  114. let lIdSet = new Set();
  115. this.getRightTreeData(lIdSet,this.rightTreeData);
  116. //在右侧id减去左侧有的id,剩下的就是新增的id
  117. lIdSet.forEach((id)=>{
  118. rIdMap.delete(id);
  119. })
  120. //console.log(rIdSet)
  121. let addMap = new Map();
  122. rIdMap.forEach((data)=>{
  123. if(data.parentId != '0'){
  124. //在左侧树能找到父节点的,新增
  125. let lNode = this.$refs.rightTree.getNode(data.parentId);
  126. if(lNode){
  127. addMap.set(data,lNode.data.id);
  128. }
  129. }
  130. })
  131. //把半选和选中的数组key合并
  132. let keys = this.$refs.leftTree.getCheckedKeys().concat(this.$refs.leftTree.getHalfCheckedKeys());
  133. const myArray = Array.from(addMap.keys());
  134. let myright= JSON.parse(JSON.stringify(myArray));
  135. this.getRightTree(myright,keys);
  136. myright.forEach((data)=>{
  137. this.$refs.rightTree.append(data,data.parentId);
  138. })
  139. // addMap.forEach((value,key)=>{
  140. // this.$refs.rightTree.append(key,value);
  141. // })
  142. }
  143. },
  144. getRightTree(arr,keys){
  145. //对比所有的node和选中的key
  146. for (let i = arr.length-1; i >= 0; i--) {
  147. let isIn = false;
  148. if(this.rightProps){
  149. //名称使用传入的字段
  150. arr[i][this.rightProps.label] = arr[i].title;
  151. }
  152. for (let j = keys.length-1; j >= 0; j--) {
  153. if(keys[j] == arr[i].id){
  154. isIn = true;
  155. //已经匹配到的key移除,节省性能
  156. keys.splice(j,1);
  157. break;
  158. }
  159. }
  160. if(isIn){
  161. //包含在选中的节点,如果有childer继续递归判断
  162. if(arr[i].children && arr[i].children.length){
  163. this.getRightTree(arr[i].children,keys);
  164. }
  165. }else{
  166. //不包含在选中key的node删除
  167. arr.splice(i,1);
  168. }
  169. }
  170. },
  171. getRightTreeData(set,arr){
  172. arr.forEach((data)=>{
  173. set.add(data.id);
  174. if(data.children && data.children.length){
  175. this.getRightTreeData(set,data.children);
  176. }
  177. })
  178. },
  179. delTree(){
  180. let delNodes = this.$refs.rightTree.getCheckedNodes();
  181. //只把选中的节点移除
  182. delNodes.forEach((node)=>{
  183. //console.log(node)
  184. this.$refs.rightTree.remove(node);
  185. this.$refs.leftTree.setChecked(node.id,false);
  186. })
  187. this.getRightNum();
  188. this.getLeftNum();
  189. this.$emit('onDelTree',delNodes);
  190. },
  191. nodeExpand(data){
  192. this.rightExpands = this.rightExpands.concat([data.id]);
  193. },
  194. checkChange(treeName){
  195. switch (treeName) {
  196. case 'leftTree':
  197. this.getLeftNum();
  198. break;
  199. case 'rightTree':
  200. this.getRightNum();
  201. break;
  202. }
  203. },
  204. setRightTree(data){
  205. this.rightTreeData = data;
  206. let ids = [];
  207. for (let i = 0; i < data.length; i++) {
  208. this.getLeafIds(ids,data[i])
  209. }
  210. //在左边把右边的节点勾选上
  211. this.$nextTick(()=>{
  212. this.$refs.leftTree.setCheckedKeys(ids,true);
  213. })
  214. },
  215. getTreeAllId(treeName){
  216. let tree = this.$refs[treeName];
  217. if(this.allChecked){
  218. tree = this.$refs.leftTree;
  219. }
  220. //console.log(tree.data);
  221. let ids = [];
  222. for (let i = 0; i < tree.data.length; i++) {
  223. this.getIds(ids,tree.data[i]);
  224. }
  225. //console.log(obj)
  226. return ids.join(',');
  227. },
  228. getIds(ids,data){
  229. ids.push(data.id);
  230. if(data.children && data.children.length){
  231. for (let i = 0; i < data.children.length; i++) {
  232. this.getIds(ids,data.children[i]);
  233. }
  234. }
  235. },
  236. getLeafIds(ids,data){
  237. if(data.children && data.children.length){
  238. for (let i = 0; i < data.children.length; i++) {
  239. this.getLeafIds(ids,data.children[i]);
  240. }
  241. }else{
  242. ids.push(data.id)
  243. }
  244. },
  245. checkChang(){
  246. this.$emit('onCheckAll');
  247. },
  248. getLeftNum(){
  249. let checkNum = this.$refs.leftTree.getCheckedKeys().length;
  250. let halfNum = this.$refs.leftTree.getHalfCheckedKeys().length;
  251. this.leftNum = checkNum+halfNum;
  252. },
  253. getRightNum(){
  254. let checkNum = this.$refs.rightTree.getCheckedKeys().length;
  255. let halfNum = this.$refs.rightTree.getHalfCheckedKeys().length;
  256. this.rightNum = checkNum+halfNum;
  257. }
  258. }
  259. };
  260. </script>