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

news2024/10/12 16:19:24

后台管理的模板很多,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简单的静态演示,不适合做复杂系统开发

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习 PostgreSQL + Spring Boot 3 +mybatisplus整合过程中的报错记录

今天计划学习 PostgreSQL&#xff0c;并顺便尝试使用 Spring Boot 3.x 框架&#xff0c;打算整合 Spring Boot 3、PostgreSQL 和 MyBatis-Plus。整合后一直出现以下报错&#xff1a; 去AI上面搜了讲的是sqlSessionFactory 或 sqlSessionTemplate 没有正确配置 初始分析&#…

MySQL-01.课程介绍

一.什么是数据库 二.数据库产品 三.课程安排

Python_函数式编程核心(高阶函数、闭包等)

函数式编程(functional programming)其实是个很古老的概念&#xff0c;诞生距今快60年啦&#xff01;最古老的函数式编程语言Lisp新出现的函数式编程语言&#xff1a;比如Erlang、Scala、clojure等热门语言&#xff1a;Python、java、JavaScript、C等都增加了函数式编程的一些特…

SpringBoot购物推荐网站开发:架构设计与技术实现

3系统分析 3.1可行性分析 通过对本东大每日推购物推荐网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本东大每日推购物推荐网站采用JAVA作为开发语言&…

SpringBoot框架下购物推荐系统的架构与实现

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常适…

VSCode搭建C/C++开发环境【Windows】

VSCode搭建C/C开发环境 1. 配置C/C开发环境1.1 下载和配置MinGW-w64编译器套件1.2 安装C/C插件 2. 在VSCode上编写C语言代码&#xff0c;并编译执行2.1 先打开一个文件夹&#xff0c;写一份C语言代码2.2 设置C/C编译的选项&#xff1a;c_cpp_properties.json2.3 创建执行任务&a…

CDGA|数据治理:唤醒“沉睡”的数据,激发无限价值潜能

在当今这个信息爆炸的时代&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;许多企业面临着数据孤岛、数据质量低下、数据利用率不高等问题&#xff0c;导致大量“沉睡”的数据未能发挥其应有的价值。数据治理&#xff0c;作为解锁这些数据宝藏的钥匙&#xff0c;…

连夜爆肝收藏各大云服务新老用户优惠活动入口地址(内含免费试用1个月的地址),适用于小白,大学生,开发者,小企业老板....

具体请前往&#xff1a;云服务器优惠活动入口大全--收藏各主流云厂商的云服务器等系列产品的优惠活动入口&#xff0c;免费试用1个月活动入口&#xff0c;让新老用户都能根据使用场景和身份快速锁定优惠权益 经济下滑&#xff0c;被优化增多&#xff0c;大学生就业难&#xff0…

Linux之如何找回 root 密码?

1、启动系统&#xff0c;进入开界面&#xff0c;在界面中按“e"进入编辑界面 2、进入编辑界面&#xff0c;使用键盘上的上下键把光标往下移动&#xff0c;找到以”Linux16“开通内容所在的行数&#xff0c;在行的最后面输入&#xff1a;init/bin/sh 3、输入完成后&…

Windows,MySQL主从复制搭建

前提&#xff1a;windows环境&#xff0c;同一个服务器安装多个相同版本的mysql数据库 多个MySQL服务搭建完成后&#xff0c;下面我们进行主从复制的相关配置 1.主数据库 执行指令 #创建用户 CREATE USER slavelocalhost IDENTIFIED BY 123456;#授权 GRANT REPLICATION SLA…

plpo vue实战版教程

vue实战版教程 什么是plpo安装1.将plop添加到您的项目2.全局安装plop(可选&#xff0c;但建议使用方便)3.在项目根目录下创建一个 plopfile.js vue 实战&#xff08;后台管理系统 - 增删改查&#xff09;所需文件文件介绍创建配置文件 plopfile.js创建模板和脚本命令文件模板创…

Emu3:北京智源推出AI多模态世界模型,超越DeepMind和微软,刷新了8项性能指标

Emu3是北京智源人工智能研究院推出的一款原生多模态世界模型&#xff0c;采用智源自研的多模态自回归技术路径&#xff0c;在图像、视频、文字上联合训练&#xff0c;使模型具备原生多模态能力&#xff0c;实现图像、视频、文字的统一输入和输出。Emu3将各种内容转换为离散符号…

食堂校园预约就餐系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;商品管理&#xff0c;论坛管理&#xff0c;用户管理&#xff0c;商家管理&#xff0c;公告信息管理&#xff0c;基础数据管理 微信端账号功能包括&#xff1a;系统首页&#xf…

【Flutter、H5、Web?前端个人总结】分享从业经历经验、自我规范准则,纯干货

前言 hi&#xff0c;正式接触web前端已经经过了两年的时间&#xff0c;从大学的java后端转型到web前端&#xff0c;再到后续转战Flutter&#xff0c;逐渐对前端有了一些心得体会&#xff0c;其实在当下前端的呈现形式一直在变化&#xff0c;无论你是用原生、还是web还是混编的…

vulnhub-Kioptrix_Level_1靶机的测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、解决检测不到IP的问题 2、信息搜集 3、利用exp ①mod_ssl2.8版本漏洞 ②smb2.2版本漏洞 四、结论 一、测试环境 1、系统环境 渗透机&#xff1a;kali2021.1(192.168.202.134) 靶 机…

【前端构建】Webpack: 现代前端开发的核心工具

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Webpack: 现代前端开发的核心工具1. 引言2. Webpack 的核心概念2.1 入口&#x…

vmware下ubuntu18.04中使用笔记本的摄像头

步骤1&#xff1a;在windows中检查相机状态 win10系统中&#xff0c;在左下的搜索栏&#xff0c;搜索“相机”&#xff0c;点击进入即可打开相机&#xff0c;并正常显示图像。 注意&#xff1a;如果相机连接到了虚拟机&#xff0c;则不能显示正常。 步骤2&#xff1a;…

解决ubuntu 下 VS code 无法打开点击没反应问题

从Ubuntu 22.04 升级到ubuntu 24.04 后&#xff0c;发现Vsode无法打开&#xff0c;不论是点击图标&#xff0c;还是terminator里面运行code 可执行程序&#xff0c;均没有反应。debug如下: 提示权限不够。 解决方案&#xff1a; sudo sysctl -w kernel.apparmor_restrict_unp…

最佳BD仓储物流方案选择秘诀!

BD仓储部署策略的执行方案是一项既精细又全面的流程&#xff0c;目的在于保障BD装备的安全保管、高效化管理以及迅速调动。以下详列了一项涵盖众多核心环节及要素的具体执行方案&#xff1a; 一、项目开展与策划 确立项目核心目标&#xff1a;精准定位BD仓储解决方案的关键目…

瑞芯微RK3399开发板Android7.1修改网络优先级方法,触觉智能演示

本文介绍Android7.1修改网络优先级方法&#xff0c;基于触觉智能SBC3968主板&#xff0c;搭载瑞芯微RK3399芯片&#xff0c;这块主板的网络优先级默认是网口&#xff1e;WiFi&#xff1e;4G&#xff0c;下面就手把手教大家怎么修改。 1、查看当前网络优先级数值 源码根目录下执…