vue+ElementUI—实现基础后台管理布局(sideBar+header+appMain)(附源码)

后台管理的模板很多,vue本身就提供了完整的vue-template-admin,vue-admin-beautiful等后台管理系统化框架,但是这些框架正是因为成体系而显得繁重。假如你想搭建一个静态的后台管理模板页面和几个单独的菜单页面,直接就上框架是否就有点大材小用了呢 百分之九十以上的后台管理布局基本都是头部导航,侧边栏,主内容三部分组成。所以,将其单独摘出来为一个单独的轻量后台页面就很有必要了。

1. 效果展示

最常见的系统布局就是:左右布局。左侧是菜单栏,右侧是内容区,内容区又分为头部和展示区。。所以我们的效果显示如下:

 目录结构呢,也很简单,因为不涉及请求,所以就是vue+element+vuex即可

 这种就很适合做vue的静态页面演示开发,因为就只有几个页面,不涉及复杂的路由和权限啥的。

本博文是借鉴了这篇博客写的:vue+elementUi——实现后台管理系统的布局(sideBar+header+appMain)_element ui页面布局模板-CSDN博客

但是由于它的细节问题太多,在调试过程中也遇到了一些问题,所以重新写一篇调试完后的代码,主要的就是方便你我他。

2.关键代码

如果迁入自由的项目,可以复制对应的关键代码,store代码,配置对应的路由,自己调试也可。如果想直接拿来即用的,下面也会附上vue代码git地址。

index.vue 主页面,负责引入头部,侧边栏,主内容组件

<template>
	<div class="app-wrapper">
		<div class="layout-aside" :class="isCollapse?'collapse':''">
			<div class="layout-logo">
				<router-link to="/">
					<img v-show="!isCollapse" style="width:50px;height:auto" src="@/assets/logo.png" alt="logo"/>
                    <img v-show="isCollapse" style="width:44px;height:auto" src="@/assets/logo.png" alt="logo"/>
					<!-- <span v-show="!isCollapse">工业品超市管理后台</span> -->
				</router-link>
			</div>
			<SideBar :collapse="isCollapse" />
		</div>
		<div class="layout-container" :class="{collapse:isCollapse}">
			<div class="layout-header" :class="{collapse:isCollapse}">
				<Header />
			</div>
			<div class="layout-main">
				<AppMain />
			</div>
		</div>
	</div>
</template>
<script>
	import Header from "@/components/Header";
	import SideBar from "@/components/SideBar";
	import AppMain from "@/components/AppMain";
	export default{
		name:'layout',//此页面在router/index.js中对应的name
		components:{Header,SideBar,AppMain},
		computed:{
           isCollapse:function(){
                return this.$store.state.isCollapse;
            }
        },
		methods:{
			
		}
	}
</script>
<style lang="scss" scoped>
.app-wrapper{
	position:relative;
}
.layout-aside{
	position:fixed;
	left:0;
	top:0;
	height:100vh;
	width:210px;
	transition:all 0.3s;
	background-color:#fff;
	.layout-logo{
		height:60px;
		background-color:#ffffff;
		a{
			display:flex;
			width:100%;
			height:60px;
			justify-content:center;
			align-items:center;
		}
		img{
			width:100px;
			height:auto;
		}
	}
}
.layout-aside.collapse{
	width:64px;
}
.layout-container{
	margin-left:210px;
	height:100%;
	overflow:hidden;
}
.layout-container.collapse{
	margin-left:64px;
	transition:all 0.1s;
}
.layout-header{
	position:fixed;
	z-index:1;
	top:0;
	right:0;
	width:calc(100% - 210px);
	height:60px;
	box-shadow:0 1px 3px rgba(0,21,41,0.08);
	background-color:#fff;
}
.layout-header.collapse{
	width:calc(100% - 64px);
	transition:all 0.1s;
}
.layout-main{
	padding: 20px;
	min-height:calc(100vh - 150px);
	margin:70px 15px 10px 10px;
	background-color:#fff;
}
</style>

Header头部部分:

<template>
	<div class="header-wrapper">
		<div class="header-left">
			<div class="open-icon" @click="handleCollapse">
				<i class="el-icon-s-fold" v-show="!isMenuOpen"></i>
				<i class="el-icon-s-unfold" v-show="isMenuOpen"></i>
                <span style="font-size:16px;margin-left:5px">梦缘系统</span>
			</div>
			<el-breadcrumb separator="/">
				<template v-for="(item,index) in breadcrumbList">
					<el-breadcrumb-item :key="index" v-if="item.meta.title" :to="{path:item.path}">
					</el-breadcrumb-item>
				</template>
			</el-breadcrumb>
		</div>
		<div class="header-right">
			<span class="header-user">{{currentName}},欢迎回来</span>
			<el-dropdown  trigger="click">
				<span class="el-dropdown-line">
					<img src="https://liuqingwushui.top/usr/uploads/2024/10/09/1728443808722546.jpg" style="border-radius:50%;width:32px" alt="avatar"/>
					<i class="el-icon-arrow-down el-icon--right"></i>
				</span>
				<el-dropdown-menu slot="dropdown">
					<el-dropdown-item  icon="el-icon-setting">修改密码</el-dropdown-item >
					<el-dropdown-item  icon="el-icon-guide" @click.native="handleLogout">退出登录</el-dropdown-item >
				</el-dropdown-menu>
			</el-dropdown>
		</div>
	</div>
