el-menu封装


main.js引入全局组件

1. 组件

menu/index.vue

<template>
  <el-menu :unique-opened="true" :default-active="this.$store.state.menuData.menuActive" class="el-menu-vertical-demo" :background-color="backgroundColor" :text-color="textColor" :active-text-color="activeTextColor">
    <subMenu :menuList="sideNavMenu"></subMenu>
  </el-menu>
</template>

<script>
export default {
  name: "index",
  props: {},
  data() {
    return {
      backgroundColor: "#EAEEF6",
      textColor: "#3F434E",
      activeTextColor: "#2A60CC",
      // sideNavMenu: this.$store.state.menuData.sideNavMenu,
      // 菜单列表
      sideNavMenu: [
        {
          "id": 1,
          "name": "首页",
          "code": "01",
          "parentId": "",
          "path": "/home",
          "icon": "icon-home",
          "level": 1,
          "resourceType": 0,
          "systemType": "",
          "status": "",
          "sortOrder": 1,
          "children": ""
        },
        {
          "id": 2,
          "name": "关于",
          "code": "02",
          "parentId": "",
          "path": "/about",
          "icon": "icon-about",
          "level": 1,
          "resourceType": 0,
          "systemType": "",
          "status": "",
          "sortOrder": 2,
          "children": [
            {
              "id": 3,
              "name": "关于我们",
              "code": "0201",
              "parentId": "2",
              "path": "/aboutUs",
              "icon": "",
              "level": 2,
              "resourceType": 0,
              "systemType": "",
              "status": "",
              "sortOrder": 1,
              "children": ""
            }
          ]
        },
      ]
    }
  },
  mounted() { },
  methods: {},
  watch: {},
  created() { },
}
</script>

<style scoped>
.el-menu {
  text-align: left;
}

.el-menu-vertical-demo {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}
</style>

menu/submenu.vue

<template>
  <div>
    <div v-for="(list,index) in this.menuList" :key="index">

      <!--      resourceType: 0 菜单,1 菜单(不显示),2 按钮-->
      <!--      1、resourceType: 0, children: null, 无子级,按最后一级菜单显示-->
      <!--      2、resourceType: 0, children: [], 有子级,按下拉菜单显示-->
      <!--      3、resourceType: 1, children: [], 有子级,按下拉菜单显示-->
      <!--      4、resourceType: 1, children: null, 无子级,不在菜单显示-->

      <div v-if="list.resourceType === 0" class="menu-nav">
        <el-submenu v-if="!!list.children" :key="list.id" :index="String(list.id)">
          <template slot="title">
            <i class="menu_icon" :class="list.icon"></i>
            <span slot="title">{{ list.name}}</span>
          </template>
          <subMenu :menuList="list.children"></subMenu>
        </el-submenu>
        <el-menu-item v-else :index="list.path">
          <router-link :target="targeLink(list.path)?'_blank':''" :to="list.path">
            <i class="menu_icon" :class="list.icon"></i>
            <span>{{list.name}}</span>
          </router-link>
        </el-menu-item>
      </div>
      <div v-else-if="list.resourceType === 1">
        <el-menu-item v-if="!!list.children" :index="list.path" :key="list.id">
          <router-link :target="targeLink(list.path)?'_blank':''" :to="list.path">
            <i class="menu_icon" :class="list.icon"></i>
            <span>{{list.name}}</span>
          </router-link>
        </el-menu-item>
      </div>

	  <!-- 侧栏数据简单可以使用以下简单封装 -->
      <!--      <el-submenu v-if="!!list.children" :key="list.id" :index="list.path">-->
      <!--        <template slot="title">-->
      <!--          <i :class="list.icon"></i>-->
      <!--          <span slot="title">{{ list.name}}</span>-->
      <!--        </template>-->
      <!--        <subMenu :menuList="list.children"></subMenu>-->
      <!--      </el-submenu>-->
      <!--      <el-menu-item v-else :index="list.path" :key="list.id">-->
      <!--        <span>{{list.name}}</span>-->
      <!--      </el-menu-item>-->
    </div>
  </div>
</template>

<script>
export default {
  name: "submenu",
  data() {
    return {}
  },
  props: {
    menuList: Array
  },
  mounted() { },
  methods: {
    targeLink(path) {
      if (path === '/aboutUs') {
        return true
      } else {
        return false
      }
    }
  },
  watch: {},
  created() { },
}
</script>

<style lang="scss" scoped>
@import "style.scss";
</style>

menu/style.scss

@charset "utf-8";

/*********************侧栏菜单*********************/
/deep/ .el-menu-item,
/deep/ .el-submenu__title {
  font-size: 18px;
}

