antdesignVue递归导航菜单

公孙令秋
2023-12-01

手写版本

文件leftNav.vue

<template>
<!-- 	  <a-switch
	      :checked="theme === 'dark'"
	      checked-children="Dark"
	      un-checked-children="Light"
	      @change="changeTheme"
	    /> -->

	<a-menu v-model:openKeys="openKeys" 
	   v-model:selectedKeys="selectedKeys" 
	     mode="inline"
	    :theme="theme"
		@click="handleClick">

		<template v-for="item in menuList">
			<a-sub-menu :key="item.id" @titleClick="titleClick" v-if="item.children">
				<template #icon>
					<component :is="$antIcons[item.icon]" />
				</template>
               
				<template #title>{{item.name + item.id}}</template>

				<template :key="sitem.id" v-for="sitem in item.children">
					<a-menu-item v-if="!sitem.children">{{sitem.name}}</a-menu-item>
					<!-- <a-menu-item v-else="!sitem.children">
					{{[sitem]}}
					</a-menu-item> -->
					<leftNav :menuList="[sitem]" v-else />
				</template>
			</a-sub-menu>
			<a-menu-item :key="item.id" v-else>
				
			<template #icon>
				<component :is="$antIcons[item.icon]" />
			</template>
			
			{{item.name +item.id}}
			</a-menu-item>
		</template>

	</a-menu>
</template>
<script>
   import { defineComponent, reactive, toRefs } from 'vue';
	export default {
		components: {
		
		},
	  setup() {
	    const state = reactive({
	      theme: 'dark',
	       selectedKeys: ['1'],
	      // openKeys: ['sub1'],
	    });
	
	    const changeTheme = checked => {
	      state.theme = checked ? 'dark' : 'light';
	    };
	
	    return { ...toRefs(state),
	      changeTheme,
	    };
	  },
	  
		props:['menuList','ids'],
		// props: {
		// 	menuList: {
		// 		type: Object,
		// 	},
		// },
		methods: {
			changNav(item) {
				console.log(item.key)
				this.$router.push({
					path: item.key
				})
				this.selectedKeys = item.key
			},
			updateMenu() {
				const routes = this.$route.matched.concat()
				this.selectedKeys = [routes.pop().path]
			}
		},
		mounted() {
		
		},
		created() {

		},
		computed: {
			// 计算属性的 getter
			childrenData: function() {
				// `this` 指向 vm 实例
				return '['+this.childrenObject+']'
			}
		}
	}
</script>
<style>
	.ant-menu-inline{
		height: 100%;
	}
</style>

官方版本

<template>
  <div style="width: 256px">
    <a-button type="primary" style="margin-bottom: 16px" @click="toggleCollapsed">
      <MenuUnfoldOutlined v-if="collapsed" />
      <MenuFoldOutlined v-else />
    </a-button>
    <a-menu
      v-model:openKeys="openKeys"
      v-model:selectedKeys="selectedKeys"
      mode="inline"
      theme="dark"
      :inline-collapsed="collapsed"
    >
      <template v-for="item in list" :key="item.key">
        <template v-if="!item.children">
          <a-menu-item :key="item.key">
            <template #icon>
              <PieChartOutlined />
            </template>
            {{ item.title }}
          </a-menu-item>
        </template>
        <template v-else>
          <sub-menu :key="item.key" :menu-info="item" />
        </template>
      </template>
    </a-menu>
  </div>
</template>
<script>
import { defineComponent, ref } from 'vue';
import { MenuFoldOutlined, MenuUnfoldOutlined, PieChartOutlined, MailOutlined } from '@ant-design/icons-vue'; // you can rewrite it to a single file component, if not, you should config vue alias to vue/dist/vue.esm-bundler.js

const SubMenu = {
  name: 'SubMenu',
  props: {
    menuInfo: {
      type: Object,
      default: () => ({}),
    },
  },
  template: `
    <a-sub-menu :key="menuInfo.key">
      <template #icon><MailOutlined /></template>
      <template #title>{{ menuInfo.title }}</template>
      <template v-for="item in menuInfo.children" :key="item.key">
        <template v-if="!item.children">
          <a-menu-item :key="item.key">
            <template #icon>
              <PieChartOutlined />
            </template>
            {{ item.title }}
          </a-menu-item>
        </template>
        <template v-else>
          <sub-menu :menu-info="item" :key="item.key" />
        </template>
      </template>
    </a-sub-menu>
  `,
  components: {
    PieChartOutlined,
    MailOutlined,
  },
};
const list = [{
  key: '1',
  title: 'Option 1',
}, {
  key: '2',
  title: 'Navigation 2',
  children: [{
    key: '2.1',
    title: 'Navigation 3',
    children: [{
      key: '2.1.1',
      title: 'Option 2.1.1',
    }],
  }],
}];
export default defineComponent({
  components: {
    'sub-menu': SubMenu,
    MenuFoldOutlined,
    MenuUnfoldOutlined,
    PieChartOutlined,
  },

  setup() {
    const collapsed = ref(false);

    const toggleCollapsed = () => {
      collapsed.value = !collapsed.value;
    };

    return {
      list,
      collapsed,
      toggleCollapsed,
      selectedKeys: ref(['1']),
      openKeys: ref(['2']),
    };
  },

});
</script>

 类似资料: