editableTree.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <template>
  2. <div id="areaTree" class="addrTree">
  3. <ul :id="treeId" class="ztree"></ul>
  4. </div>
  5. </template>
  6. <script>
  7. import $ from 'jquery'
  8. export default {
  9. name: 'editableTree',
  10. components: {},
  11. props: {
  12. treeData: {
  13. // 树 data
  14. type: Array,
  15. default() {
  16. return []
  17. },
  18. },
  19. editable: {
  20. // 是否可编辑
  21. type: Boolean,
  22. default: true,
  23. },
  24. btn: {
  25. // 按钮集合
  26. type: Array,
  27. default() {
  28. return ['add', 'del']
  29. },
  30. },
  31. selectFirstNode: {
  32. // 是否默认选中第一个节点
  33. type: Boolean,
  34. default: false,
  35. },
  36. pIdKey: {
  37. type: String,
  38. default: 'parentId',
  39. },
  40. },
  41. data() {
  42. return {
  43. treeId: 'treeDemo' + new Date().getTime(),
  44. setting: {
  45. view: {
  46. addHoverDom: this.editable && this.showBtn('add') && this.addHoverDom,
  47. showIcon: false,
  48. showLine: true,
  49. selectedMulti: false,
  50. },
  51. edit: {
  52. enable: this.editable,
  53. showRemoveBtn: this.showBtn('del') && this.showRemoveBtn,
  54. showRenameBtn: this.showBtn('edit') && this.showRenameBtn,
  55. removeTitle: '删除',
  56. renameTitle: '修改',
  57. },
  58. data: {
  59. simpleData: {
  60. enable: true,
  61. idKey: 'id',
  62. pIdKey: this.pIdKey,
  63. rootPId: 0,
  64. },
  65. },
  66. callback: {
  67. onClick: this.zTreeOnClick,
  68. beforeDrag: this.beforeDrag,
  69. onExpand: this.onExpand,
  70. beforeRemove: this.beforeRemove,
  71. beforeEditName: this.beforeEditName,
  72. beforeRename: this.beforeRename,
  73. onRename: this.onRename,
  74. onRemove: this.onRemove,
  75. },
  76. },
  77. zNodes: [],
  78. log: '',
  79. className: 'dark',
  80. newCount: 1,
  81. curDragNodes: '',
  82. autoExpandNode: '',
  83. action: 'add',
  84. }
  85. },
  86. methods: {
  87. zTreeOnClick(event, treeId, treeNode) {
  88. this.$emit('treeNodeClick', treeNode)
  89. },
  90. beforeDrag(treeId, treeNodes) {
  91. return false
  92. },
  93. onExpand(event, treeId, treeNode) {
  94. if (treeNode === this.autoExpandNode) {
  95. this.className = this.className === 'dark' ? '' : 'dark'
  96. this.showLog('[ ' + this.getTime() + ' onExpand ]&nbsp;&nbsp;&nbsp;&nbsp;' + treeNode.name)
  97. }
  98. },
  99. remove() {
  100. // 移除节点
  101. var zTree = $.fn.zTree.getZTreeObj(this.treeId),
  102. nodes = zTree.getSelectedNodes(),
  103. treeNode = nodes[0]
  104. this.$emit('delTreeNode', treeNode)
  105. },
  106. beforeRemove(treeId, treeNode) {
  107. if (treeNode.id) {
  108. console.log('delete:', treeNode)
  109. this.$emit('deleteNode', treeNode) // 触发删除
  110. }
  111. return false
  112. },
  113. onRemove(e, treeId, treeNode) {
  114. this.showLog('[ ' + this.getTime() + ' onRemove ]&nbsp;&nbsp;&nbsp;&nbsp; ' + treeNode.name)
  115. },
  116. onRename(event, treeId, treeNode, isCancel) {
  117. console.log('rename')
  118. this.$emit('treeInfoEvent', treeNode, event)
  119. },
  120. beforeRename(treeId, treeNode, newName) {
  121. if (newName.length == 0) {
  122. alert('节点名称不能为空.')
  123. var zTree = $.fn.zTree.getZTreeObj(this.treeId)
  124. setTimeout(function () {
  125. zTree.editName(treeNode)
  126. }, 10)
  127. return false
  128. } else if (newName.length > 20) {
  129. alert('节点名称不能大于20个字符.')
  130. var zTree = $.fn.zTree.getZTreeObj(this.treeId)
  131. setTimeout(function () {
  132. zTree.editName(treeNode)
  133. }, 10)
  134. return false
  135. }
  136. return true
  137. },
  138. showLog(str) {
  139. if (!this.log) this.log = $('#log')
  140. this.log.append("<li class='" + this.className + "'>" + str + '</li>')
  141. if (this.log.children('li').length > 8) {
  142. this.log.get(0).removeChild(this.log.children('li')[0])
  143. }
  144. },
  145. getTime() {
  146. var now = new Date(),
  147. h = now.getHours(),
  148. m = now.getMinutes(),
  149. s = now.getSeconds(),
  150. ms = now.getMilliseconds()
  151. return h + ':' + m + ':' + s + ' ' + ms
  152. },
  153. addHoverDom(treeId, treeNode) {
  154. if (treeNode.addDis != true) {
  155. let _this = this
  156. var sObj = $('#' + treeNode.tId + '_span')
  157. if (treeNode.editNameFlag || $('#addBtn_' + treeNode.tId).length > 0) return
  158. var addStr =
  159. "<span class='button add' id='addBtn_" + treeNode.tId + "' title='新增' onfocus='this.blur();'>新增</span>"
  160. sObj.after(addStr)
  161. var btn = $('#addBtn_' + treeNode.tId)
  162. if (btn)
  163. btn.bind('click', function () {
  164. _this.add(treeNode)
  165. })
  166. }
  167. },
  168. add(treeNode) {
  169. // 增加子节点
  170. this.action = 'add' // 切换为add
  171. var zTree = $.fn.zTree.getZTreeObj(this.treeId)
  172. var isParent = false
  173. var nodes = zTree.getSelectedNodes()
  174. var treeNode2 = nodes[0]
  175. if (treeNode) {
  176. treeNode2 = zTree.addNodes(treeNode, {
  177. id: '',
  178. pId: treeNode.id,
  179. sysCode: treeNode.sysCode || treeNode.valStr,
  180. isParent: isParent,
  181. name: '新子节点' + this.newCount++,
  182. })
  183. } else {
  184. treeNode2 = zTree.addNodes(null, { id: '', pId: 0, isParent: isParent, name: '新节点' + this.newCount++ })
  185. }
  186. if (treeNode2) {
  187. zTree.editName(treeNode2[0])
  188. } else {
  189. alert('叶子节点被锁定,无法增加子节点')
  190. }
  191. },
  192. addTopNodes() {
  193. this.action = 'add'
  194. var zTree = $.fn.zTree.getZTreeObj(this.treeId)
  195. var treeNode = zTree.addNodes(null, { id: '', pId: 0, isParent: true, name: '新节点' + this.newCount++ })
  196. zTree.editName(treeNode[0])
  197. this.treeNodeMessage = zTree.getNodes() //Root节点信息
  198. this.$emit('RootNodes', this.treeNodeMessage)
  199. },
  200. showRemoveBtn(treeId, treeNode) {
  201. if (treeNode.removeDis == true) return false
  202. return true
  203. },
  204. showRenameBtn(treeId, treeNode) {
  205. if (treeNode.renameDis == true) return true
  206. return false
  207. },
  208. showBtn(button) {
  209. if (this.btn && this.btn.length > 0) {
  210. if (this.btn.findIndex((v) => v == button) > -1) {
  211. return true
  212. } else {
  213. return false
  214. }
  215. } else {
  216. return false
  217. }
  218. },
  219. selectFirstNodeFun() {
  220. // 选中第一个节点
  221. if (this.selectFirstNode) {
  222. const treeObj = $.fn.zTree.getZTreeObj(this.treeId)
  223. console.log(treeObj)
  224. let nodes = treeObj.getNodes()
  225. if (nodes.length > 0) {
  226. treeObj.selectNode(nodes[0])
  227. }
  228. }
  229. },
  230. selectNode(node) {
  231. const treeObj = $.fn.zTree.getZTreeObj(this.treeId)
  232. treeObj.selectNode(node)
  233. },
  234. queryTreeFun(data) {
  235. this.searchTree(data)
  236. },
  237. searchTree(info) {
  238. var treeObj = $.fn.zTree.getZTreeObj(this.treeId)
  239. if (info.val == '') {
  240. $.fn.zTree.init($('#' + this.treeId), this.setting, this.treeData)
  241. } else {
  242. function filter(node) {
  243. return node.name.indexOf(info.val) > -1
  244. }
  245. let nodes = treeObj.transformToArray(this.treeData)
  246. nodes = JSON.parse(JSON.stringify(nodes))
  247. nodes.map((item) => {
  248. if (item.hasOwnProperty('children')) {
  249. delete item.children
  250. }
  251. return item
  252. })
  253. nodes = nodes.filter((v) => v.name.indexOf(info.val) > -1)
  254. nodes = treeObj.transformTozTreeNodes(nodes)
  255. $.fn.zTree.init($('#' + this.treeId), this.setting, nodes)
  256. treeObj.expandAll(true)
  257. }
  258. },
  259. },
  260. watch: {
  261. treeData(val) {
  262. $.fn.zTree.init($('#' + this.treeId), this.setting, val)
  263. this.selectFirstNodeFun()
  264. },
  265. },
  266. mounted() {
  267. this.$nextTick(() => {
  268. $.fn.zTree.init($('#' + this.treeId), this.setting, this.treeData)
  269. this.selectFirstNodeFun()
  270. })
  271. },
  272. }
  273. </script>
  274. <style lang="scss" scope>
  275. .addrTree {
  276. position: relative;
  277. height: 100%;
  278. background: #fff;
  279. .tree_title {
  280. height: 30px;
  281. line-height: 30px;
  282. padding: 0 10px;
  283. background: #fafafa;
  284. button {
  285. float: right;
  286. margin: 4px 4px 0 0;
  287. }
  288. }
  289. .ztree {
  290. height: 100%;
  291. overflow: auto;
  292. padding: 5px;
  293. li span.button.add {
  294. background-position: -143px 0;
  295. }
  296. }
  297. [treenode_a] {
  298. vertical-align: middle;
  299. .button.add {
  300. margin-right: 2px;
  301. display: none;
  302. }
  303. &:hover {
  304. .button.add {
  305. display: inline-block;
  306. }
  307. }
  308. span {
  309. vertical-align: middle !important;
  310. }
  311. }
  312. [treenode_a].curSelectedNode {
  313. .button.add {
  314. display: inline-block;
  315. }
  316. }
  317. [treenode_switch] {
  318. vertical-align: middle;
  319. }
  320. }
  321. </style>