vue后台管理系统从0到1(5)

news2024/10/12 8:08:03

文章目录

  • vue后台管理系统从0到1(5)
    • 完善侧边栏
    • 修改bug
    • 渲染header导航栏

vue后台管理系统从0到1(5)

在这里插入图片描述
接上一期,我们需要完善我们的侧边狼

完善侧边栏

我们在 element 组件中可以看见,这一个侧边栏是符合我们的要求的
在这里插入图片描述
我们就使用这样一个侧边栏动态渲染我们的各个选项,但是目前没有接入后端接口,我们需要自己先定义静态侧边栏数据,然后在使用v-for动态渲染上去

在这里插入图片描述
这是我写好的侧边栏动态v-for渲染代码
在这里插入图片描述

这里是渲染数据和渲染方法

在这里插入图片描述

这里是加上的样式

以上代码,不懂的自己查gpt或者查一些ai

CommonAside.vue 完整代码

<template>
  <el-aside width="200px">
    <el-menu @select="handleMenuSelect" background-color="#545c64" text-color="#fff">
      <h3>通用后台管理系统</h3>
      <el-menu-item
          v-for="item in noChildren"
          :index="item.path"
          :key="item.path"
      >
        <i :class="item.icon"></i>
        <span>{{ item.label }}</span>
      </el-menu-item>

      <el-sub-menu
          v-for="item in hasChildren"
          :index="item.path"
          :key="item.path"
      >
        <template #title>
          <i :class="item.icon"></i>
          <span>{{ item.label }}</span>
        </template>
        <el-menu-item
            v-for="subItem in item.children"
            :index="subItem.path"
            :key="subItem.path"
        >
          <i :class="subItem.icon"></i>
          <span>{{ subItem.label }}</span>
        </el-menu-item>
      </el-sub-menu>
    </el-menu>
  </el-aside>
</template>

<script setup>
import { ref, computed } from 'vue';
import { useRouter } from 'vue-router';

const router = useRouter();
const list = ref([
  { path: '/home', name: 'home', label: '首页', icon: 'el-icon-house', url: 'Home' },
  { path: '/mall', name: 'mall', label: '商品管理', icon: 'el-icon-video-play', url: 'Mall' },
  { path: '/user', name: 'user', label: '用户管理', icon: 'el-icon-user', url: 'User' },
  {
    path: '/other', label: '其他', icon: 'el-icon-location',
    children: [
      { path: '/page1', name: 'page1', label: '页面1', icon: 'el-icon-setting', url: 'Page1' },
      { path: '/page2', name: 'page2', label: '页2', icon: 'el-icon-setting', url: 'Page2' }
    ]
  }
]);

const noChildren = computed(() => list.value.filter(item => !item.children));
const hasChildren = computed(() => list.value.filter(item => item.children));

const handleMenuSelect = (index) => {
  const item = list.value.find(item => item.path === index) ||
      list.value.flat().find(item => item.path === index);
  if (item) {
    router.push(item.path);
  }
};
</script>

<style lang="less" scoped>
.icons {
  width: 18px;
  height: 18px;
  margin-right: 5px;
}

.el-menu{
  border-right: none;
  h3{
    line-height: 48px;
    color: #fff;
    text-align: center;
  }
}

.el-aside{
  height: 10000px;
  background-color: #545c64;
}

</style>

为了防止出错,重构 Main.vue 代码如下,不懂的gpt,我认为重要的是整个项目完成的流程
在这里插入图片描述

<script setup>
// 可以在这里添加组件的逻辑
import CommonAside from '@/components/CommonAside.vue'
</script>

<template>
  <div class="common-layout">
    <el-container>
      <el-aside width="200px"  class="aside-container">
        <!-- 侧边栏内容 -->
        <common-aside></common-aside>
      </el-aside>
      <el-container>
        <el-header class="el-header">
          <common-header></common-header>
        </el-header>
        <el-main class="right-main">
          main
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<style>

