Kaynağa Gözat

feat: navbar 组件

王家程 10 ay önce
ebeveyn
işleme
ce76b9b418

+ 105 - 0
src/components/MNavBar/index.vue

@@ -0,0 +1,105 @@
+<!--
+ * @Author: wjc
+ * @Date: 2024-07-03 10:35:44
+ * @LastEditors: wjc
+ * @LastEditTime: 2024-07-04 15:24:50
+ * @Description: 
+-->
+<template>
+  <up-navbar
+    ref="mNavBarRef"
+    v-bind="$attrs"
+    :title="title"
+    placeholder
+    :bg-color="bgColor"
+    auto-back
+  >
+    <template #right>
+      <slot name="right">
+        <view v-if="rightMenu" class="right-box">
+          <view class="i-ep-more-filled wh-24px cursor-pointer" @click="triggerMore"></view>
+          <view v-if="showMore" class="overlay" @click="() => (showMore = false)"></view>
+          <view v-if="showMore" class="menu-box">
+            <view
+              v-for="menu in rightMenu"
+              :key="menu.command"
+              class="menu-item"
+              hover-class="menu-item-hover"
+              @click="handleMenuClick(menu.command)"
+            >
+              <view v-if="menu.icon" :class="menu.icon" class="menu-item-icon"></view>
+              <view class="menu-item-text">{{ menu.text }}</view>
+            </view>
+          </view>
+        </view>
+      </slot>
+    </template>
+  </up-navbar>
+</template>
+
+<script setup lang="ts">
+  export interface RightMenuItem {
+    icon?: string
+    text: string
+    command: string
+  }
+
+  defineOptions({ name: 'MNavBar' })
+
+  withDefaults(
+    defineProps<{
+      title?: string
+      placeholder?: boolean
+      bgColor?: string
+      rightMenu?: RightMenuItem[]
+    }>(),
+    { boolean: true, bgColor: 'transparent' }
+  )
+  const emits = defineEmits<{
+    (e: 'right-click', command: string): void
+  }>()
+
+  const mNavBarRef = ref()
+  const showMore = ref(false)
+
+  const triggerMore = () => {
+    showMore.value = !showMore.value
+  }
+
+  const handleMenuClick = (command: string) => {
+    emits('right-click', command)
+    showMore.value = false
+  }
+</script>
+
+<script lang="ts">
+  export default {
+    name: 'MNavBar',
+  }
+</script>
+
+<style scoped lang="scss">
+  .right-box {
+    @apply relative w-full z-1;
+    .overlay {
+      @apply fixed inset-0px opacity-100;
+      background: rgba(0, 0, 0, 0);
+    }
+    .menu-box {
+      @apply absolute right-0px z-10 flex flex-col gap-6px w-auto whitespace-nowrap rounded-6px bg-white;
+      box-shadow: 0px 0px 10px rgba(0, 0, 0, 20%);
+      .menu-item {
+        @apply flex items-center gap-8px h-full flex-1 px-16px py-8px text-left;
+        .menu-item-icon {
+          @apply wh-30px;
+        }
+        .menu-item-text {
+          @apply w-full text-left;
+        }
+      }
+      .menu-item-hover {
+        @apply bg-gray-100;
+      }
+    }
+  }
+</style>

+ 2 - 3
src/interceptors/router.ts

@@ -2,7 +2,7 @@
  * @Author: wjc
  * @Author: wjc
  * @Date: 2024-07-02 10:16:29
  * @Date: 2024-07-02 10:16:29
  * @LastEditors: wjc
  * @LastEditors: wjc
- * @LastEditTime: 2024-07-02 15:05:47
+ * @LastEditTime: 2024-07-03 11:42:42
  * @Description:
  * @Description:
  */
  */
 import type { App } from 'vue'
 import type { App } from 'vue'