</template>
<script>
	// import {logout} from "@/api/user";
	export default{
		name:'Header',
		data(){
            return {
                isMenuOpen:false,
                breadcrumbList:[],
                currentName:'admin'
            }
		},
		watch:{
			$route(to,from){
				this.updateBreadcrumb(to.matched);
			}
		},
		mounted(){
			this.updateBreadcrumb(this.$route.matched);
		},
		methods:{
			updateBreadcrumb(list=[]){
				this.breadcrumbList = list;
			},
			handleCollapse(){
				this.isMenuOpen= !this.isMenuOpen;
				this.$store.commit('changeCollapse',this.isMenuOpen);
			},
			handleLogout(){
				this.$confirm('确认退出?','提示',{
					confirmButtonTextt:'确定',
					cancelButtonText:'取消',
					type:'warning'
				}).then(()=>{
					//logout();
					this.$router.push('/login');
				}).catch(()=>{})
			}
		}
	}
</script>
<style lang="scss" scope>
.header-wrapper{
	display:flex;
	justify-content:space-between;
	align-content:center;
	padding:0 15px;
	height:60px;
	.header-left{
		display:flex;
		align-items:center;
		.open-icon{
			font-size:20px;
			margin-right:15px;
			cursor:pointer;
            display: flex;
            align-items: center;
		}
	}
	.header-right{
		display:flex;
		align-items:center;
		.header-user{
			margin-right:15px;
		}
	}
}
.el-dropdown-link{
	cursor:pointer;
	color:#409eff;
	img{
		width:40px;
		height:40px;
		border-radius:5px;
	}
}
.el-icon-arrow-down{
	font-size:12px;
}
.demostration{
	display:block;
	color:#8492a6;
	font-size:14px;
	margin-bottom:20px;
}
</style>

Sidebar侧边栏部分:

<template>
	<el-scrollbar class="sidebar-scroll">
        <el-menu  class="el-menu-vertical-demo" :default-active="this.$route.path"  :collapse="isCollapse" router>
            <template v-for="(item,index) in menuData">
                <el-submenu v-if="item.children && item.children.length > 0" :key="index" :index="item.path">
                    <template slot="title">
                    <i :class="item.meta.icon"></i>
                    <span>{{ item.meta.title }}</span>
                    </template>
                    <el-menu-item
                        v-for="(child,childIndex) in item.children"
                        :key="`${index}-${childIndex}`"
                        :index="child.path"
                    >
                    <i :class="child.meta.icon"></i>
                    <span>{{ child.meta.title }}</span>
                    </el-menu-item>
                </el-submenu>
                <el-menu-item v-else :key="index" :index="item.path">
                    <i :class="item.meta.icon"></i>
                    <span>{{ item.meta.title }}</span>
                </el-menu-item>
            </template>
        </el-menu>
	</el-scrollbar>
</template>
<script>
    import {mapState,mapGetters} from "vuex";
    export default{
        name:'SideBar',
        computed:{
            ...mapGetters(['firstMenu','subMenu','menuData']),
            isCollapse:function(){
                return this.$store.state.isCollapse;
            }
        },
        props:{
            collapse:{
                type:Boolean,
                default:false
            }
        },
        data(){
            return {
                currentRouter:''
            }
        },
        watch:{
            $route(to,from){
                this.currentRouter = to.path;
            }
        },
        mouted(){
            this.currentRouter = this.$route.path;
        },
        methods:{
        }
    }
</script>
<style lang="scss" scoped>
	.sidebar-scroll{
		height:calc(100% - 60px);
	}
	.sidebar{
		height:100%;
		text-align:left;
		border-right:none;
	}
    .el-menu-vertical-demo:not(.el-menu--collapse) {
        width: 210px;
        min-height: 400px;
    }
</style>

Appmain主内容部分:

<template>
	<div class="app-main">
		<transition name="fade-transfrom" mode="out-in">
			<router-view />
		</transition>
	</div>
</template>
<script>
export default{
	name:'AppMain'
}
</script>
<style lang="scss" scope>
	.app-main{
		width:100%;
		height:100%;
	}
</style>

Store状态管理js:

