赞
踩
样式如上
需要typescript,vue3环境下运行
需要下载依赖如下
- npm install sass-loader node-sass --save-dev
-
- npm install element-plus --save
-
- npm install view-ui-plus@1.3.1 --save
-
-
-
- main.ts中
- import 'view-ui-plus/dist/styles/viewuiplus.css'
-
- import ElementPlus from 'element-plus'
- import 'element-plus/dist/index.css'
-
-
- app.use(ElementPlus)
需要scss以及,element-plus
- <template>
- <div class="sidebar">
- <el-menu :default-active="activeIndex" class="menu" active-text-color="#FFFFFF" background-color="#060E83"
- text-color="#fff" :unique-opened="true" router @select="handleSelect" @close="menuClose" @open="menuOpen">
- <template v-for="menus in ItemList" :key="menus">
- <el-sub-menu :key="menus.menuId" :index="menus.index" v-if="menus.childs">
- <template #title>
- <img :src="menus.icon" alt="" style="margin-right: 16px;width: 22px;height: 22px;">
- <span>{{ menus.title }}</span>
- </template>
- <el-timeline style="box-sizing: border-box;padding-left: 20px;">
- <el-timeline-item v-for="(childvl, ci) in menus.childs" :key="ci" center @click="changeColor">
- <!-- {{ activity.content }} -->
- <el-menu-item :index="childvl.index" :key="ci" style="margin-bottom:10px;">{{
- childvl.title
- }}</el-menu-item>
- </el-timeline-item>
- </el-timeline>
- </el-sub-menu>
- <el-menu-item :index="menus.index" v-else style="margin-bottom:10px;">
- <img :src="menus.icon" alt="" style="margin-right: 16px;">
- <span>{{ menus.title }}</span>
- </el-menu-item>
- </template>
- </el-menu>
- </div>
- </template>
-
- <script lang="ts" setup>
- import getData from "@/assets/json/st_classlist.json";
- import { ref, onMounted } from "vue";
- const ItemList: any = ref([])
- const activeIndex = ref('')
- const handleSelect = (key: any) => {
- activeIndex.value = key
- }
- function addRouterIndex() {
- setTimeout(() => {
- const childrenArray = ItemList.value.map((item: any) => {
- return item.childs;
- });
- //用来存放child里不为null的值
- let intChild = []
- intChild = childrenArray.filter(function (val: any) {
- return val
- });
- //把intChild中的所有数组拼接起来
- const flattenedArray = intChild.reduce((acc: any[], cur: any) => {
- return acc.concat(cur);
- }, []);
- //获取该路由所对应的下标
- const index = flattenedArray.findIndex((person: { index: string; }) => person.index === activeIndex.value);
- let nodes = document.querySelectorAll('.el-timeline-item__node')[index] as HTMLElement
- if (nodes) {
- nodes.style.background = "#fff"
- nodes.style.transition = "0.5s"
- }
- }, 100);
- }
- const popstate = () => {
- activeIndex.value = location.hash.split("/")[1]
- addRouterIndex()
- }
- const changeColor = () => {
- addRouterIndex()
- }
- const menuClose = () => {
- addRouterIndex()
- }
- const menuOpen = () => {
- addRouterIndex()
- }
- onMounted(() => {
- // console.log(getData.data);
- ItemList.value = getData.data
- popstate()
- window.addEventListener('popstate', popstate, false);
- addRouterIndex()
- console.log(ItemList.value);
- })
- </script>
-
- <style scoped lang="scss">
- .sidebar {
- height: calc(100vh - 76px);
- box-shadow: 2px 0px 6px 0px rgba(0, 0, 0, 0.1);
-
- .menu {
- border-right: unset;
- height: 100%;
- width: 240px;
- font-size: 16px;
-
- .el-sub-menu {
- width: 224px;
- height: auto;
- border-radius: 8px;
- margin: auto;
- }
-
- ::v-deep .el-sub-menu__title {
- font-size: 16px;
- }
-
- .el-menu-item {
- // width: 224px;
- height: 50px;
- border-radius: 8px;
- margin: auto;
- font-size: 16px;
- }
-
- .is-active {
- background: rgba(94, 103, 246, 0.3);
- }
-
- .logo {
- height: 50px;
- line-height: 50px;
- padding: 0 10px;
- overflow: hidden;
-
- img {
- vertical-align: middle;
- margin-left: 6px;
- }
-
- span {
- font-weight: bold;
- font-size: 16px;
- }
- }
- }
-
- .menu:not(.el-menu--collapse) {
- width: 240px;
- }
- }
-
- ::v-deep .el-sub-menu .el-menu-item {
- min-width: 0;
- }
-
- ::v-deep .el-timeline-item__wrapper {
- top: 0px !important;
- height: 49px;
- }
-
- ::v-deep .el-timeline-item__node {
- background: #2B329A;
- }
-
- .el-timeline {
- --el-timeline-node-color: #2B329A;
- }
-
- .el-active-fff {
- background: #fff;
- }
-
- ::v-deep .el-timeline-item__wrapper {
- height: 40px;
- }
-
- .sidebar .menu[data-v-0f7446ba]:not(.el-menu--collapse) {
- box-sizing: border-box;
- padding-top: 20px;
- }
- </style>
下面是JSON文件内容
- {
- "code": 200,
- "message": "操作成功",
- "data": [
- {
- "index": "ceshione",
- "icon": "https://img.icons8.com/3d-fluency/2x/fingerprint.png%202x,%20https://img.icons8.com/3d-fluency/1x/fingerprint.png",
- "title": "测试",
- "menuId": "1082",
- "component": null,
- "childs": [
- {
- "index": "ceshitwo",
- "icon": "#",
- "title": "测试",
- "menuId": "1087",
- "component": null,
- "childs": null
- },
- {
- "index": "ceshithree",
- "icon": "#",
- "title": "测试",
- "menuId": "1088",
- "component": null,
- "childs": null
- }
- ]
- },
- {
- "index": "ceshifore",
- "icon": "https://img.icons8.com/3d-fluency/2x/fingerprint.png%202x,%20https://img.icons8.com/3d-fluency/1x/fingerprint.png",
- "title": "测试",
- "menuId": "1083",
- "component": null,
- "childs": [
- {
- "index": "ceshifive",
- "icon": "#",
- "title": "测试",
- "menuId": "1089",
- "component": null,
- "childs": null
- }
- ]
- },
- {
- "index": "",
- "icon": "https://img.icons8.com/3d-fluency/2x/fingerprint.png%202x,%20https://img.icons8.com/3d-fluency/1x/fingerprint.png",
- "title": "测试",
- "menuId": "1084",
- "component": null,
- "childs": [
- {
- "index": "ceshisix",
- "icon": "#",
- "title": "测试",
- "menuId": "1001",
- "component": null,
- "childs": null
- }
- ]
- },
- {
- "index": "#",
- "icon": "https://img.icons8.com/3d-fluency/2x/fingerprint.png%202x,%20https://img.icons8.com/3d-fluency/1x/fingerprint.png",
- "title": "测试",
- "menuId": "1086",
- "component": null,
- "childs": [
- {
- "index": "ceshieight",
- "icon": "#",
- "title": "测试",
- "menuId": "1089",
- "component": null,
- "childs": null
- }
- ]
- }
- ]
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。