2.vue3+ts+element-plus后台管理界面布局及动态侧边栏实现

1. 界面布局

  利用element-plus的布局组件实现:  <el-container> 整个布局容器,  <el-header> 顶部布局容器,  <el-aside> 侧边布局容器  <el-main> 主要布局容器。  采用组件化思想,将header和aside组件化,方便布局。

<template>
  <div class="common-layout">
    <el-container>

      <CommonAside />

      <el-container>
        <el-header>
          <CommonHeader />
        </el-header>
        <el-main>
          <router-view />
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>
<script lang="ts" setup>
import CommonAside from '../components/CommonAside.vue'
import CommonHeader from '../components/CommonHeader.vue'

</script>
  color: var(--el-text-color-primary);
}</style>

2.侧边栏布局及动态实现技术

侧边栏的布局,利用element-plus的el-menu组件实现。  el-menu组件实现第一级菜单,el-submenu实现第二级菜单。  el-menu-item实现菜单项,el-submenu-item实现二级菜单项。  el-menu-item-group实现菜单组,el-menu-item-group实现菜单组。

      所有菜单内容存储在数组menuData中,通过v-for指令动态渲染。通过noChildren过滤出没有子菜单的菜单数据也就是一级菜单数据。  通过hasChildren过滤出有子菜单的菜单数据也就是二级菜单数据。

  需要说明的是在vue3和elment-plus中: 
 1.el-menu-item和el-submenu-item组件的name属性值必须唯一,否则会报错。 
  index属性也必须唯一,否则后面现实菜单单击一项所有项全部响应。
 2.icon采用组件化设计,不同以前版本通过拼接字符串的方式调用组件(大多过去实现采用这种方法)。具体为:

   <component :is="item.icon" ></component>

   这块实现参考文章:https://blog.csdn.net/qq_40190624/article/details/125019530 说的较为详细。

ai推荐使用:<el-icon><icon-svg :icon-class="item.icon" /></el-icon>

   需要自定义的图标,可以到iconfont官网下载,然后放到static文件夹下,然后通过import引入。https://blog.csdn.net/qq_39246667/article/details/124347398 给出具体方法较为复杂.

  3.noChildren()方法最好存储成具体的变量,这样在代码中可以很方便的调用,而不用在v-for中直接调用函数。
<template>
    <!-- <el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
      <el-radio-button :label="false">expand</el-radio-button>
      <el-radio-button :label="true">collapse</el-radio-button>
    </el-radio-group> -->
    <el-menu default-active="2" class="el-menu-vertical-demo" :collapse="isCollapse" @open="handleOpen"
        @close="handleClose">
        <el-menu-item v-for="item in noChildren()" :key="item.name" :index="item.name">
            <component :is="item.icon" style="width: 18px;height: 18px;"></component>
            <template #title>{{item.label}}</template>
        </el-menu-item>
        <el-sub-menu v-for="item in hasChildren()" :key="item.name" :index="item.label">
            <template #title>
                <el-icon>
                    <component :is="item.icon" style="width: 18px;height: 18px;"></component>
                </el-icon>
                <span>{{item.label}}</span>
            </template>
            <el-menu-item-group v-for="subItem in item.children" :key="subItem.name">
            <el-menu-item :index="subItem.name">{{subItem.label}}</el-menu-item>
           </el-menu-item-group>
        </el-sub-menu>
    </el-menu>
</template>
  
<script lang="ts" setup>
import { ref } from 'vue'
import {
    Document,
    Menu as IconMenu,
    Location,
    Setting,
} from '@element-plus/icons-vue'

// 声明一个变量isCollapse,值为false
const isCollapse = ref(false)

const menuData = [
    {
        path: "/",
        name: "home",
        label: "首页",
        icon: 'Menu',
        url: "Home/Home",
    },
    {
        path: "/mall",
        name: "mall",
        label: "商品管理",
        icon: "Document",
        url: "MallManage/MallManage",
    },
    {
        path: "/user",
        name: "user",
        label: "用户管理",
        icon: "Setting",
        url: "UserManage/UserManage",
    },
    {
        label: "其他",
        icon: "location",
        children: [
            {
                path: "/page1",
                name: "page1",
                label: "首页",
                icon: "Setting",
                url: "Other/PageOne",
            },
            {
                path: "/page2",
                name: "page2",
                label: "首页",
                icon: "Setting",
                url: "Other/PageTwo",
            },
        ],
    },
]
// 声明一个函数handleOpen,参数为key和keyPath,用于接收参数
const handleOpen = (key: string, keyPath: string[]) => {
    console.log(key, keyPath)
}
// 声明一个函数handleClose,参数为key和keyPath,用于接收参数
const handleClose = (key: string, keyPath: string[]) => {
    console.log(key, keyPath)
}
const noChildren = () => { return menuData.filter((item) => !item.children) }
// 过滤出没有子菜单的菜单数据

const hasChildren = () => { return menuData.filter((item) => item.children) }
// 过滤出有子菜单的菜单数据

</script>
  
<style>
.el-menu-vertical-demo:not(.el-menu--collapse) {
    width: 200px;
    min-height: 400px;
}
</style>
  

注意:index 项目必须唯一 :index="item.label"  item.label选项各菜单都有且不同,子菜单项标题没有name,所以item.name报错。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3 和 Element Plus 的组合中,要实现侧边栏折叠的效果,可以使用`el-menu`作为根节点,并结合`el-menu-item`和`el-submenu`来构建菜单栏。 首先,在模板中使用`el-menu`作为整个菜单的容器,并设置`collapse`属性来控制侧边栏的折叠状态。当`collapse`为`true`时,侧边栏折叠,文字会隐藏。当`collapse`为`false`时,侧边栏展开,文字会显示。 ```html <template> <el-menu :collapse="isCollapse"> <!-- 菜单项 --> <el-menu-item index="1">菜单项1</el-menu-item> <el-menu-item index="2">菜单项2</el-menu-item> <!-- 子菜单 --> <el-submenu index="3"> <template #title> 子菜单 </template> <el-menu-item index="3-1">子菜单项1</el-menu-item> <el-menu-item index="3-2">子菜单项2</el-menu-item> </el-submenu> </el-menu> </template> ``` 然后,在data中定义一个`isCollapse`变量来控制折叠状态的切换。通过点击按钮或其他交互方式,修改`isCollapse`的值来实现侧边栏的折叠和展开。 ```javascript <script> export default { data() { return { isCollapse: true, // 初始化折叠状态为true,侧边栏默认折叠 }; }, }; </script> ``` 需要注意的是,`el-menu`标签本身希望里面嵌套的是`el-menu-item`、`el-submenu`、`el-menu-item-group`其中之一。因此,我们要根据菜单的结构来合理使用这些标签。 通过上述方法,你可以实现Vue 3 和 Element Plus 中的侧边栏折叠效果。根据`el-menu`的属性设置和交互操作来控制侧边栏的折叠和展开状态,从而实现文字的隐藏和显示效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值