42 混合布局菜单开发 - udo-bit/naive_admin_pro GitHub Wiki

目标

混合布局基础侧边栏菜单功能开发

开发

首先我们先来实现一下混合布局中的基础侧边栏部分的开发。
首先我们第一步还是先来实现一个侧边栏组件,在src中的layouts创建一个side-menu的文件夹,然后再创建一个index.vue的文件。用于存放我们公共的侧边栏组件的代码部分。

<script lang="ts" setup>
import { menuProps } from 'naive-ui'

const props = defineProps({
  ...menuProps,
})
</script>

<template>
  <n-menu v-bind="props" />
</template>

然后接下来我们先在mix-layout中实现侧边栏组件,在mix-layout中引入我们的侧边栏部分:

<script lang="ts" setup>
import SideMenu from '../side-menu/index.vue'
const props = withDefaults(defineProps<{
  // ...
  collapsedIconSize?: number
  active?: string
  options?: MenuOption[]
  expandedKeys?: MenuProps['expandedKeys']
}>(), {
  // ...
	collapsedIconSize: 22,
})
defineEmits(['update:collapsed', 'update:active', 'update:expandedKeys'])
</script>
<template>
  <LayoutSider
    :collapsed-width="siderCollapsedWidth"
    :width="siderWidth"
    :collapsed="collapsed"
    :show-trigger="showSiderTrigger"
    @update:collapsed="($event) => $emit('update:collapsed', $event)"
  >
     <SideMenu
      :collapsed-icon-size="collapsedIconSize"
      :collapsed-width="siderCollapsedWidth"
      :collapsed="collapsed"
      :value="active"
      :options="options"
      :expanded-keys="expandedKeys"
      @update:value="$emit('update:active', $event)"
      @update:expandedKeys="$emit('update:expandedKeys', $event)"
    />
  </LayoutSider>
</template>

接下来我们处理一下数据,在layouts的目录中创建一个composables的文件夹,然后创建一个menu-data.ts的文件,接下来我们先把我们的模拟数据放到这个文件中。

import type { MenuOption } from 'naive-ui'
import { NIcon } from 'naive-ui'
import { SaveFilled as BookIcon, PhoneFilled as PersonIcon, WalletFilled as WineIcon } from '@vicons/antd'
import type { Component } from '@vue/runtime-core'
function renderIcon(icon: Component) {
  return () => h(NIcon, null, { default: () => h(icon) })
}
export const menuOptions: MenuOption[] = [
  {
    label: '且听风吟',
    key: 'hear-the-wind-sing',
    icon: renderIcon(BookIcon),
  },
  {
    label: '1973年的弹珠玩具',
    key: 'pinball-1973',
    icon: renderIcon(BookIcon),
    disabled: true,
    children: [
      {
        label: '鼠',
        key: 'rat',
      },
    ],
  },
  {
    label: '寻羊冒险记',
    key: 'a-wild-sheep-chase',
    disabled: true,
    icon: renderIcon(BookIcon),
  },
  {
    label: '舞,舞,舞',
    key: 'dance-dance-dance',
    icon: renderIcon(BookIcon),
    children: [
      {
        type: 'group',
        label: '人物',
        key: 'people',
        children: [
          {
            label: '叙事者',
            key: 'narrator',
            icon: renderIcon(PersonIcon),
          },
          {
            label: '羊男',
            key: 'sheep-man',
            icon: renderIcon(PersonIcon),
          },
        ],
      },
      {
        label: '饮品',
        key: 'beverage',
        icon: renderIcon(WineIcon),
        children: [
          {
            label: '威士忌',
            key: 'whisky',
          },
        ],
      },
      {
        label: '食物',
        key: 'food',
        children: [
          {
            label: '三明治',
            key: 'sandwich',
          },
        ],
      },
      {
        label: '过去增多,未来减少',
        key: 'the-past-increases-the-future-recedes',
      },
    ],
  },
]

然后我们在base-layout中的index.vue中使用:

<script lang="ts" setup>
</script>
<template>
  <MixLayout
      v-if="layout.layout === 'mix'"
      v-model:collapsed="layout.collapsed"
      :logo="layout.logo"
      :title="layout.title"
 +     :options="menuOptions"
      :show-sider-trigger="layout.showSiderTrigger"
      :sider-width="layout.siderWidth"
      :sider-collapsed-width="layout.siderCollapsedWidth"
    >
      <template #headerRight>
        <RightContent />
      </template>
      <router-view />
    </MixLayout>
</template>

查看效果

⚠️ **GitHub.com Fallback** ⚠️