Przeglądaj źródła

refactor: a-menu jsx render, fix top-navmenu error #119

Sendya 6 lat temu
rodzic
commit
3d7acb786f

+ 74 - 65
src/components/menu/index.js

@@ -57,53 +57,7 @@ export default {
     }
   },
   methods: {
-    renderIcon: function (h, icon) {
-      if (icon === 'none' || icon === undefined) {
-        return null
-      }
-      const props = {}
-      typeof (icon) === 'object' ? props.component = icon : props.type = icon
-      return h(Icon, { props: { ...props } })
-    },
-    renderMenuItem: function (h, menu, pIndex, index) {
-      const target = menu.meta.target || null
-      return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index }, [
-        h('router-link', { attrs: { to: { name: menu.name }, target: target } }, [
-          this.renderIcon(h, menu.meta.icon),
-          h('span', [menu.meta.title])
-        ])
-      ])
-    },
-    renderSubMenu: function (h, menu, pIndex, index) {
-      const this2_ = this
-      const subItem = [h('span', { slot: 'title' }, [this.renderIcon(h, menu.meta.icon), h('span', [menu.meta.title])])]
-      const itemArr = []
-      const pIndex_ = pIndex + '_' + index
-      console.log('menu', menu)
-      if (!menu.hideChildrenInMenu) {
-        menu.children.forEach(function (item, i) {
-          itemArr.push(this2_.renderItem(h, item, pIndex_, i))
-        })
-      }
-      return h(SubMenu, { key: menu.path ? menu.path : 'submenu_' + pIndex + '_' + index }, subItem.concat(itemArr))
-    },
-    renderItem: function (h, menu, pIndex, index) {
-      if (!menu.hidden) {
-        return menu.children && !menu.hideChildrenInMenu
-          ? this.renderSubMenu(h, menu, pIndex, index)
-          : this.renderMenuItem(h, menu, pIndex, index)
-      }
-    },
-    renderMenu: function (h, menuTree) {
-      const this2_ = this
-      const menuArr = []
-      menuTree.forEach(function (menu, i) {
-        if (!menu.hidden) {
-          menuArr.push(this2_.renderItem(h, menu, '0', i))
-        }
-      })
-      return menuArr
-    },
+    // select menu item
     onOpenChange (openKeys) {
       const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
       if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
@@ -130,27 +84,82 @@ export default {
       }
 
       this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
+    },
+
+    // render
+    renderItem (menu) {
+      if (!menu.hidden) {
+        return menu.children && !menu.hideChildrenInMenu ? this.renderSubMenu(menu) : this.renderMenuItem(menu)
+      }
+      return null
+    },
+    renderMenuItem (menu) {
+      const target = menu.meta.target || null
+      const props = {
+        to: { name: menu.name },
+        target: target
+      }
+      return (
+        <Item {...{ key: menu.path }}>
+          <router-link {...{ props }}>
+            {this.renderIcon(menu.meta.icon)}
+            <span>{menu.meta.title}</span>
+          </router-link>
+        </Item>
+      )
+    },
+    renderSubMenu (menu) {
+      const itemArr = []
+      if (!menu.hideChildrenInMenu) {
+        menu.children.forEach(item => itemArr.push(this.renderItem(item)))
+      }
+      return (
+        <SubMenu {...{ key: menu.path }}>
+          <span slot="title">
+            {this.renderIcon(menu.meta.icon)}
+            <span>{menu.meta.title}</span>
+          </span>
+          {itemArr}
+        </SubMenu>
+      )
+    },
+    renderIcon (icon) {
+      if (icon === 'none' || icon === undefined) {
+        return null
+      }
+      const props = {}
+      typeof (icon) === 'object' ? props.component = icon : props.type = icon
+      return (
+        <Icon {... { props } }/>
+      )
     }
   },