// src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state:{
    isCollapse:false,
    menuData:[
            {
                path:'/dream/home',
                meta:{
                    icon:'el-icon-data-line',
                    title:'首页'
                }
            },
      {
                path:'/dream/2',
                meta:{
                    icon:'el-icon-office-building',
                    title:'梦缘'
                }
            },
      {
                path:'/dream/3',
                meta:{
                    icon:'el-icon-place',
                    title:'流情'
                }
            },
      {
                path:'/dream/4',
                meta:{
                    icon:'el-icon-postcard',
                    title:'日志'
                }
            },
      {
                path:'/dream/5',
                meta:{
                    icon:'el-icon-pie-chart',
                    title:'数据'
                },
                children:[
                  {
                    path:'/dream/6',
                    meta:{
                        icon:'el-icon-postcard',
                        title:'数据1'
                    }
                },
                ]   
            }
        ]
  },
  mutations:{
    changeCollapse: (state,isCollapse) => {
        state.isCollapse = isCollapse
    },
    setMenuData(state,menuData){
    state.menuData = menuData;
    }
  },
  actions: {
    // 异步 actions
  },
  getters:{
		menuData(state,rootState){
			if(state.filterMenu){
				const {permissions,roles} = rootState.accout;
				return filterMenu(JSON.parse(JSON.stringfy(state.menuData)),permissions,roles)
			}
			return state.menuData;
		},
		firstMenu(state){
			const {menuData} = state;
			if(menuData.length>0&&!menuData[0].fullPath){
				formatFullPath(menuData);
			}
			return menuData.map(item=>{
				const menuItem = {...item};
				delete menuItem.children;
				return menuItem
			})
		},
		subMenu(state){
			const {menuData,activateFirst} = state;
			if(menuData.length>0&&!menuData[0].fullPath){
				formatFullPath(menuData);
			}
			const current = menuData.find(menu=>menu.fullPath== activatedFirst);
			return current && current.chilren||[]
		}
	},
  modules: {
    // 模块
  }
});

3.示例源码下载

git地址:vue-admin-static: vue+element后台管理极简版:头部和侧边导航栏,固定路由。适合写vue简单的静态演示,不适合做复杂系统开发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/890247.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

维生素对于生活的重要性

在探索健康奥秘的旅途中&#xff0c;维生素作为人体不可或缺的微量营养素&#xff0c;扮演着至关重要的角色。它们虽不直接提供能量&#xff0c;却是酶促反应、细胞代谢、免疫功能乃至心理健康的基石。今天&#xff0c;让我们一同深入探讨人体所需补充的维生素&#xff0c;这些…

VSCode 使用 EmmyLua 对lua进行调试

时间&#xff1a;2024年10月 其他&#xff1a;win10&#xff0c;EmmyLua v0.8.20 参考&#xff1a;https://blog.csdn.net/ShenHaoDeHao/article/details/140268354 有几个概念搞清楚就好理解了。一般开发中&#xff0c;我们编写的lua文件由宿主程序的来解析、执行&#xff1…

【计算机网络 - 基础问题】每日 3 题(三十九)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞…

软件设计师(软考学习)

数据库技术 数据库基础知识 1. 数据库中的简单属性、多值属性、复合属性、派生属性简单属性&#xff1a;指不能够再分解成更小部分的属性&#xff0c;通常是数据表中的一个列。例如学生表中的“学号”、“姓名”等均为简单属性。 多值属性&#xff1a;指一个属性可以有多个值…

目标检测——YOLO11算法解读

作者&#xff1a;Ultralytics公司 代码&#xff1a;https://github.com/ultralytics/ultralytics YOLO系列算法解读&#xff1a; YOLOv1通俗易懂版解读、SSD算法解读、YOLOv2算法解读、YOLOv3算法解读、YOLOv4算法解读、YOLOv5算法解读、YOLOR算法解读、YOLOX算法解读、YOLOv6算…

分布式数据库的进度管理:TiDB 备份恢复工具 PiTR 的原理与实践

导读 对于一款企业级数据库产品而言&#xff0c;数据的安全性和可恢复性是至关重要的。PiTR&#xff08;Point in Time Restore&#xff09;作为 TiDB 备份工具的核心功能之一&#xff0c;提供了一种精细的数据恢复能力&#xff0c;允许用户将数据库集群恢复到过去的任意时间点…

1.MySQL存储过程基础(1/10)

引言 数据库管理系统&#xff08;Database Management System, DBMS&#xff09;是现代信息技术中不可或缺的一部分。它提供了一种系统化的方法来创建、检索、更新和管理数据。DBMS的重要性体现在以下几个方面&#xff1a; 数据组织&#xff1a;DBMS 允许数据以结构化的方式存…

8.优化存储过程的性能(8/10)

