node_menu.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <template>
  2. <div class="flow-menu" ref="tool">
  3. <div v-for="(menu,index) in menuList" :key="index">
  4. <span class="ef-node-pmenu" @click="menu.open = !menu.open"><i :class="{'el-icon-caret-bottom': menu.open,'el-icon-caret-right': !menu.open}"></i>&nbsp;{{menu.name}}</span>
  5. <ul v-show="menu.open" class="ef-node-menu-ul">
  6. <draggable @end="end" @start="move" v-model="menu.children" :options="draggableOptions">
  7. <li v-for="(subMenu,index) in menu.children" class="ef-node-menu-li" :key="index" :type="subMenu.type">
  8. <i :class="subMenu.ico"></i> {{subMenu.name}}
  9. </li>
  10. </draggable>
  11. </ul>
  12. </div>
  13. </div>
  14. </template>
  15. <script>
  16. import draggable from 'vuedraggable'
  17. var mousePosition = {
  18. left: -1,
  19. top: -1
  20. }
  21. export default {
  22. data() {
  23. return {
  24. activeNames: '1',
  25. // draggable配置参数参考 https://www.cnblogs.com/weixin186/p/10108679.html
  26. draggableOptions: {
  27. preventOnFilter: false,
  28. sort: false,
  29. disabled: false,
  30. ghostClass: 'tt',
  31. // 不使用H5原生的配置
  32. forceFallback: true,
  33. // 拖拽的时候样式
  34. // fallbackClass: 'flow-node-draggable'
  35. },
  36. // 默认打开的左侧菜单的id
  37. defaultOpeneds: ['1', '2'],
  38. menuList: [
  39. {
  40. id: '1',
  41. type: 'group',
  42. name: '基础节点',
  43. ico: 'el-icon-video-play',
  44. open: true,
  45. children: [
  46. {
  47. id: '11',
  48. type: 'start',
  49. name: '流程开始',
  50. ico: 'el-icon-time',
  51. // 自定义覆盖样式
  52. style: {}
  53. }, {
  54. id: '12',
  55. type: 'task',
  56. name: '任务节点',
  57. ico: 'el-icon-odometer',
  58. // 自定义覆盖样式
  59. style: {}
  60. },{
  61. id: '11',
  62. type: 'end',
  63. name: '流程结束',
  64. ico: 'el-icon-switch-button',
  65. // 自定义覆盖样式
  66. style: {}
  67. },
  68. ]
  69. },
  70. {
  71. id: '2',
  72. type: 'group',
  73. name: '状态节点',
  74. ico: 'el-icon-video-pause',
  75. open: true,
  76. children: [
  77. {
  78. id: '21',
  79. type: 'judge',
  80. name: '判断节点',
  81. ico: 'el-icon-sort',
  82. // 自定义覆盖样式
  83. style: {}
  84. }, {
  85. id: '22',
  86. type: 'status',
  87. name: '任务状态',
  88. ico: 'el-icon-refresh-left',
  89. // 自定义覆盖样式
  90. style: {}
  91. }
  92. ]
  93. }
  94. ],
  95. nodeMenu: {}
  96. }
  97. },
  98. components: {
  99. draggable
  100. },
  101. created() {
  102. /**
  103. * 以下是为了解决在火狐浏览器上推拽时弹出tab页到搜索问题
  104. * @param event
  105. */
  106. if (this.isFirefox()) {
  107. document.body.ondrop = function (event) {
  108. // 解决火狐浏览器无法获取鼠标拖拽结束的坐标问题
  109. mousePosition.left = event.layerX
  110. mousePosition.top = event.clientY - 50
  111. event.preventDefault();
  112. event.stopPropagation();
  113. }
  114. }
  115. },
  116. methods: {
  117. // 根据类型获取左侧菜单对象
  118. getMenuByType(type) {
  119. for (let i = 0; i < this.menuList.length; i++) {
  120. let children = this.menuList[i].children;
  121. for (let j = 0; j < children.length; j++) {
  122. if (children[j].type === type) {
  123. return children[j]
  124. }
  125. }
  126. }
  127. },
  128. // 拖拽开始时触发
  129. move(evt, a, b, c) {
  130. var type = evt.item.attributes.type.nodeValue
  131. this.nodeMenu = this.getMenuByType(type)
  132. },
  133. // 拖拽结束时触发
  134. end(evt, e) {
  135. this.$emit('addNode', evt, this.nodeMenu, mousePosition)
  136. },
  137. // 是否是火狐浏览器
  138. isFirefox() {
  139. var userAgent = navigator.userAgent
  140. if (userAgent.indexOf("Firefox") > -1) {
  141. return true
  142. }
  143. return false
  144. }
  145. }
  146. }
  147. </script>