【前端】Vue+Element UI案例:通用后台管理系统-导航栏

news2025/1/21 5:54:46

文章目录

    • 目标
    • 代码
      • 0.数据
      • 1.其他准备
      • 2.结构
      • 3.动态显示数据
      • 4.主题:背景色,点击悬停效果
      • 5.去除padding
      • 6.去除下拉框
      • 7.标题
      • 8.路由跳转
    • 总代码
      • 组件CommonAside.vue
      • 文件结构
    • 参考

参考视频: VUE项目,VUE项目实战,vue后台管理系统,前端面试,前端面试项目

案例链接
【前端】Vue+Element UI案例:通用后台管理系统-导航栏(视频p1-16)https://blog.csdn.net/karshey/article/details/127640658
【前端】Vue+Element UI案例:通用后台管理系统-Header+导航栏折叠(p17-19)https://blog.csdn.net/karshey/article/details/127652862
【前端】Vue+Element UI案例:通用后台管理系统-Home组件:卡片、表格(p20-22)https://blog.csdn.net/karshey/article/details/127674643
【前端】Vue+Element UI案例:通用后台管理系统-Echarts图表准备:axios封装、mock数据模拟实战(p23-25)https://blog.csdn.net/karshey/article/details/127735159
【前端】Vue+Element UI案例:通用后台管理系统-Echarts图表:折线图、柱状图、饼状图(p27-30)https://blog.csdn.net/karshey/article/details/127737979
【前端】Vue+Element UI案例:通用后台管理系统-面包屑、tag栏(p31-35)https://blog.csdn.net/karshey/article/details/127756733
【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写、Dialog对话框弹出(p36-38)https://blog.csdn.net/karshey/article/details/127787418
【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Table表格增删查改、Pagination分页、搜索框(p39-42)https://blog.csdn.net/karshey/article/details/127777962
【前端】Vue+Element UI案例:通用后台管理系统-登陆页面Login(p44)https://blog.csdn.net/karshey/article/details/127795302
【前端】Vue+Element UI案例:通用后台管理系统-登陆页面功能:登录权限跳转、路由守卫、退出(p45-46)https://blog.csdn.net/karshey/article/details/127849502
【前端】Vue+Element UI案例:通用后台管理系统-登陆不同用户显示不同菜单、动态添加路由(p47-48)https://blog.csdn.net/karshey/article/details/127865621
【前端】Vue+Element UI案例:通用后台管理系统-项目总结https://blog.csdn.net/karshey/article/details/127867638

目标

在这里插入图片描述

  • 悬停效果
  • 点击效果
  • 其他:点击展开和收缩
  • 动态显示“首页”“商品管理”等
  • 有路由跳转

其实是项目的导航栏组件。只打算看导航栏部分的可以跳过1.其他准备

代码

0.数据

我们把它单独放到一个MenuData.js中,然后用export default暴露出来。

{
      path: '/',
      name: 'home',
      label: '首页',
      icon: 's-home',
      url: 'Home/Home'
    },
    {
      path: '/mall',
      name: 'mall',
      label: '商品管理',
      icon: 'video-play',
      url: 'MallManage/MallManage'
    },
    {
      path: '/user',
      name: 'user',
      label: '用户管理',
      icon: 'user',
      url: 'UserManage/UserManage'
    },
    {
      label: '其他',
      icon: 'location',
      children: [
        {
          path: '/page1',
          name: 'page1',
          label: '页面1',
          icon: 'setting',
          url: 'Other/PageOne'
        },
        {
          path: '/page2',
          name: 'page2',
          label: '页面2',
          icon: 'setting',
          url: 'Other/PageTwo'
        }
      ]
    }

1.其他准备

注意要查看官方文档:官方文档

全局引入Element UI

先安装Element UI:

npm i element-ui -S

全局引入:在main.js中

import ElementUI from 'element-ui'

Vue.use(ElementUI)

路由配置

这里我们先配置Home页面(会显示导航栏的页面)。官方文档:Vue Router

