vue3设置左侧菜单和头部

文章描述了在Vue项目中创建文件,配置路由,实现登录验证,并详细介绍了Aside、Header和Main组件的使用,以及el-组件如el-container、el-aside等的布局结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

创建文件

引入layou/index.vue

添加按钮

layout/index.vue

layout/Aside/index.vue

layout/Header/index.vue

layout/Main/index.vue

src/views/Home/index.vue


未完善,有待改进

页面展示

创建文件

在src/layout包下,创建Aside、Header、Main文件夹和index.vue文件

引入layou/index.vue

在router包下index.vue 文件中引入layou/index.vue

import Home from '../layout/index.vue'


// 配置首页路由
  {
    path: '/home', // 添加register路由规则
    name: 'home',
    component: Home
  },

添加按钮

在Login页面中,进行设置,进行验证后再跳转。

<el-form-item>
                <!-- 按钮 -->
                <!-- <el-button style="width: 100%;" type="primary" >登陆</el-button> -->
                <el-button style="width: 100%;" type="primary" @click="handleLogin">登陆</el-button>
            </el-form-item>




<script lang="ts" setup>

// 处理登录按钮点击事件
    const handleLogin = () => {
    if (loginForm.value.account === 'admin' && loginForm.value.password === 'admin') {
        // 登录成功
        
        router.push('/home');
    } else {
        console.log('账号或密码错误,请重新输入');
        console.log('account:' + loginForm.value.account);
        console.log('password:' + loginForm.value.password);
        // 刷新页面
        // window.location.reload();
    }
};

</script>

layout/index.vue

主文件,在这里调用Aside、Header、Main.

<template>
  <div class="common-layout">
  <el-container class="zhongtiframe">
    <el-aside class="aside" :style="{ height: height + 'px',minHeight: minHeight + 'px' }">
      <Aside/>
    </el-aside>
    <el-container>
      <el-header>
          <Header/>
      </el-header>
      <el-main>
          <Main/>
      </el-main>
    </el-container>
  </el-container>
</div>
</template>

<script setup>
  // 导入左侧导航组件
  import Aside from './Aside/index.vue'
  import Header from './Header/index.vue'
  import Main from './Main/index.vue'
  import { ref,onMounted } from 'vue';
  const height = ref(0)
  const minHeight = ref(0)

  onMounted(() => {
      getHeight();
      // 监听页面缩放事件
      minHeight.value = document.documentElement.clientHeight;
      window.addEventListener('resize',getHeight)
  })
  // 获取文档高度
  function getHeight() {
      height.value = document.documentElement.clientHeight ;
  }
</script>

<style lang="scss" scoped>

// 设置Aside部分页面的颜色
.aside {
  background-color: #9dc8fb;
}
.el-header {
    --el-header-padding: 1 20px;
    --el-header-height: 60px;
    box-sizing: border-box;
    flex-shrink: 0;
    height: var(--el-header-height);
    padding: var(--el-header-padding);
}

</style>

layout/Aside/index.vue

