# 六.导航(菜单)

前言 --> 菜单组件特点

  • 1.使用递归组件

# 1.目录结构

├── menu
│   ├── menu-item.vue
│   ├── menu.vue
│   ├── resub-menu.vue
│   ├── sub-menu.vue
│   └── index.js
1
2
3
4
5
6

# 2.实现方式

# 2.1 Menu.vue

<template>
  <ul class="menu">
    <slot></slot>
  </ul>
</template>

<script>
export default {
  name: "VueMenu",
  props: {
    data: {
      type: Object,
      default: () => ({}),
    },
  },
};
</script>

<style lang="scss" scoped>
.menu {
  cursor: pointer;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 2.2 MenuItem

<template>
  <li class="item">
    <slot></slot>
  </li>
</template>

<script>
export default {
  name: "VueMenuItem",
  props: {
    data: {
      type: Object,
      default: () => ({}),
    },
  },
};
</script>

<style lang="scss" scoped>
.item {
  display: block;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 2.3 ReSubMenu.vue








 








 












<template>
  <sub-menu>
    <template #title>
      {{ data.title }}
    </template>
    <div v-for="(child, index) in data.children" :key="index">
      <menu-item v-if="!child.children">{{ child.title }}</menu-item>
      <vue-resub-menu v-else :data="child"></vue-resub-menu> <!-- 2.添加限定条件 -->
    </div>
  </sub-menu>
</template>

<script>
import SubMenu from "./sub-menu";
import MenuItem from "./menu-item";
export default {
  name: "VueResubMenu", // 1.添加名称标识
  components: {
    SubMenu,
    MenuItem,
  },
  props: {
    data: {
      type: Object,
      default: () => ({}),
    },
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 2.4 SubMenu.vue

<template>
  <div>
    <div class="title" @click="change">
      <slot name="title"></slot>
    </div>
    <div v-show="flag" class="sub">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  name: "VueSubMenu",
  data() {
    return { flag: false };
  },
  methods: {
    change() {
      this.flag = !this.flag;
    },
  },
};
</script>

<style lang="scss" scoped>
.title {
  &::before {
    content: "⬇️";
    display: inline;
    font-size: 12px;
  }
}
.sub {
  padding-left: 10px;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

提示

递归组件常用来开发具有位置层级关系的独立组件,这类组件一般都是数据驱动型的,父级有一个字段 children,然后递归

# 3.使用案例

使用 vue 的递归组件写一个菜单组件,实现无限菜单

刷新
全屏/自适应

总结

合理使用动态组件可以让我们写出的代码更加简洁,减少冗余代码