sideM.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <div v-drag class="mobile-nav-button" draggable="false" @click="showMobileNav($event)">
  3. <appstore-outlined style="font-size: 20px; color: white" />
  4. </div>
  5. <a-drawer v-model:visible="visible" :width="210" :closable="false" placement="left">
  6. <header class="snowy-header-logo mobile-nav">
  7. <div class="snowy-header-left">
  8. <div class="logo-bar">
  9. <img class="logo" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
  10. <span>{{ sysBaseConfig.SNOWY_SYS_NAME }}</span>
  11. </div>
  12. </div>
  13. </header>
  14. <a-menu style="width: 208px; margin-left: -24px" mode="inline" @select="onSelect">
  15. <NavMenu :nav-menus="menu"></NavMenu>
  16. </a-menu>
  17. </a-drawer>
  18. </template>
  19. <script>
  20. import NavMenu from './NavMenu.vue'
  21. import { globalStore } from '@/store'
  22. import { mapState } from 'pinia'
  23. export default {
  24. components: {
  25. NavMenu
  26. },
  27. directives: {
  28. drag(el) {
  29. const oDiv = el // 当前元素
  30. let firstTime = ''
  31. let lastTime = ''
  32. // 禁止选择网页上的文字
  33. // document.onselectstart = function() {
  34. // return false;
  35. // };
  36. oDiv.onmousedown = function (e) {
  37. // 鼠标按下,计算当前元素距离可视区的距离
  38. const disX = e.clientX - oDiv.offsetLeft
  39. const disY = e.clientY - oDiv.offsetTop
  40. document.onmousemove = function (e) {
  41. oDiv.setAttribute('drag-flag', true)
  42. firstTime = new Date().getTime()
  43. // 通过事件委托,计算移动的距离
  44. const l = e.clientX - disX
  45. const t = e.clientY - disY
  46. // 移动当前元素
  47. if (t > 0 && t < document.body.clientHeight - 50) {
  48. oDiv.style.top = `${t}px`
  49. }
  50. if (l > 0 && l < document.body.clientWidth - 50) {
  51. oDiv.style.left = `${l}px`
  52. }
  53. }
  54. document.onmouseup = function () {
  55. lastTime = new Date().getTime()
  56. if (lastTime - firstTime > 200) {
  57. oDiv.setAttribute('drag-flag', false)
  58. }
  59. document.onmousemove = null
  60. document.onmouseup = null
  61. }
  62. // return false不加的话可能导致黏连,就是拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
  63. return false
  64. }
  65. }
  66. },
  67. data() {
  68. return {
  69. visible: false,
  70. menu: []
  71. }
  72. },
  73. computed: {
  74. ...mapState(globalStore, ['sysBaseConfig'])
  75. },
  76. created() {
  77. const menu = this.$router.getMenu()
  78. this.menu = this.filterUrl(menu)
  79. },
  80. methods: {
  81. showMobileNav(e) {
  82. const isdrag = e.currentTarget.getAttribute('drag-flag')
  83. this.visible = true
  84. if (isdrag === 'true') {
  85. return false
  86. } else {
  87. this.visible = true
  88. }
  89. },
  90. // 当菜单被选中时
  91. onSelect(obj) {
  92. const pathLength = obj.keyPath.length
  93. const path = obj.keyPath[pathLength - 1]
  94. this.$router.push({ path })
  95. this.visible = false
  96. },
  97. // 转换外部链接的路由
  98. filterUrl(map) {
  99. map.forEach((item, index) => {
  100. item.meta = item.meta ? item.meta : {}
  101. // 处理隐藏
  102. if (item.meta.hidden) {
  103. map.splice(index, 1)
  104. }
  105. // 处理http
  106. // eslint-disable-next-line eqeqeq
  107. if (item.meta.type == 'iframe') {
  108. item.path = `/i/${item.name}`
  109. }
  110. // 递归循环
  111. if (item.children && item.children.length > 0) {
  112. item.children = this.filterUrl(item.children)
  113. }
  114. })
  115. return map
  116. }
  117. }
  118. }
  119. </script>
  120. <style lang="less" scoped>
  121. .mobile-nav {
  122. margin-top: -24px;
  123. margin-left: -24px;
  124. margin-right: -24px;
  125. }
  126. .mobile-nav-button {
  127. position: fixed;
  128. bottom: 10px;
  129. left: 10px;
  130. z-index: 10;
  131. width: 50px;
  132. height: 50px;
  133. background: var(--primary-color);
  134. box-shadow: 0 2px 12px 0 var(--primary-color);
  135. border-radius: 50%;
  136. display: flex;
  137. align-items: center;
  138. justify-content: center;
  139. }
  140. </style>