优化存储过程的性能 1.引言 存储过程是数据库系统中预先编写好的SQL语句集合&#xff0c;它们被保存在数据库服务器上&#xff0c;可以在需要时被调用执行。存储过程的使用可以提高数据库操作的效率&#xff0c;减少网络通信&#xff0c;并且可以封装复杂的逻辑&#xff0c;使…

无人机之交互系统篇

一、系统构成 无人机交互系统通常由多个子系统组成&#xff0c;包括但不限于&#xff1a; 多模式人机交互装置&#xff1a;这是人机交互系统的基础层&#xff0c;通常包括计算机、局域网、传感器等设备&#xff0c;用于实现操作员与无人机之间的数据交互和指令传递。例如&…

新型物联网电力数据采集器 智能网关通讯协议有哪些?

随着智能化技术的快速发展&#xff0c;电气监测与管理在各个域的应用愈发重要&#xff0c;在物联网&#xff08;IoT&#xff09;应用的发展中&#xff0c;网关扮演着至关重要的角色。它作为连接设备与云平台或数据中心的桥梁&#xff0c;负责数据的收集、处理和传输。网关不仅支…

鸿蒙开发之ArkUI 界面篇 三十四 容器组件Tabs一

当页面较多时&#xff0c;可以通过Tabs组件进行展示&#xff0c;如下图&#xff0c;支持顶部、底部、侧边栏 Tabs页面需两个组件&#xff0c;分别是TabContent和TabBar。TabContent必须有&#xff0c;TabBar是导航标题&#xff0c;可以没有也能显示&#xff0c;只是没有标题提示…

uniapp__微信小程序使用秋云ucharts折线图双轴

1、子组件 <template><view class"charts-box"><qiun-data-charts type"line":opts"computedOpts":chartData"chartData"/></view> </template><script> export default {props: {chartData: {t…

【论文阅读】Learning a Few-shot Embedding Model with Contrastive Learning

使用对比学习来学习小样本嵌入模型 引用&#xff1a;Liu, Chen, et al. “Learning a few-shot embedding model with contrastive learning.” Proceedings of the AAAI conference on artificial intelligence. Vol. 35. No. 10. 2021. 论文地址&#xff1a;下载地址 论文代码…

沉浸式娱乐新纪元,什么是5G+实时云渲染VR大空间解决方案?

近年来&#xff0c;虚拟现实&#xff08;VR&#xff09;技术在娱乐、教育、医疗等多个领域展现出巨大的潜力&#xff0c;尤其是VR大空间体验&#xff0c;更是以其沉浸式和互动性的特点&#xff0c;迅速成为市场的新宠。据Statista数据显示&#xff0c;2023年&#xff0c;全球虚…

【笔记】Day2.5.1查询运费模板列表(未完

&#xff08;一&#xff09;代码编写 1.阅读需求&#xff0c;确保理解其中的每一个要素&#xff1a; 获取全部运费模板&#xff1a;这意味着我需要从数据库中查询所有运费模板数据。按创建时间倒序排序&#xff1a;这意味着查询结果需要根据模板的创建时间进行排序&#xff0…

【Java】集合中单列集合详解(一):Collection与List

目录 引言 一、Collection接口 1.1 主要方法 1.1.1 添加元素 1.1.2 删除元素 1.1.3 清空元素 1.1.4 判断元素是否存在 1.1.5 判断是否为空 1.1.6 求取元素个数 1.2 遍历方法 1.2.1 迭代器遍历 1.2.2 增强for遍历 1.2.3 Lambda表达式遍历 1.2.4 应用场景 二、…

【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可…

aws(学习笔记第二课) AWS SDK(node js)

aws(学习笔记第二课) 使用AWS SDK&#xff08;node js&#xff09; 学习内容&#xff1a; 使用AWS SDK&#xff08;node js&#xff09; 1. AWS SDK&#xff08;node js&#xff09; AWS支持多种SDK开发(除了AWS CLI&#xff0c;还支持其他的SDK) AndroidPythonNode.js(Javas…

数据结构-C语言顺序栈功能实现

栈 栈&#xff1a;类似于一个容器&#xff0c;如我们生活中的箱子&#xff0c;我们向箱子里放东西&#xff0c;那么最先放的东西是最后才能拿出来的 代码实现 #include <stdio.h> #include <stdlib.h>#define MAX_SIZE 100typedef struct {int* base; // 栈底指针…

[Linux#65][TCP] 详解 延迟应答 | 捎带应答 | 流量控制 | 拥塞控制

目录 一、延迟应答 二、捎带应答 三. 流量控制 总结 四. 拥塞控制 1. 拥塞控制 2. 慢启动机制&#xff1a; 3.思考 4.拥塞避免算法 5. 快速恢复算法 一、延迟应答 1. 立即应答问题 接收数据的主机若立刻返回ACK应答&#xff0c;可能返回的窗口较小。例如&#xff1…