<template>
  <div class="Aside_title">
    海洋笔记
  </div>

    <el-radio-group v-model="isCollapse"  >

    <svg class="icon"  v-if="isCollapse" @click="toggleCollapse" >
    <use xlink:href="#icon-Shankar" />
  </svg>
  <svg class="icon"  v-else @click="toggleCollapse" >
    <use xlink:href="#icon-xiangzuo1" />
  </svg>
    
    </el-radio-group>
    <hr class="horizontal-line">
    
    <!-- default-active="2" 表示默认激活的是下拉菜单中的第三个菜单项,因为菜单项的索引是从 0 开始计数的。 -->
    <el-menu
      default-active="1"
      class="el-menu-vertical-demo"
      :collapse="isCollapse"
      @open="handleOpen"
      @close="handleClose"
    >
      <el-sub-menu index="1">
        <template #title >
          <!-- 设置自定义图标 -->
          <svg class="icon1" >
            <use xlink:href="#icon-biji" />
          </svg>
          <span class="icon-wenzi">笔记管理</span>
        </template>
        <el-menu-item-group>
          <el-menu-item index="1-1">笔记列表</el-menu-item>
          <el-menu-item index="1-2">item two</el-menu-item>
        </el-menu-item-group>
      </el-sub-menu>

      <el-sub-menu index="2">
        <template #title >
          <!-- 设置自定义图标 -->
          <svg class="icon1" >
            <use xlink:href="#icon-shoucang" />
          </svg>
          <span class="icon-wenzi">我的收藏</span>
        </template>
        <el-menu-item-group>
          <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-sub-menu>
      
      <el-sub-menu index="3">
        <template #title >
          <!-- 设置自定义图标 -->
          <svg class="icon1" >
            <use xlink:href="#icon-fenxiang" />
          </svg>
          <span class="icon-wenzi">分享与协作</span>
        </template>
        <el-menu-item-group>
          <el-menu-item index="1-1">分享管理</el-menu-item>
          <el-menu-item index="1-2">协作管理</el-menu-item>
        </el-menu-item-group>
      </el-sub-menu>

      <el-sub-menu index="4">
        <template #title >
          <!-- 设置自定义图标 -->
          <svg class="icon1" >
            <use xlink:href="#icon-fenlei" />
          </svg>
          <span class="icon-wenzi">分类与标签管理</span>
        </template>
        <el-menu-item-group>
          <el-menu-item index="1-1">分类管理</el-menu-item>
          <el-menu-item index="1-2">标签管理</el-menu-item>
        </el-menu-item-group>
      </el-sub-menu>

      <el-menu-item index="5">
        <svg class="icon1" >
            <use xlink:href="#icon-huishouzhan" />
          </svg>
        <template #title >
          <!-- 设置自定义图标 -->
          
          <span class="icon-wenzi">回收站</span>
        </template>
        
      </el-menu-item>

      <el-menu-item index="6" disabled>
        <svg class="icon1" >
            <use xlink:href="#icon-daikaifa" />
          </svg>
        <template #title >
          <!-- 设置自定义图标 -->
          
          <span class="icon-wenzi">待开发</span>
        </template>
        
      </el-menu-item>
      
    </el-menu>

    
  </template>
  
  <script lang="ts" setup>
  import { ref } from 'vue'
  
  const isCollapse = ref(true)
  const handleOpen = (key: string, keyPath: string[]) => {
    console.log(key, keyPath)
  }
  const handleClose = (key: string, keyPath: string[]) => {
    console.log(key, keyPath)
  }
  const toggleCollapse = () => {
  isCollapse.value = !isCollapse.value
}

  </script>
  
  <style>

  .el-menu-vertical-demo:not(.el-menu--collapse) {
    width: 34vh;
    min-height: 394px;
    background-color: #9dc8fb;
    
  }
  .el-menu {
    box-sizing: border-box;
    list-style: none;
    background-color: #9dc8fb;
    border: 0;  /**设置边框为0 */
    
    position: relative;
}
.el-aside {
    box-sizing: border-box;
    flex-shrink: 0;
    overflow: auto;
    width: var(--el-aside-width,214px);
}
/* 设置海洋笔记 */
  .Aside_title{
    font-size: 40px;
    height: 100px; /* 设置容器的高度 */
    line-height: 100px; /* 设置行高等于容器高度 */
    text-align: center; /* 水平居中 */
    color: white;
  }


  /* 对展开和缩小图标进行设置 */
.icon{
  height: 20px;
  width: 20px;
  fill: #ffffff; /* 设置图标颜色为白色 */
  cursor: pointer; /* 当鼠标移动到图标上时显示小手样式 */
}
.icon1{
  height: 20px;
  width: 20px;
  text-align: left;
  /* margin-right: 10px; */
}
.icon-wenzi {
    vertical-align: bottom;
    margin-left: 10px;
}


/* 对横线的设置 */
.horizontal-line {
  border-top: 1px solid rgb(240, 232, 232); /* 设置颜色和宽度 */
  margin: 0 0; /* 设置上下边距 */
}


.el-sub-menu__title{
    padding: 0px;
    display: flex;
    justify-content: center;
}

.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item, .el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item-group__title, .el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title {
    /* padding-left: calc(var(--el-menu-base-level-padding) + var(--el-menu-level)*var(--el-menu-level-padding)); */
    white-space: nowrap;
    /* text-align: left; */
    float: left;
    margin-left: 10px;
}


  </style>
  

layout/Header/index.vue