-  render (h) {
-    return h(
-      Menu,
-      {
-        props: {
-          theme: this.$props.theme,
-          mode: this.$props.mode,
-          openKeys: this.openKeys,
-          selectedKeys: this.selectedKeys
-        },
-        on: {
-          openChange: this.onOpenChange,
-          select: obj => {
-            this.selectedKeys = obj.selectedKeys
-            this.$emit('select', obj)
-          }
-        }
+  render () {
+    const { mode, theme, menu } = this
+    const props = {
+      mode: mode,
+      theme: theme,
+      openKeys: this.openKeys
+    }
+    const on = {
+      select: obj => {
+        this.selectedKeys = obj.selectedKeys
+        this.$emit('select', obj)
       },
-      this.renderMenu(h, this.menu)
+      openChange: this.onOpenChange
+    }
+
+    const menuTree = menu.map(item => {
+      if (item.hidden) {
+        return null
+      }
+      return this.renderItem(item)
+    })
+    // {...{ props, on: on }}
+    return (
+      <Menu vModel={this.selectedKeys} {...{ props, on: on }}>
+        {menuTree}
+      </Menu>
     )
   }
 }

+ 156 - 0
src/components/menu/index.render.js

@@ -0,0 +1,156 @@
+import Menu from 'ant-design-vue/es/menu'
+import Icon from 'ant-design-vue/es/icon'
+
+const { Item, SubMenu } = Menu
+
+export default {
+  name: 'SMenu',
+  props: {
+    menu: {
+      type: Array,
+      required: true
+    },
+    theme: {
+      type: String,
+      required: false,
+      default: 'dark'
+    },
+    mode: {
+      type: String,
+      required: false,
+      default: 'inline'
+    },
+    collapsed: {
+      type: Boolean,
+      required: false,
+      default: false
+    }
+  },
+  data () {
+    return {
+      openKeys: [],
+      selectedKeys: [],
+      cachedOpenKeys: []
+    }
+  },
+  computed: {
+    rootSubmenuKeys: vm => {
+      const keys = []
+      vm.menu.forEach(item => keys.push(item.path))
+      return keys
+    }
+  },
+  created () {
+    this.updateMenu()
+  },
+  watch: {
+    collapsed (val) {
+      if (val) {
+        this.cachedOpenKeys = this.openKeys.concat()
+        this.openKeys = []
+      } else {
+        this.openKeys = this.cachedOpenKeys
+      }
+    },
+    $route: function () {
+      this.updateMenu()
+    }
+  },
+  methods: {
+    renderIcon: function (h, icon) {
+      if (icon === 'none' || icon === undefined) {
+        return null
+      }
+      const props = {}
+      typeof (icon) === 'object' ? props.component = icon : props.type = icon
+      return h(Icon, { props: { ...props } })
+    },
+    renderMenuItem: function (h, menu, pIndex, index) {
+      const target = menu.meta.target || null
+      return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index }, [
+        h('router-link', { attrs: { to: { name: menu.name }, target: target } }, [
+          this.renderIcon(h, menu.meta.icon),
+          h('span', [menu.meta.title])
+        ])
+      ])
+    },
+    renderSubMenu: function (h, menu, pIndex, index) {
+      const this2_ = this
+      const subItem = [h('span', { slot: 'title' }, [this.renderIcon(h, menu.meta.icon), h('span', [menu.meta.title])])]
+      const itemArr = []
+      const pIndex_ = pIndex + '_' + index
+      console.log('menu', menu)
+      if (!menu.hideChildrenInMenu) {
+        menu.children.forEach(function (item, i) {
+          itemArr.push(this2_.renderItem(h, item, pIndex_, i))
+        })
+      }
+      return h(SubMenu, { key: menu.path ? menu.path : 'submenu_' + pIndex + '_' + index }, subItem.concat(itemArr))
+    },
+    renderItem: function (h, menu, pIndex, index) {
+      if (!menu.hidden) {
+        return menu.children && !menu.hideChildrenInMenu
+          ? this.renderSubMenu(h, menu, pIndex, index)
+          : this.renderMenuItem(h, menu, pIndex, index)
+      }
+    },
+    renderMenu: function (h, menuTree) {
+      const this2_ = this
+      const menuArr = []
+      menuTree.forEach(function (menu, i) {
+        if (!menu.hidden) {
+          menuArr.push(this2_.renderItem(h, menu, '0', i))
+        }
+      })
+      return menuArr
+    },
+    onOpenChange (openKeys) {
+      const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
+      if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
+        this.openKeys = openKeys
+      } else {
+        this.openKeys = latestOpenKey ? [latestOpenKey] : []
+      }
+    },
+    updateMenu () {
+      const routes = this.$route.matched.concat()
+
+      if (routes.length >= 4 && this.$route.meta.hidden) {
+        routes.pop()
+        this.selectedKeys = [routes[2].path]
+      } else {
+        this.selectedKeys = [routes.pop().path]
+      }
+
+      const openKeys = []
+      if (this.mode === 'inline') {
+        routes.forEach(item => {
+          openKeys.push(item.path)
+        })
+      }
+
+      this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
+    }
+  },
+  render (h) {
+    return h(
+      Menu,
+      {
+        props: {
+          theme: this.$props.theme,
+          mode: this.$props.mode,
+          openKeys: this.openKeys,
+          selectedKeys: this.selectedKeys
+        },
+        on: {
+          openChange: this.onOpenChange,
+          select: obj => {
+            this.selectedKeys = obj.selectedKeys
+            this.$emit('select', obj)
+          }
+        }
+      },
+      this.renderMenu(h, this.menu)
+    )
+  }
+}

+ 12 - 0
src/components/page/GlobalLayout.vue

@@ -299,6 +299,7 @@ export default {
           display: inline-block;
           transition: all .3s;
           height: 100%;
+          color: rgba(0, 0, 0, 0.65);
 
           &:hover {
             background: rgba(0, 0, 0, 0.025);
@@ -323,6 +324,9 @@ export default {
 
           .action {
             color: rgba(255, 255, 255, 0.85);
+            a {
+              color: rgba(255, 255, 255, 0.85);
+            }
 
             &:hover {
               background: rgba(255, 255, 255, 0.16);
@@ -348,6 +352,9 @@ export default {
               text-align: center;
               width: 56px;
               line-height: 58px;
+              h1 {
+                display: none;
+              }
             }
           }
         }
@@ -380,6 +387,9 @@ export default {
               white-space: nowrap;
             }
           }
+          .ant-menu.ant-menu-horizontal {
+                max-width: 350px;
+          }
         }
       }
 
@@ -401,6 +411,8 @@ export default {
           border: none;
           height: 64px;
           line-height: 64px;
+          width: 100%;
+          max-width: 700px;
         }
 
         .header-index-left {

+ 4 - 4
src/components/tools/UserMenu.vue

@@ -1,10 +1,10 @@
 <template>
   <div class="user-wrapper">
-    <span class="action">
-      <a href="https://pro.loacg.com/docs/getting-started" target="_blank" style="color: #001529">
+    <a href="https://pro.loacg.com/docs/getting-started" target="_blank">
+      <span class="action">
         <a-icon type="question-circle-o"></a-icon>
-      </a>
-    </span>
+      </span>
+    </a>
     <header-notice class="action"/>
     <a-dropdown>
       <span class="action ant-dropdown-link user-dropdown-menu">