@@ -21,9 +21,8 @@ const interceptor = {
     const userStore = useUserStore()
     const userStore = useUserStore()
     const token = userStore.storageUserId
     const token = userStore.storageUserId
     const path = url.split('?')[0]
     const path = url.split('?')[0]
-
     const isNeedLogin = loginBlacklist.includes(path)
     const isNeedLogin = loginBlacklist.includes(path)
-    console.log('244-', path, loginBlacklist, isNeedLogin)
+
     // 不需要登录权限的,直接跳转
     // 不需要登录权限的,直接跳转
     if (!isNeedLogin) {
     if (!isNeedLogin) {
       return true
       return true

+ 1 - 4
src/layouts/default.vue

@@ -2,7 +2,7 @@
  * @Author: wjc
  * @Author: wjc
  * @Date: 2024-06-25 15:42:58
  * @Date: 2024-06-25 15:42:58
  * @LastEditors: wjc
  * @LastEditors: wjc
- * @LastEditTime: 2024-06-25 16:22:04
+ * @LastEditTime: 2024-07-03 11:40:24
  * @Description: 
  * @Description: 
 -->
 -->
 <template>
 <template>
@@ -13,8 +13,5 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-  import MPage from '@/components/MPage'
-  import MFooter from '@/components/MFooter'
-
   defineOptions({ name: 'DefaultLayout' })
   defineOptions({ name: 'DefaultLayout' })
 </script>
 </script>

+ 5 - 2
src/pages.json

@@ -5,7 +5,9 @@
 			"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
 			"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
 			"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
 			"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
 			"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue",
 			"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue",
-			"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
+			"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue",
+			"^M(.*)": "@/components/M$1/index.vue",
+			"^m-(.*)": "@/components/M$1/index.vue"
 		}
 		}
 	},
 	},
 	"tabBar": {
 	"tabBar": {
@@ -73,8 +75,9 @@
 		{
 		{
 			"path": "pages/test/index",
 			"path": "pages/test/index",
 			"actions": ["login"],
 			"actions": ["login"],
+			"layout": false,
 			"style": {
 			"style": {
-				"navigationBarTitleText": "test page"
+				"navigationStyle": "custom"
 			}
 			}
 		}
 		}
 	],
 	],

+ 1 - 3
src/pages/index/index.vue

@@ -2,7 +2,7 @@
  * @Author: wjc
  * @Author: wjc
  * @Date: 2019-08-22 19:41:20
  * @Date: 2019-08-22 19:41:20
  * @LastEditors: wjc
  * @LastEditors: wjc
- * @LastEditTime: 2024-07-02 11:51:16
+ * @LastEditTime: 2024-07-03 11:27:15
  * @Description: 
  * @Description: 
 -->
 -->
 <template>
 <template>
@@ -22,8 +22,6 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-  import MIcon from '@/components/MIcon/index.vue'
-
   const title = ref('自定义图标')
   const title = ref('自定义图标')
   const icon = ref('anl')
   const icon = ref('anl')
 
 

+ 1 - 2
src/pages/login/index.vue

@@ -2,7 +2,7 @@
  * @Author: wjc
  * @Author: wjc
  * @Date: 2024-06-06 14:51:25
  * @Date: 2024-06-06 14:51:25
  * @LastEditors: wjc
  * @LastEditors: wjc
- * @LastEditTime: 2024-07-02 15:05:10
+ * @LastEditTime: 2024-07-03 11:27:20
  * @Description: 
  * @Description: 
 -->
 -->
 <template>
 <template>
@@ -51,7 +51,6 @@
 <script setup lang="ts">
 <script setup lang="ts">
   import { useUserStore } from '@/stores/modules/userStore'
   import { useUserStore } from '@/stores/modules/userStore'
   import logo from '@/static/images/logo.png'
   import logo from '@/static/images/logo.png'
-  import MFooter from '@/components/MFooter'
   import PrivacyModal from './components/privacy.vue'
   import PrivacyModal from './components/privacy.vue'
 
 
   defineOptions({ name: 'Login' })
   defineOptions({ name: 'Login' })

+ 1 - 2
src/pages/mine/index.vue

@@ -2,7 +2,7 @@
  * @Author: wjc
  * @Author: wjc
  * @Date: 2024-06-17 16:02:59
  * @Date: 2024-06-17 16:02:59
  * @LastEditors: wjc
  * @LastEditors: wjc