<template>
  <div class="header_container">
    <!-- 面包屑 -->
    <div  class="header_left">
      面包屑
    </div>

    <!-- 头像和用户名 -->
    <div class="header_right">
      <div class="header_avatar">
      <el-avatar
        src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
      />
      </div>
      <!-- 用户名 -->
      <div >
        <!-- 下拉菜单 -->
      <el-dropdown @command="handleCommand" class="header_headPortrait">
      <span class="el-dropdown-link">
        admin<el-icon class="el-icon--right"><arrow-down /></el-icon>
      </span>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item command="a">个人信息</el-dropdown-item>
            <el-dropdown-item command="b">退出</el-dropdown-item>
            <el-dropdown-item command="c">Action 3</el-dropdown-item>
            <el-dropdown-item command="d" disabled>Action 4</el-dropdown-item>
            <el-dropdown-item command="e" divided>Action 5</el-dropdown-item>
          </el-dropdown-menu>
        </template>
    </el-dropdown>
      </div>
        

    
  </div>
</div>
<hr/>
  </template>
  
  <script lang="ts" setup>

import { ElMessage } from 'element-plus'
import { ArrowDown } from '@element-plus/icons-vue'

const handleCommand = (command: string | number | object) => {
  ElMessage(`click on item ${command}`)
}
  

  </script>
  
  <style  lang="scss" scoped>

.header_headPortrait{
  display: flex;
  justify-content: center; /* 水平居中 */
  align-items: center; /* 垂直居中 */
  
}
.example-showcase .el-dropdown-link {
  cursor: pointer;
  color: var(--el-color-primary);
  display: flex;
  align-items: center;
}

.header_container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-sizing: border-box;
    height: 100%;
.header_right {
        display: flex;
        justify-content: space-between;
        align-items: center;
        box-sizing: border-box;
        .header_avatar {
            cursor: pointer;
            margin-right: 12px;
            /* .avatar_img {
                width: 30px;
                height: 30px;
            } */
        }
        .el-dropdown-link {
            cursor: pointer;
            display: flex;
            align-items: center;
            border: none;
            outline: none; 
        }
    }
}
  
  
  </style>
  

layout/Main/index.vue

<template>
  <el-tabs
    type="card"
    closable
    class="demo-tabs"
  >
    <Hello/>
    
  </el-tabs>
  
</template>

<script setup>
import Hello from '@/views/Home/index.vue'
    
</script>

<style lang="scss" scoped>

</style>

src/views/Home/index.vue

<template>
    <div>
            这是我的首页
    </div>
</template>

<script setup>

</script>

<style lang="scss" scoped>

</style>

### 实现 Vue3 中 Element Plus 左侧菜单折叠效果 为了实现在 Vue3 项目中使用 Element Plus 组件库创建可折叠的左侧菜单,需遵循特定的设计模式技术要点。 #### 创建基础布局 首先,在应用中设置基本的页面框架,该框架应包含头部、主体以及侧边栏部分。通过 `el-container` 其他容器组件来定义这些区域[^2]: ```html <template> <el-container class="home-container"> <!-- 头部 --> <el-header>Header</el-header> <!-- 主体 --> <el-container> <!-- 侧边栏 --> <el-aside width="auto">Aside</el-aside> <!-- 右侧主要内容区 --> <el-main>Main Content Area</el-main> </el-container> </el-container> </template> ``` #### 添加响应式菜单逻辑 为了让菜单具备展开/收缩的功能,可以利用 Vue 的双向绑定特性自定义事件处理程序。这里的关键在于维护一个布尔类型的变量用于控制菜单宽度的变化,并将其与按钮或其他触发器关联起来以便切换状态[^1]。 ```javascript <script setup lang="ts"> import { ref } from &#39;vue&#39;; const isCollapse = ref(false); function toggleSideBar() { isCollapse.value = !isCollapse.value; } </script> ``` 接着修改 HTML 结构中的 `<el-aside>` 部分以适应新的属性: ```html <!-- 修改后的侧边栏 --> <el-aside :width="isCollapse ? &#39;64px&#39; : &#39;200px&#39;" @click="toggleSideBar()"> <el-menu router :collapse="isCollapse" default-active="/dashboard"> <!-- 菜单... --> </el-menu> </el-aside> ``` 上述代码片段展示了如何动态调整侧边栏宽度并监听点击事件从而改变其显示形态。值得注意的是,`:collapse` 属性决定了菜单项文字是否隐藏;而 `default-active` 则指定了默认激活路径。 #### 解决性能问题 针对可能出现的动画延迟或卡顿情况(如引用所提到),建议优化资源加载方式,特别是对于第三方字体图标文件。可以通过按需加载的方式减少不必要的网络请求次数,提高用户体验质量[^3]。 此外,还可以考虑采用 CSS 动画代替 JavaScript 来完成过渡效果,因为浏览器通常能更高效地渲染前者。确保所有样式表都经过压缩并且只包含了必要的规则集也能有效降低复杂度。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值