sideM.vue 3.6 KB

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