安装:这里的版本是3.6.5
ps:可以在npm网站上查到包的所有版本,我们这里要的是3.x.x的最新版。

npm install vue-router@3.6.5

路由的配置:目前只配置了Main组件的

import Vue from "vue";
import VueRouter from "vue-router";
import Main from '../Views/Main'

Vue.use(VueRouter)

const routes=[
    // 主路由
    {
        path:'/',
        component:Main
    }
]

const router = new VueRouter({
    routes
})

export default router

目前的依赖
当前的package.json文件的dependencies应当如下:

"dependencies": {
    "core-js": "^3.8.3",
    "element-ui": "^2.15.10",
    "vue": "^2.6.14",
    "vue-router": "^3.6.5"
  }

当前的main.js

import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';
import router from './router/index'

Vue.config.productionTip = false
Vue.use(ElementUI)

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

Main.vue布局结构
要的是这个布局:
在这里插入图片描述
找到对应代码:

<el-container>
  <el-aside width="200px">Aside</el-aside>
  <el-container>
    <el-header>Header</el-header>
    <el-main>Main</el-main>
  </el-container>
</el-container>

把它放到Main.vue里。

App.vue如下:

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
export default {
}
</script>

<style>

</style>

效果:
在这里插入图片描述
接下来我们写一个组件:CommonAside.vue,把导航栏写在这个组件里,再把组件放到Aside中。

因此放了布局的Main.vue如下:

<template>
    <el-container>
        <el-aside width="200px">
            <common-aside/>
        </el-aside>
        <el-container>
            <el-header>Header</el-header>
            <el-main>Main</el-main>
        </el-container>
    </el-container>
</template>

<script>
import CommonAside from '../components/CommonAside.vue'
export default {
    data(){
        return{}
    },
    components:{
        CommonAside
    }
}
</script>

<style>

</style>

组件CommonAside如下:

<template>
  <!-- 在这里开始写导航栏 -->
</template>

<script>
export default {

}
</script>

<style>

</style>

接下来就是本文正题:导航栏。

2.结构

Element UI文档
我们现在Element UI官方文档上找到类似的导航结构:就是你了!
在这里插入图片描述
阅读代码,我们不难发现代码分为“展开收起”部分和“导航”部分,我们要的是导航部分。把代码对着我们的目标稍作调整得到:

<el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
    :collapse="isCollapse">
    <el-menu-item index="2">
        <i class="el-icon-menu"></i>
        <span slot="title">导航一</span>
    </el-menu-item>
    <el-submenu index="1">
        <template slot="title">
            <i class="el-icon-location"></i>
            <span slot="title">导航二</span>
        </template>
        <el-menu-item-group>
            <span slot="title">分组一</span>
            <el-menu-item index="1-1">选项1</el-menu-item>
            <el-menu-item index="1-2">选项2</el-menu-item>
        </el-menu-item-group>
    </el-submenu>
</el-menu>

效果:
在这里插入图片描述

3.动态显示数据

导航栏分为一级导航栏和二级导航栏,目标中的 其他-页面1 就是二级导航栏,首页、商品管理、用户管理 都是一级导航栏。

一级和二级的区别在于:数据中是否有children属性,如果有,那它的children属性就是二级导航。所以这里要用到计算属性

computed:{
   noChildren(){
       // 如果没有children则返回true,会被过滤器留下
       return this.MenuData.filter(item=>!item.children)
   },
   hasChildren(){
       return this.MenuData.filter(item=>item.children)
   }
}

一级导航栏的循环显示:

<!-- 观察数据,我们发现name是唯一标识 -->
<!-- 查看文档,index是唯一标识 -->
 <el-menu-item v-for="item in noChildren" :key="item.name" :index="item.name">
     <!-- 这里是字体图标,用模板字符串拼接,注意要动态绑定 -->
     <i :class="`el-icon-${item.icon}`"></i>
     <span slot="title">{{item.label}}</span>
 </el-menu-item>

效果:
在这里插入图片描述
二级导航栏也是类似做法:

<el-submenu v-for="item in hasChildren" :key="item.name" :index="item.name">
        <template slot="title">
            <i :class="`el-icon-${item.icon}`"></i>
            <span slot="title">{{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-submenu>
</el-menu>

效果:
在这里插入图片描述

4.主题:背景色,点击悬停效果

再次打开文档,找到自定义颜色部分:
在这里插入图片描述
显然是这里:我们把它直接复制粘贴。
在这里插入图片描述
则标签如下:

<el-menu default-active="1-4-1" 
class="el-menu-vertical-demo" 
@open="handleOpen" 
@close="handleClose"
:collapse="isCollapse" 
background-color="#545c64" 
text-color="#fff" 
active-text-color="#ffd04b">

效果:就是这样!
在这里插入图片描述

5.去除padding

在浏览器中F12可知,padding是由body等标签自动带有的,我们只需要在App.vue中把它们清除即可(reset)。

html,
body,
h3,
p {
  margin: 0;
  padding: 0
}

6.去除下拉框

这里我们先安装less:这样写CSS可以嵌套,更加方便。

npm install less less-loader --save

浏览器F12,显然有下拉框的这个类是:el-menu
在这里插入图片描述
把el-menu设置成height:100vh即可。

7.标题

html:

<!-- 要放到导航栏里面 -->
<h3>通用后台管理系统</h3>

css:

<style lang="less" scoped>
.el-menu{
    height:100vh;
    
    h3{
        text-align: center;
        line-height: 48px;
        color: #fff;
        font-size: 16px;
        font-weight: 400;
    }
}
</style>

效果:
在这里插入图片描述

8.路由跳转

添加点击事件:

<el-menu-item 
@click="clickItem(item)" 
v-for="item in noChildren" 
:key="item.name" 
:index="item.name">
<el-menu-item-group v-for="subItem in item.children" :key="subItem.name">
    <el-menu-item @click="clickItem(subItem)" :index="subItem.name">{{ subItem.label }}</el-menu-item>
</el-menu-item-group>

js:

clickItem(item){
   // 防止自己跳自己的报错
   if(this.$route.path!==item.path&&!(this.$route.path==='/home'&&(item.path==='/'))){
       this.$router.push(item.path)
   }
}

不过目前只有一个路由。

总代码

组件CommonAside.vue

<template>
    <el-menu default-active="1-4-1" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
        :collapse="isCollapse" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
        <!-- 要放到导航栏里面 -->
        <h3>通用后台管理系统</h3>
        <!-- 观察数据,我们发现name是唯一标识 -->
        <!-- 查看文档,index是唯一标识 -->
        <el-menu-item @click="clickItem(item)" v-for="item in noChildren" :key="item.name" :index="item.name">
            <!-- 这里是字体图标,用模板字符串拼接,注意要动态绑定 -->
            <i :class="`el-icon-${item.icon}`"></i>
            <span slot="title">{{ item.label }}</span>
        </el-menu-item>
        <el-submenu v-for="item in hasChildren" :key="item.name" :index="item.name">
            <template slot="title">
                <i :class="`el-icon-${item.icon}`"></i>
                <span slot="title">{{ item.label }}</span>
            </template>
            <el-menu-item-group @click="clickItem(subItem)" 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-submenu>
    </el-menu>
</template>

<style lang="less" scoped>
.el-menu-vertical-demo:not(.el-menu--collapse) {
    width: 200px;
    min-height: 400px;
}

.el-menu{
    height:100vh;

    h3{
        text-align: center;
        line-height: 48px;
        color: #fff;
        font-size: 16px;
        font-weight: 400;
    }
}
</style>

<script>
import MenuData from '../data/MenuData'
export default {
    data() {
        return {
            isCollapse: false,
            MenuData
        };
    },
    methods: {
        handleOpen(key, keyPath) {
            console.log(key, keyPath);
        },
        handleClose(key, keyPath) {
            console.log(key, keyPath);
        },
        clickItem(item){
            // 防止自己跳自己的报错
            if(this.$route.path!==item.path&&!(this.$route.path==='/home'&&(item.path==='/'))){
                this.$router.push(item.path)
            }
        }
    },
    computed: {
        noChildren() {
            // 如果没有children则返回true,会被过滤器留下
            return this.MenuData.filter(item => !item.children)
        },
        hasChildren() {
            return this.MenuData.filter(item => item.children)
        }
    }
}
</script>

文件结构

在这里插入图片描述

参考

VUE项目,VUE项目实战,vue后台管理系统,前端面试,前端面试项目:p1-16

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

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

相关文章

Vue父传子详细教程

本文父组件&#xff1a;shopping.vue 子组件&#xff1a;shoplist.vue 1.父组件引入子组件 1.1.引入组件 import shoplist from ../shoplist.vue 1.2.注册组件 components: { shoplist } 1.3.使用组件 <shoplist></shoplist> 2.父组件定…

vue-admin-beautiful:npm ERR! code ERESOLVE npm ERR! code E451

记录一个离谱的编译错误。 克隆vue-admin-beautiful项目&#xff0c;master分支可以正常拉取&#xff0c;vue3.0-antdv编译报下面的错误。 尝试一&#xff1a; $ cnpm install Install fail! Error: GET https://registry.npmmirror.com/vab-config response 451 status Error…

Java-web实现用户登录、注册功能

目录环境搭建数据库用户登录需求分析代码实现编写UserMapper类编写User类编写loginServlet类编写login.html编写login.css用户注册需求分析代码编写编写UserMapper类编写registerServlet类编写register.html编写register.css编写SqlSessionFactory工具类项目总体架构运行展示案…

css绘制一个Pinia小菠萝

效果如下&#xff1a; pinia小菠萝分为头部和身体&#xff0c;头部三片叶子&#xff0c;菠萝为身体 头部 先绘制头部的盒子&#xff0c;将三片叶子至于头部盒子中 先绘制中间的叶子&#xff0c;利用border-radius实现叶子的效果&#xff0c;可以借助工具来快速实现圆角的预想…

SpringBoot 单元测试——JUnit5

目录 1、JUnit5概述 1.1、JUnit5 构成 1.2、JUnit5 配置 1.2.1、导入 Junit5 开发场景 1.2.2、Junit5 开发场景自动导入依赖项 2、JUnit5 使用 2.1、Jnuit5 测试代码开发 2.1.1、测试代码格式 2.1.2、测试样例 2.2、JUnit5常用注解 2.2.1、Test :表示方法是测试方法。…

【云原生 | 23】Docker运行Web服务实战之Tomcat

作者简介&#xff1a;&#x1f3c5;云计算领域优质创作者&#x1f3c5;新星计划第三季python赛道第一名&#x1f3c5; 阿里云ACE认证高级工程师&#x1f3c5; ✒️个人主页&#xff1a;小鹏linux &#x1f48a;个人社区&#xff1a;小鹏linux&#xff08;个人社区&#xff09;欢…

利用vue+高德地图API 实现用户的运动轨迹

利用vue高德地图API 实现用户的运动轨迹 高德地图网址&#xff1a;https://lbs.amap.com/api/jsapi-v2/guide/abc/prepare 任务一&#xff1a;实现地图显示 先完成准备工作&#xff0c;这一步是后面工作的基础。准备工作部分参考了&#xff1a; https://blog.csdn.net/qq_5…

vue3中vite的@路径别名与path中的resolve

使用路径引用 在vue3中&#xff0c;想用符号代替./…/这种相对路径引用使用&#xff0c; 前者相当于从根目录往后找&#xff0c;后者相当于从后往前找。 具体方法就是在vite.config.js中 import { resolve } from "path"export default defineConfig({plugins: [v…

Vue动态组件

等疫情结束了&#xff0c;要开始爬爬山、看看海&#xff0c;做些不会后悔的事情 一、概念 1. 示例 组件是可复用的 Vue 实例&#xff0c;且带有一个名字&#xff0c;这里实现一个最简单的组件&#xff1a; 父组件&#xff1a; <template><div><h1>Father…

【让CSDN的浪漫弥漫女神节】_Unity基础不动山不摇_回顾篇

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

promise 以及经典面试题

1.Promise 它是一个ES6提出一个新语法&#xff0c;用来优化异步代码的写法。promise&#xff1a;承诺 ● 生活中&#xff0c;它是用来表述 对将来要发生的事情的肯定。 例如 &#xff1a; 高中生说&#xff0c;老师&#xff0c;我会考上一所好大学的&#xff1b;销售员说&…

刷题日常计~JS④

作者 : SYFStrive 博客首页 : 点击跳转HomePage &#x1f4dc;&#xff1a; 初编程JavaScript之每天10&#x1f5e1;5题 &#x1f449; 从质变到量变&#x1f4aa; &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区…

Ajax 前后端数据交互

ajax 数据交互 今天又是奋斗的一天&#xff0c;行吧&#xff0c;来学习ajax ajax 数据交互什么是ajax&#xff1f;ajax的优势ajax的使用创建一个ajax对象配置这个对象发送请求接受返回过来的数据ajax状态码readystatechangeresponseTextajax请求方式封装一个属于自己的ajax什么…

2022年最新最详细在IDEA中配置Tomcat(含有详细图解过程)、建立使用IEDA建立一个Web项目的案例

1、首先已经成功安装过tomcat 如果没有成功安装&#xff0c;参考这篇tomcat安装教程(安装成功可忽略)&#xff1a;https://blog.csdn.net/weixin_43304253/article/details/117001797 2、在IDEA中配置tomcat的详细步骤 2.1、run ->Edit Confifurations 2.2 、点击加号 2.…

微信小程序自定义导航栏,实现不同用户角色登陆后显示不同的tabbar(避坑版)

在我们开发小程序的过程中&#xff0c;会遇到权限登录问题&#xff0c;不同的角色登录后显示的底部导航栏tabbar是不一样的。网上看到了很多的博客&#xff0c;多多少少会有些坑&#xff0c;会遇到问题。今天这篇博客就可以一次性解决。 了解概念 自定义tabbar 使用方法 app…

React修改Antd组件样式的方法

1.修改默认组件样式和写自己组件样式的区别 当我们写自己的样式时&#xff0c;在组件页面中定义class名称&#xff0c;再在less文件中对这个class定义样式。 //index.js import React,{useState} from react; import styles from ./index.less;const Index (props) >{ret…

36.一文讲透JavaScript日期对象Date,时间戳、1970、date方法、date计算

文章目录JavaScript日期和时间处理方法Date对象的创建new Date()new Date(milliseconds)1970年之前的时间&#xff1f;new Date(date_str)new Date(year, month, date, hours, minutes, sec, ms)Date对象的方法获取日期内容设置日期内容日期的自动校准日期转为数字、日期差值Da…

Node.js安装及环境配置之Windows篇

Node.js安装及环境配置之Windows篇Node.js安装及环境配置之Windows篇一、安装环境二、安装node.js步骤三、前期准备四、开始安装五、环境配置Node.js安装及环境配置之Windows篇 一、安装环境 1、本机系统&#xff1a;Windows 10&#xff08;64位&#xff09; 2、Node.js&…

纯js判断文件流格式类型:pdf,doc,docx,xls,xlsx,ppt,pptx一次搞定!

目录使用js判断文件类型的场景方法特点输入输出方法步骤1. 查看每种格式文件的16进制码&#xff0c;提取不同文件类型的“特征数”。2. 先判断大类型&#xff0c;在具体大类下判断小类型项目地址&#xff1a;纯前端基于react实现的多类型文件预览&#xff1a;通过arraybuffer判…

uniapp全局组件全局使用(不在每个页面template使用,仅支持H5),函数式调用全局组件方法

最简单的使用&#xff0c;在 main.js 编写如下代码&#xff0c;即可将 xxx 组件在每个页面显示 // main.js// 引入组件 import xxx from "/components/xxx.vue";// 将该组件挂载在document.body下 document.body.appendChild(new xxx().$mount().$el); 函数式调用全…