tree.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. <template>
  2. <div>
  3. <!--
  4. 拖拽
  5. draggable
  6. @node-drop="handleDrop"
  7. @node-drag-enter="handleDragEnter"
  8. :allow-drop="allowDrop"
  9. -->
  10. <el-tree
  11. :props="props"
  12. :load="loadNode"
  13. node-key="id"
  14. lazy
  15. show-checkbox
  16. :expand-on-click-node="expand"
  17. ref="tree"
  18. v-loading="loading"
  19. @check-change="handleCheckChange"
  20. >
  21. <template slot-scope="{data,node}">
  22. <div class="row">
  23. <span class="content">{{data.name}}</span>
  24. <span class="handle">
  25. <el-button type="text" size="mini" @click.stop.prevent="addNode(data,node)">新增</el-button>
  26. <el-button
  27. v-if="data.id!=-1"
  28. type="text"
  29. size="mini"
  30. @click.stop.prevent="delNode(data,node)"
  31. >删除</el-button>
  32. <el-button
  33. v-if="data.id!=-1"
  34. type="text"
  35. size="mini"
  36. @click.stop.prevent="putNode(data,node)"
  37. >更新</el-button>
  38. </span>
  39. </div>
  40. </template>
  41. </el-tree>
  42. </div>
  43. </template>
  44. <script>
  45. // import { getNode, addNode, delNode, putNode } from "@/Api/tree";
  46. import { getNode, addNode, delNode, putNode } from "@/Api/dept";
  47. export default {
  48. name: "tree",
  49. data() {
  50. return {
  51. props: {
  52. label: "name",
  53. children: "zones",
  54. isLeaf: (data, node) => {
  55. // console.log("isLeaf",data,node);
  56. //算出是否是叶子 true是叶子,false不是🍃
  57. if (data.id != -1) {
  58. // console.log(1111,data,node);
  59. // console.log(parseInt((data.rght - data.lft - 1) / 2));
  60. if (!data.hasOwnProperty("rght")) return true; //如果没有rght属性 则就是叶子节点
  61. return parseInt((data.rght - data.lft - 1) / 2) == 0;
  62. }
  63. return false;
  64. }
  65. },
  66. loading: false,
  67. expand: true //是否点击任意地方展开
  68. };
  69. },
  70. methods: {
  71. //加载节点
  72. loadNode(node, resolve) {
  73. // console.log(resolve);
  74. if (node.level === 0) {
  75. let data = [
  76. {
  77. name: "树容器",
  78. id: -1
  79. }
  80. ];
  81. resolve(data);
  82. this.$nextTick(() => {
  83. this.$emit("check-node", this.$refs.tree.getCheckedNodes()); //返回所有节点
  84. });
  85. // return resolve(data);
  86. } else if (node.level === 1) {
  87. getNode().then(res => {
  88. // console.log(res.data);
  89. // res.data.leaf = false
  90. resolve(res.data);
  91. this.$nextTick(() => {
  92. this.$emit("check-node", this.$refs.tree.getCheckedNodes()); //返回所有节点
  93. });
  94. });
  95. } else {
  96. // console.log(node);
  97. let parent_id = node.data.id;
  98. let data = { parent_id };
  99. getNode(data)
  100. .then(res => {
  101. // console.log(res);
  102. resolve(res.data);
  103. this.$nextTick(() => {
  104. this.$emit("check-node", this.$refs.tree.getCheckedNodes()); //返回所有节点
  105. });
  106. })
  107. .catch(e => {
  108. // console.log(e);
  109. resolve({});
  110. });
  111. }
  112. },
  113. //添加节点
  114. addNode(data, node) {
  115. // this.expand = false;
  116. // console.log(data, node);
  117. this.$prompt("请输入名字", "插入节点", {
  118. confirmButtonText: "确定",
  119. cancelButtonText: "取消"
  120. })
  121. .then(({ value }) => {
  122. console.log(data);
  123. let rep =
  124. data.id == -1
  125. ? { name: value }
  126. : { name: value, parent_id: data.id };
  127. this.loading = true;
  128. addNode(rep).then(res => {
  129. let childrenNode = res.data.node;
  130. let msg = res.data.message;
  131. this.$refs.tree.append(childrenNode, node); //插入节点
  132. node.isLeaf = false; //自己有叶子了,则自己不是叶子
  133. this.$message({
  134. type: "success",
  135. message: msg
  136. });
  137. console.log("插入成功", res);
  138. this.loading = false;
  139. // this.expand = true;
  140. });
  141. })
  142. .catch(e => {
  143. this.expand = true;
  144. console.log(e);
  145. });
  146. },
  147. //删除节点
  148. delNode(data, node) {
  149. // this.expand = false;
  150. // console.log(data, node);
  151. if (data.id == -1) {
  152. this.$message({
  153. type: "warring",
  154. message: "顶级容器不能删除"
  155. });
  156. return;
  157. }
  158. this.loading = true;
  159. delNode({ id: data.id })
  160. .then(res => {
  161. console.log("删除节点", res);
  162. this.$refs.tree.remove(node);
  163. this.loading = false;
  164. this.$nextTick(() => {
  165. this.$emit("check-node", this.$refs.tree.getCheckedNodes()); //返回所有节点
  166. });
  167. // this.expand = true;
  168. })
  169. .catch(e => {
  170. // this.expand = true;
  171. console.log(e);
  172. });
  173. },
  174. //更新节点 更新名字
  175. putNode(data, node) {
  176. // this.expand = false;
  177. this.$prompt("请输入名字", "修改节点", {
  178. confirmButtonText: "确定",
  179. cancelButtonText: "取消"
  180. })
  181. .then(({ value }) => {
  182. this.loading = true;
  183. let rep = {
  184. id: data.id,
  185. name: value
  186. };
  187. putNode(rep)
  188. .then(res => {
  189. console.log("更新成功");
  190. console.log(data.id, data);
  191. data.name = value;
  192. this.$refs.tree.updateKeyChildren(data.id, data);
  193. // this.$forceUpdate();
  194. this.loading = false;
  195. this.$nextTick(() => {
  196. this.$emit("check-node", this.$refs.tree.getCheckedNodes()); //返回所有节点
  197. });
  198. })
  199. .catch(e => {
  200. this.loading = false;
  201. console.log(e);
  202. });
  203. // this.expand = true;
  204. })
  205. .catch(e => {
  206. // this.expand = true;
  207. this.loading = false;
  208. console.log("取消修改", e);
  209. });
  210. },
  211. /** 选择状态改变
  212. * @param {Object} data 节点详细数据
  213. * @param {Boolean} checked 是否被选中
  214. * @param {Boolean} indeterminate 是否内部被选择部分
  215. */
  216. handleCheckChange(data, checked, indeterminate) {
  217. // console.log(data, checked, indeterminate);
  218. this.$emit("check-node", this.$refs.tree.getCheckedNodes()); //返回所有节点
  219. },
  220. // 以下未使用 ✳
  221. //拖拽 更新节点
  222. handleDrop(draggingNode, dropNode, dropType, ev) {
  223. console.log(draggingNode.data, dropNode.data);
  224. let from = draggingNode.data; //拖拽的节点
  225. let to = dropNode.data; //到达某个点
  226. //更新 某个节点 与 另一个节点 在 同一个父级下
  227. let data = {
  228. id: from.id,
  229. name: from.name,
  230. parent_id: to.parent_id
  231. };
  232. this.loading = true;
  233. putNode(data).then(res => {
  234. this.loading = false;
  235. console.log(res);
  236. });
  237. },
  238. //拖拽 进入
  239. handleDragEnter(draggingNode, dropNode, ev) {
  240. console.log("tree drag enter: ", dropNode);
  241. let from = draggingNode.data; //拖拽的节点
  242. let to = dropNode.data; //到达某个点
  243. let data = {
  244. id: from.id,
  245. name: from.name,
  246. parent_id: to.id
  247. };
  248. this.loading = true;
  249. putNode(data).then(res => {
  250. //拖拽进入成功
  251. console.log(res);
  252. this.loading = false;
  253. });
  254. },
  255. //拖拽
  256. allowDrop(draggingNode, dropNode, type) {
  257. // console.log(dropNode);
  258. if (dropNode.isLeaf) {
  259. return false;
  260. } else {
  261. // console.log(dropNode);
  262. return true;
  263. }
  264. }
  265. }
  266. };
  267. </script>
  268. <style lang="less">
  269. .row {
  270. flex: 1;
  271. display: flex;
  272. align-items: center;
  273. justify-content: space-between;
  274. font-size: 14px;
  275. // padding-right: 8px;
  276. .handle {
  277. // background-color: #ccc;
  278. padding: 0px 5px;
  279. // border-radius: 5px;
  280. box-shadow: -2px -2px 2px #ccc inset;
  281. line-height: 15px;
  282. margin-left: 30px;
  283. }
  284. }
  285. </style>