.common-layout{
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
el-container{
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
.el-header{
  background-color: #333;
}
</style>

然后就是重新跑项目:
在这里插入图片描述
如果对于以上代码有问题可以私信我,我们的侧边栏就渲染完成了,这里有一个bug,就是我们的 icon 没有加载出来,我还没有发现问题在哪,如果你们发现了,可以私信我。
紧接着上文,我们的项目目前仍然存在侧边栏 icon 加载问题,我今天好好的看了一下代码,发现展示 icon 的地方代码出了问题

修改bug

在这里插入图片描述
这是我修改过的代码

我原本写的展示 icon 使用 标签,并且把 icon 的渲染写成了 class 属性里

重构 commonAside.vue 如下:

<template>
  <el-aside width="200px">
    <el-menu @select="handleMenuSelect" background-color="#545c64" text-color="#fff">
      <h3>通用后台管理系统</h3>
      <el-menu-item
          v-for="item in noChildren"
          :index="item.path"
          :key="item.path"
      >
        <component class="icons" :is="item.icon"></component>
        <span>{{ item.label }}</span>
      </el-menu-item>

      <el-sub-menu
          v-for="item in hasChildren"
          :index="item.path"
          :key="item.path"
      >
        <template #title>
          <component class="icons" :is="item.icon"></component>
          <span>{{ item.label }}</span>
        </template>
        <el-menu-item
            v-for="subItem in item.children"
            :index="subItem.path"
            :key="subItem.path"
        >
          <component class="icons" :is="subItem.icon"></component>
          <span>{{ subItem.label }}</span>
        </el-menu-item>
      </el-sub-menu>
    </el-menu>
  </el-aside>
</template>

<script setup>
import { ref, computed } from 'vue';
import { useRouter } from 'vue-router';

const router = useRouter();
const list = ref([
  { path: '/home', name: 'home', label: '首页', icon: 'house', url: 'Home' },
  { path: '/mall', name: 'mall', label: '商品管理', icon: 'video-play', url: 'Mall' },
  { path: '/user', name: 'user', label: '用户管理', icon: 'user', url: 'User' },
  {
    path: '/other', label: '其他', icon: 'location',
    children: [
      { path: '/page1', name: 'page1', label: '页面1', icon: 'setting', url: 'Page1' },
      { path: '/page2', name: 'page2', label: '页2', icon: 'setting', url: 'Page2' }
    ]
  }
]);

const noChildren = computed(() => list.value.filter(item => !item.children));
const hasChildren = computed(() => list.value.filter(item => item.children));

const handleMenuSelect = (index) => {
  const item = list.value.find(item => item.path === index) ||
      list.value.flat().find(item => item.path === index);
  if (item) {
    router.push(item.path);
  }
};
</script>

<style lang="less" scoped>
.icons {
  width: 18px;
  height: 18px;
  margin-right: 5px;
}

.el-menu{
  border-right: none;
  h3{
    line-height: 48px;
    color: #fff;
    text-align: center;
  }
}

.el-aside{
  height: 10000px;
  background-color: #545c64;
}

</style>

渲染header导航栏

然后我们接着渲染我们的 header 导航栏部分,目标是渲染成这样
在这里插入图片描述
那么第一步分析界面布局

可以得出以下两个部分,也是我们需要分开写的两个部件

首先,使用一个 header 把整体包起来

  <div class="header">
    
    
  </div>

然后我们把导航栏分成左右两部分,左边有图标和首页字体,右边是用户头像

  <div class="header">
    <div class="l-content">
    
    </div>

    <div class="r-content">
      
    </div>
    
  </div>

然后我们具体实现左右两边的东西

  <div class="header">
    <div class="l-content">
    	//图标
      <el-button size="small">
        <component class="icons" is="menu"></component>
      </el-button>
		//面包屑字体
      <el-breadcrumb separator="/" class="bread">
        <el-breadcrumb-item :to="{path:'/'}">首页</el-breadcrumb-item>
      </el-breadcrumb>
      
    </div>

    <div class="r-content">
    //用户头像
     <el-dropdown>
    <span class="el-dropdown-link">
      <img :src="getImageUrl(user)" class="user"/>
    </span>
        <template #dropdown>
        //单击头像退出按钮
          <el-dropdown-menu>
            <el-dropdown-item>个人中心</el-dropdown-item>
            <el-dropdown-item>退出</el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
      
    </div>
  </div>

然后我们加入样式

<style lang="less" scoped>
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  height: 100%;
  background-color: #333;

}

.icons {
  width: 20px;
  height: 20px;
}

.l-content {
    display: flex;
    align-items: center;
    .el-button{
      margin-right: 20px;
    }
  }


.r-content  {
  .user{
    width: 40px;
    height: 40px;
    border-radius: 50%;
  }
}

/* 注意::deep() 是一个 Vue.js 中的作用域穿透伪元素,用于在 scoped CSS 中访问子组件的样式。
   但它不是标准的 CSS 语法,且在新版本的 Vue.js 中可能已经被废弃或替换。
   如果这段代码是在 Vue.js 项目中使用的,请确保你的项目支持这种语法。
   此外,由于选择器中包含特殊字符(如点号和括号),你可能需要对其进行适当的转义或使用其他方法来实现相同的效果。
   但在这里,为了保持原始信息的完整性,我保留了这段代码的原样。 */
:deep(.bread span) {
  color: #fff !important;
  cursor: pointer !important;
}

</style>

再加入渲染数据的代码

<script setup>
import {ref, computed} from 'vue';
import {useRouter} from 'vue-router';

const router = useRouter();
const list = ref([
  {path: '/home', name: 'home', label: '首页', icon: 'el-icon-house', url: 'Home'},
  {path: '/mall', name: 'mall', label: '商品管理', icon: 'el-icon-video-play', url: 'Mall'},
  {path: '/user', name: 'user', label: '用户管理', icon: 'el-icon-user', url: 'User'},
  {
    path: '/other', label: '其他', icon: 'el-icon-location',
    children: [
      {path: '/page1', name: 'page1', label: '页面1', icon: 'el-icon-setting', url: 'Page1'},
      {path: '/page2', name: 'page2', label: '页2', icon: 'el-icon-setting', url: 'Page2'}
    ]
  }
]);

const getImageUrl = (user) => {
  return new URL(`../assets/images/${user}.png`, import.meta.url).href;
};
</script>

最后整合代码:
CommonHeader.vue代码:

<template>
  <div class="header">
    <div class="l-content">
      <el-button size="small">
        <component class="icons" is="menu"></component>
      </el-button>

      <el-breadcrumb separator="/" class="bread">
        <el-breadcrumb-item :to="{path:'/'}">首页</el-breadcrumb-item>
      </el-breadcrumb>
    </div>

    <div class="r-content">
      <el-dropdown>
    <span class="el-dropdown-link">
      <img :src="getImageUrl(user)" class="user"/>
    </span>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item>个人中心</el-dropdown-item>
            <el-dropdown-item>退出</el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </div>
  </div>


</template>

<script setup>
import {ref, computed} from 'vue';
import {useRouter} from 'vue-router';

const router = useRouter();
const list = ref([
  {path: '/home', name: 'home', label: '首页', icon: 'el-icon-house', url: 'Home'},
  {path: '/mall', name: 'mall', label: '商品管理', icon: 'el-icon-video-play', url: 'Mall'},
  {path: '/user', name: 'user', label: '用户管理', icon: 'el-icon-user', url: 'User'},
  {
    path: '/other', label: '其他', icon: 'el-icon-location',
    children: [
      {path: '/page1', name: 'page1', label: '页面1', icon: 'el-icon-setting', url: 'Page1'},
      {path: '/page2', name: 'page2', label: '页2', icon: 'el-icon-setting', url: 'Page2'}
    ]
  }
]);

const getImageUrl = (user) => {
  return new URL(`../assets/images/${user}.png`, import.meta.url).href;
};
</script>

<style lang="less" scoped>
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  height: 100%;
  background-color: #333;

}

.icons {
  width: 20px;
  height: 20px;
}

.l-content {
    display: flex;
    align-items: center;
    .el-button{
      margin-right: 20px;
    }
  }


.r-content  {
  .user{
    width: 40px;
    height: 40px;
    border-radius: 50%;
  }
}

/* 注意::deep() 是一个 Vue.js 中的作用域穿透伪元素,用于在 scoped CSS 中访问子组件的样式。
   但它不是标准的 CSS 语法,且在新版本的 Vue.js 中可能已经被废弃或替换。
   如果这段代码是在 Vue.js 项目中使用的,请确保你的项目支持这种语法。
   此外,由于选择器中包含特殊字符(如点号和括号),你可能需要对其进行适当的转义或使用其他方法来实现相同的效果。
   但在这里,为了保持原始信息的完整性,我保留了这段代码的原样。 */
:deep(.bread span) {
  color: #fff !important;
  cursor: pointer !important;
}

</style>

然后,我们启动项目,查看如下:
在这里插入图片描述
这样一个新的组件就被我们写好了。

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

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

相关文章

I/O进程(Day26)

一、学习内容 I/O进程 标准IO 概念 针对文件的读写操作 文件IO最终达成的目的&#xff1a;将一个临时存在于内存中的数据&#xff0c;永久性的存放于磁盘当中 操作 文件IO的操作&#xff0c;需要这样的2个指针 一个指针&#xff1a;指向源数据&#xff0c;提供读取操作的指针 …

复杂系统学习

一、复杂网络分析在复杂性研究中的地位 1.复杂系统 系统中存在的复杂度从两个维度来看 ①系统自由度&#xff08;系统组成成分的数目&#xff09; ②相互作用&#xff08;线性到非线性的转换&#xff09; 复杂网络是复杂系统的骨架 复杂系统可以抽象成一个网络&#xff0…

大数据新视界 --大数据大厂之 Dremio:改变大数据查询方式的创新引擎

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

【JVM】如何判断对象是否可以被回收

引用计数法&#xff1a; 在对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时&#xff0c;计数器值就加一&#xff1b;当引用失效时&#xff0c;计数器值就减一&#xff1b;任何时刻计数器为零的对象就是不可能再被使用的。 优点&#xff1a;实现简单&#xff0c;判…

Visual Studio--VS安装配置使用教程

Visual Studio Visual Studio 是一款功能强大的开发人员工具&#xff0c;可用于在一个位置完成整个开发周期。 它是一种全面的集成开发环境 (IDE)。对新手特别友好&#xff0c;使用方便&#xff0c;不需要复杂的去配置环境。用它学习很方便。 Studio安装教程 Visual Studio官…

从这里看BD仓储如何改变物流效率?

BD仓储物流建设成为当代物流领域的核心要素&#xff0c;推动着整个行业朝向高效性与智能化水平不断提升。在BD仓储物流的创新浪潮中&#xff0c;RFID技术犹如一颗耀眼的明珠&#xff0c;凭借其无可比拟的特性获得了业界的广泛推崇与广泛应用。该技术通过无线信号与电子标签的互…

Python剪辑视频

import os from moviepy.editor import VideoFileClipvideo_dir r"E:\学习\视频剪辑" s_video_file "1.mp4" d_video_file "剪辑片段1.mp4" s_video_path os.path.join(video_dir, s_video_file) # 原视频文件路径 d_video_path os.path…

FDTD Solutions(时域有限差分)仿真技术与应用

FDTD Solutions是一款非常好用的微纳光学设计工具。该软件提供了丰富的设计功能&#xff0c;支持CMOS图像传感器&#xff0c;OLED和液晶&#xff0c;表面计量&#xff0c;表面等离子体&#xff0c;石墨烯&#xff0c;太阳能电池&#xff0c;集成光子组件&#xff0c;超材料&…

排序|归并排序|递归|非递归|计数排序(C)

归并排序 如果数组的左半区间有序&#xff0c;右半区间有序&#xff0c;可以直接进行归并 基本思想 快排是一种前序&#xff0c;归并是后序 每次取小尾插 void _MergeSort(int* a, int* tmp, int begin, int end) {if (end < begin)return;int mid (end begin) / 2;/…

go开发环境设置-安装与交叉编译

