Browse Source

feat: add tag display to the menu

vben 4 years ago
parent
commit
a3887f8cd9

+ 1 - 0
CHANGELOG.zh_CN.md

@@ -3,6 +3,7 @@
 ### ✨ Features
 
 - 表单项的`componentsProps`支持函数类型
+- 菜单新增 tag 显示
 
 ### ⚡ Performance Improvements
 

+ 23 - 2
src/components/Menu/src/MenuContent.tsx

@@ -35,6 +35,23 @@ export default defineComponent({
       return icon ? <Icon icon={icon} size={18} class="menu-item-icon" /> : null;
     }
 
+    function renderTag() {
+      const { item, showTitle } = props;
+      if (!item || showTitle) return null;
+
+      const { tag } = item;
+      if (!tag) return null;
+
+      const { dot, content, type = 'error' } = tag;
+      if (!dot && !content) return null;
+      const cls = ['basic-menu__tag'];
+
+      dot && cls.push('dot');
+      type && cls.push(type);
+
+      return <span class={cls}>{dot ? '' : content}</span>;
+    }
+
     return () => {
       if (!props.item) {
         return null;
@@ -46,17 +63,21 @@ export default defineComponent({
 
       const beforeStr = name.substr(0, index);
       const afterStr = name.substr(index + searchValue.length);
+      const cls = showTitle ? 'show-title' : 'basic-menu__name';
       return (
         <>
           {renderIcon(icon!)}
           {index > -1 && searchValue ? (
-            <span class={showTitle ? 'show-title' : ''}>
+            <span class={cls}>
               {beforeStr}
               <span class={`basic-menu__keyword`}>{searchValue}</span>
               {afterStr}
             </span>
           ) : (
-            <span class={[showTitle ? 'show-title' : '']}>{name}</span>
+            <span class={[cls]}>
+              {name}
+              {renderTag()}
+            </span>
           )}
         </>
       );

+ 39 - 0
src/components/Menu/src/index.less

@@ -51,6 +51,45 @@
 
   // collapsed show title end
 
+  &__name {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+    align-items: center;
+  }
+
+  &__tag {
+    display: inline-block;
+    padding: 2px 4px;
+    margin-right: 4px;
+    font-size: 12px;
+    line-height: 14px;
+    color: #fff;
+    border-radius: 2px;
+
+    &.dot {
+      width: 8px;
+      height: 8px;
+      padding: 0;
+      border-radius: 50%;
+    }
+
+    &.primary {
+      background: @primary-color;
+    }
+
+    &.error {
+      background: @error-color;
+    }
+
+    &.success {
+      background: @success-color;
+    }
+
+    &.warn {
+      background: @warning-color;
+    }
+  }
   // scrollbar -s tart
   &__content {
     /* 滚动槽 */

+ 6 - 0
src/router/menus/modules/dashboard.ts

@@ -4,10 +4,16 @@ const menu: MenuModule = {
   menu: {
     name: 'Dashboard',
     path: '/dashboard',
+    // tag: {
+    //   dot: true,
+    // },
     children: [
       {
         path: '/workbench',
         name: '工作台',
+        // tag: {
+        //   content: 'new',
+        // },
       },
       {
         path: '/analysis',

+ 7 - 0
src/router/types.d.ts

@@ -43,6 +43,11 @@ export interface AppRouteRecordRaw extends Omit<RouteRecordRaw, 'meta'> {
   props?: any;
   fullPath?: string;
 }
+export interface MenuTag {
+  type?: 'primary' | 'error' | 'warn' | 'success';
+  content?: string;
+  dot?: boolean;
+}
 
 export interface Menu {
   name: string;
@@ -60,6 +65,8 @@ export interface Menu {
   roles?: RoleEnum[];
 
   meta?: Partial<RouteMeta>;
+
+  tag?: MenuTag;
 }
 export interface MenuModule {
   orderNo?: number;