/*父节点鼠标移入样式*/
/deep/ .el-submenu__title:hover,
.el-submenu__title:hover [class*="el-icon-"],
.el-submenu__title:hover [class*=" icon-"],
.el-submenu__title:hover [class^=icon-],
.el-submenu__title:hover .menu_icon {
  color: $menu_active_text_color !important;
}

/*父节点选中字体和图标样式*/
/deep/ .el-submenu {

  &.is-opened.is-active {

    // .el-submenu__title [class*="el-icon-"],
    // .el-submenu__title [class*=" icon-"],
    // .el-submenu__title [class*="icon-"],
    &>.el-submenu__title .menu_icon,
    &>.el-submenu__title {
      color: $menu_active_text_color !important;
    }

    &>.el-submenu__title {
      font-weight: bold;
      background-color: $menu_active_bg_color !important;
    }
  }
}

/*子节点样式*/
/* .el-menu--inline .el-menu-item {
  padding-left: 80px !important;
} */

/*子节点鼠标移入选中样式*/
.el-menu-item:hover,
.el-menu-item:hover [class*=" icon-"],
.el-menu-item:hover [class^=icon-],
.el-menu-item.is-active {
  color: $menu_active_text_color !important;
  background-color: $menu_active_bg_color !important;
}

// router-link / a 标签
a {
  display: block;
  color: #3F434E;
}

.el-menu-item:hover a,
.el-menu-item.is-active a {
  color: $menu_active_text_color ;
}

/*小三角*/
/deep/ .el-submenu__icon-arrow {
  font-size: 18px;
}

/deep/ .el-icon-arrow-down:before {
  content: "\E790";
}

/*icon*/
[class*="el-icon-"],
[class*=" icon-"],
[class^=icon-] {
  font-size: 20px;
  margin-right: 5px;
  // color: #f00;
}

2. 调用

<Menu></Menu>
首先,我们需要安装 `element-plus`,这是 `ElementUI` 的 `Vue3` 版本。 ```bash npm install element-plus --save ``` 然后,在 `main.js` 文件中引入并注册 `ElementPlus`。 ```js import { createApp } from 'vue' import ElementPlus from 'element-plus' import 'element-plus/lib/theme-chalk/index.css' import App from './App.vue' const app = createApp(App) app.use(ElementPlus) app.mount('#app') ``` 接下来,我们需要将 `el-menu` 组件封装成一个新的组件 `el-cascader-menu`,并在其中使用 `el-cascader` 组件来实现级联选择效果。 ```html <template> <el-cascader v-model="selected" :options="options" :props="props" :show-all-levels="false" @change="handleChange" ></el-cascader> </template> <script> import { ref, watch } from 'vue' import { useRoute } from 'vue-router' export default { name: 'ElCascaderMenu', props: { menuList: { type: Array, required: true } }, setup(props) { const route = useRoute() const selected = ref([]) const options = ref(props.menuList) const propsData = { checkStrictly: true, value: 'id', label: 'title', children: 'children' } const props = ref(propsData) watch( () => props.value, () => { options.value = props.menuList } ) const handleChange = (value) => { const path = value.map((id) => { const item = options.value.find((item) => item.id === id) return item.path || item.url }) route.push(path.join('/')) } return { selected, options, props, handleChange } } } </script> ``` 在 `setup` 函数中,我们使用 `ref` 创建了 `selected`、`options`、`props` 三个响应式变量,并使用 `watch` 监听 `props.value` 的变化来更新 `options` 的值。 `handleChange` 函数用来处理选择项的变化,并使用 `vue-router` 来实现路由跳转。 最后,我们需要在 `App.vue` 文件中引入并使用 `el-cascader-menu` 组件。 ```html <template> <div id="app"> <el-cascader-menu :menuList="menuList" /> </div> </template> <script> import ElCascaderMenu from '@/components/ElCascaderMenu.vue' export default { name: 'App', components: { ElCascaderMenu }, data() { return { menuList: [ { id: '1', title: '导航1', children: [ { id: '1-1', title: '选项1', children: [ { id: '1-1-1', title: '选项1-1', url: '/option-1-1' }, { id: '1-1-2', title: '选项1-2', url: '/option-1-2' } ] }, { id: '1-2', title: '选项2', url: '/option-2' } ] }, { id: '2', title: '导航2', children: [ { id: '2-1', title: '选项1', url: '/option-2-1' }, { id: '2-2', title: '选项2', url: '/option-2-2' } ] } ] } } } </script> ``` 在 `menuList` 中,我们使用了 `children` 字段来实现级联选择的效果。当某一层级的选项被选中后,其子选项会自动展示在下一层级中。 最终效果如下所示: ![el-cascader-menu](https://user-images.githubusercontent.com/26276002/138021340-2b3d6e3d-6c7c-4d19-aa1a-7b2e1d0f05d2.gif)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值