Ver Fonte

feat: add demo for modify menu badge data

Netfan há 9 meses atrás
pai
commit
0f756503ff

+ 1 - 0
packages/@core/ui-kit/menu-ui/src/index.ts

@@ -1,3 +1,4 @@
+export { default as MenuBadge } from './components/menu-badge.vue';
 export * from './components/normal-menu';
 export { default as Menu } from './menu.vue';
 export type * from './types';

+ 19 - 0
packages/stores/src/modules/access.ts

@@ -41,6 +41,25 @@ interface AccessState {
  */
 export const useAccessStore = defineStore('core-access', {
   actions: {
+    getMenuByPath(path: string) {
+      function findMenu(
+        menus: MenuRecordRaw[],
+        path: string,
+      ): MenuRecordRaw | undefined {
+        for (const menu of menus) {
+          if (menu.path === path) {
+            return menu;
+          }
+          if (menu.children) {
+            const matched = findMenu(menu.children, path);
+            if (matched) {
+              return matched;
+            }
+          }
+        }
+      }
+      return findMenu(this.accessMenus, path);
+    },
     setAccessCodes(codes: string[]) {
       this.accessCodes = codes;
     },

+ 1 - 0
playground/package.json

@@ -30,6 +30,7 @@
   },
   "dependencies": {
     "@tanstack/vue-query": "catalog:",
+    "@vben-core/menu-ui": "workspace:*",
     "@vben/access": "workspace:*",
     "@vben/common-ui": "workspace:*",
     "@vben/constants": "workspace:*",

+ 111 - 2
playground/src/views/demos/badge/index.vue

@@ -1,7 +1,116 @@
 <script lang="ts" setup>
-import { Fallback } from '@vben/common-ui';
+import { reactive } from 'vue';
+import { useRoute } from 'vue-router';
+
+import { Page } from '@vben/common-ui';
+import { useAccessStore } from '@vben/stores';
+import { MenuBadge } from '@vben-core/menu-ui';
+
+import { Button, Card, Radio, RadioGroup } from 'ant-design-vue';
+
+import { useVbenForm } from '#/adapter/form';
+
+const colors = [
+  { label: '预设:默认', value: 'default' },
+  { label: '预设:关键', value: 'destructive' },
+  { label: '预设:主要', value: 'primary' },
+  { label: '预设:成功', value: 'success' },
+  { label: '自定义', value: 'bg-gray-200 text-black' },
+];
+
+const route = useRoute();
+const accessStore = useAccessStore();
+const menu = accessStore.getMenuByPath(route.path);
+const badgeProps = reactive({
+  badge: menu?.badge as string,
+  badgeType: menu?.badge ? 'normal' : (menu?.badgeType as 'dot' | 'normal'),
+  badgeVariants: menu?.badgeVariants as string,
+});
+
+const [Form] = useVbenForm({
+  handleValuesChange(values) {
+    badgeProps.badge = values.badge;
+    badgeProps.badgeType = values.badgeType;
+    badgeProps.badgeVariants = values.badgeVariants;
+  },
+  schema: [
+    {
+      component: 'RadioGroup',
+      componentProps: {
+        buttonStyle: 'solid',
+        options: [
+          { label: '点徽标', value: 'dot' },
+          { label: '文字徽标', value: 'normal' },
+        ],
+        optionType: 'button',
+      },
+      defaultValue: badgeProps.badgeType,
+      fieldName: 'badgeType',
+      label: '类型',
+    },
+    {
+      component: 'Input',
+      componentProps: {
+        maxLength: 4,
+        placeholder: '请输入徽标内容',
+        style: { width: '200px' },
+      },
+      defaultValue: badgeProps.badge,
+      fieldName: 'badge',
+      label: '徽标内容',
+    },
+    {
+      component: 'RadioGroup',
+      defaultValue: badgeProps.badgeVariants,
+      fieldName: 'badgeVariants',
+      label: '颜色',
+    },
+    {
+      component: 'Input',
+      fieldName: 'action',
+    },
+  ],
+  showDefaultActions: false,
+});
+
+function updateMenuBadge() {
+  if (menu) {
+    menu.badge = badgeProps.badge;
+    menu.badgeType = badgeProps.badgeType;
+    menu.badgeVariants = badgeProps.badgeVariants;
+  }
+}
 </script>
 
 <template>
-  <Fallback description="用于徽标示例" status="coming-soon" title="徽标示例" />
+  <Page
+    description="菜单项上可以显示徽标,这些徽标可以主动更新"
+    title="菜单徽标"
+  >
+    <Card title="徽标更新">
+      <Form>
+        <template #badgeVariants="slotProps">
+          <RadioGroup v-bind="slotProps">
+            <Radio
+              v-for="color in colors"
+              :key="color.value"
+              :value="color.value"
+            >
+              <div
+                :title="color.label"
+                class="flex h-[14px] w-[50px] items-center justify-start"
+              >
+                <MenuBadge
+                  v-bind="{ ...badgeProps, badgeVariants: color.value }"
+                />
+              </div>
+            </Radio>
+          </RadioGroup>
+        </template>
+        <template #action>
+          <Button type="primary" @click="updateMenuBadge">更新徽标</Button>
+        </template>
+      </Form>
+    </Card>
+  </Page>
 </template>

+ 3 - 0
pnpm-lock.yaml

@@ -1768,6 +1768,9 @@ importers:
       '@tanstack/vue-query':
         specifier: 'catalog:'
         version: 5.62.7(vue@3.5.13(typescript@5.7.2))
+      '@vben-core/menu-ui':
+        specifier: workspace:*
+        version: link:../packages/@core/ui-kit/menu-ui
       '@vben/access':
         specifier: workspace:*
         version: link:../packages/effects/access