1. 引言 Go语言&#xff0c;又称Golang&#xff0c;是Google开发的一门编程语言&#xff0c;以其高效、简洁和并发编程的优势受到广泛欢迎。作为一门静态类型、编译型语言&#xff0c;Go在构建网络服务器、微服务和命令行工具方面表现突出。 在开发过程中&#xff0c;开发者常…

PyCharm打开及配置现有工程(详细图解)

本文详细介绍了如何利用Pycharm打开一个现有的工程&#xff0c;其中包括编译器的配置。 PyCharm打开及配置现有工程 1、打开工程2、配置编译器 1、打开工程 双击PyCharm软件&#xff0c;点击左上角 文件 >> 打开(O)… 选中想要打开的项目之后点击“确定” 2、配置编译器…

STM32学习--3-5 光敏控制传感器控制蜂鸣器

接线图 Buzzer.c #include "stm32f10x.h" // Device header void Buzzer_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode GPIO_Mode_O…

Microsoft Visual Studio安装gtest

1. 参考【Windows Visual Studio下安装和使用google test&#xff08;gtest&#xff09;】 https://blog.csdn.net/Bule_Zst/article/details/78420894 2. 编译gtest使用Win32模式。 3. 配置属性&#xff0c;C/C&#xff0c;常规&#xff0c;附加包含目录 …

【画质模组】古墓丽影mod,调色并修改光影,游戏画质大提升

大家好&#xff0c;今天小编我给大家继续引入一款游戏mod&#xff0c;这次这个模组主要是针对雷神之锤4进行修改&#xff0c;如果你觉得游戏本身光影有缺陷&#xff0c;觉得游戏色彩有点失真的话&#xff0c;或者说你想让雷神之锤4这款游戏增加对光线追踪的支持的话&#xff0c…

Java | Leetcode Java题解之第474题一和零

题目&#xff1a; 题解&#xff1a; class Solution {public int findMaxForm(String[] strs, int m, int n) {int[][] dp new int[m 1][n 1];int length strs.length;for (int i 0; i < length; i) {int[] zerosOnes getZerosOnes(strs[i]);int zeros zerosOnes[0]…

【红外传感器】STM32C8T6标准库使用红外对管

好好学习&#xff0c;天天向上 前言一、了解红外二、标准库的代码1.infrared.c2.infrared.h3.main.c4 现象 总结 前言 红外线&#xff1a;频率介于微波与可见光之间的电磁波。 参考如下 【STM32】标准库与HAL库对照学习教程外设篇–红外避障传感器 光电红外传感器详解&#…

查看 Excel 应用程序中已打开的 Excel 文件的完整路径

要查看 Excel 应用程序中已打开的 Excel 文件的完整路径&#xff08;全路径&#xff09;&#xff0c;你可以通过以下几种方法获取具体路径&#xff0c;尤其是在 VSTO 应用程序中。 方法1&#xff1a;使用 VSTO Excel 外接程序代码 在 VSTO 外接程序代码中&#xff0c;您可以直接…

前端反馈弹框组件封装

一、需求背景 需要针对某个功能进行用户调查反馈&#xff0c;设计一个弹框&#xff0c;进行后端入表记录&#xff0c;以便后期进行数据分析。 二、实现UI 三、代码留存 以vue为例 <template><div class"advice-container"><van-dialogv-model"…

聚类分析 | WOA-K-means++聚类优化算法

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 (创新)WOA-K-means聚类优化算法 (WOA聚类优化&#xff0c;创新&#xff0c;独家) 鲸鱼算法优化K-means聚类优化算法 matlab语言&#xff0c;一键出图&#xff0c;直接运行 1.鲸鱼算法WOA作为群智能算法简单高效&a…

Collection-LinkedList源码解析

文章目录 概述LinkedList实现底层数据结构构造函数getFirst(), getLast()removeFirst(), removeLast(), remove(e), remove(index)add()addAll()clear()Positional Access 方法查找操作 概述 LinkedList同时实现了List接口和Deque接口&#xff0c;也就是说它既可以看作一个顺序…