- * @LastEditTime: 2024-06-28 15:39:17
+ * @LastEditTime: 2024-07-03 11:27:27
  * @Description: 
  * @Description: 
 -->
 -->
 <template>
 <template>
@@ -23,7 +23,6 @@
 
 
 <script setup lang="ts">
 <script setup lang="ts">
   import { useUserStore } from '@/stores/modules/userStore'
   import { useUserStore } from '@/stores/modules/userStore'
-  import MCard from '@/components/MCard'
 
 
   defineOptions({ name: 'Mine' })
   defineOptions({ name: 'Mine' })
 
 

+ 24 - 1
src/pages/test/index.vue

@@ -2,13 +2,36 @@
  * @Author: wjc
  * @Author: wjc
  * @Date: 2024-07-02 10:07:46
  * @Date: 2024-07-02 10:07:46
  * @LastEditors: wjc
  * @LastEditors: wjc
- * @LastEditTime: 2024-07-02 15:22:36
+ * @LastEditTime: 2024-07-04 14:27:51
  * @Description: 
  * @Description: 
 -->
 -->
 <template>
 <template>
+  <MNavBar title="测试页面" :right-menu="rightMenu" @right-click="handleRightClick">
+    <!-- <template #right><view>123</view></template> -->
+  </MNavBar>
   <view>需要登录才能查看的页面</view>
   <view>需要登录才能查看的页面</view>
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
   defineOptions({ name: 'Auth' })
   defineOptions({ name: 'Auth' })
+
+  const rightMenu = ref([
+    {
+      icon: 'i-ep-link',
+      text: '扫一扫',
+      command: 'qrcode',
+    },
+    {
+      icon: 'i-ep-full-screen',
+      text: '投屏',
+      command: 'view',
+    },
+    {
+      icon: 'i-ep-credit-card',
+      text: '收付款',
+      command: 'money',
+    },
+  ])
+
+  const handleRightClick = () => {}
 </script>
 </script>

+ 5 - 5
src/stores/modules/userStore.ts

@@ -2,7 +2,7 @@
  * @Author: wjc
  * @Author: wjc
  * @Date: 2024-06-05 17:13:30
  * @Date: 2024-06-05 17:13:30
  * @LastEditors: wjc
  * @LastEditors: wjc
- * @LastEditTime: 2024-07-01 14:59:31
+ * @LastEditTime: 2024-07-02 16:42:44
  * @Description:
  * @Description:
  */
  */
 import { defineStore } from 'pinia'
 import { defineStore } from 'pinia'
@@ -21,10 +21,10 @@ export const useUserStore = defineStore('user', {
       storageUserId: '',
       storageUserId: '',
     }
     }
   },
   },
-  // persist: true,
-  persist: {
-    paths: ['isPrivacyShowed', 'isInstall', 'storageUserId', 'storageLoginInfo'],
-  },
+  persist: true,
+  // persist: {
+  //   paths: ['isPrivacyShowed', 'isInstall', 'storageUserId', 'storageLoginInfo'],
+  // },
   getters: {},
   getters: {},
   actions: {
   actions: {
     loginAction(data: ILogin): Promise<LoginRes> {
     loginAction(data: ILogin): Promise<LoginRes> {

+ 1 - 0
types/components.d.ts

@@ -12,6 +12,7 @@ declare module 'vue' {
     MContainer: typeof import('./../src/components/MContainer/index.vue')['default']
     MContainer: typeof import('./../src/components/MContainer/index.vue')['default']
     MFooter: typeof import('./../src/components/MFooter/index.vue')['default']
     MFooter: typeof import('./../src/components/MFooter/index.vue')['default']
     MIcon: typeof import('./../src/components/MIcon/index.vue')['default']
     MIcon: typeof import('./../src/components/MIcon/index.vue')['default']
+    MNavBar: typeof import('./../src/components/MNavBar/index.vue')['default']
     MPage: typeof import('./../src/components/MPage/index.vue')['default']
     MPage: typeof import('./../src/components/MPage/index.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
     RouterView: typeof import('vue-router')['RouterView']