Vue的可伸缩后台导航菜单

Vue的可伸缩后台导航菜单

文章说明

采用Vue3+iconfont编写了一个简单的可伸缩后台导航菜单的基本框架,在动画方面效果一直加不好,就索性不加动画了;然后主题颜色也并不好调,就直接调了一个简单的颜色,不是很舒服,可以根据自己的想法进行修整。

源码

App.vue

<template>
  <link rel="stylesheet" href="/style/css/nav-collapse.css">
  <link rel="stylesheet" href="/style/css/iconfont.css">
  <link rel="stylesheet" :href="'/style/css/theme-' + data.theme + '.css'">

  <div>
    <div class="nav-container">
      <ul class="nav-list">
        <li v-for="item in data.navList" :key="item.id" @click="changeCurMenu(item)"
            :class="item.navName === data.curMenu ? 'active-nav-item nav-item' : 'nav-item'">
          <i :class="'iconfont ' + item.icon"></i>
          <span :style="{display: data.spanDisplay}">{{ item.navName }}</span>
        </li>
      </ul>
    </div>

    <div class="content-container">
      <div class="header">
        <div class="collapse-button" @click="changeCollapse">
          <i class="iconfont icon-menu-bar"></i>
        </div>
        <div class="cur-menu">
          {{ data.curMenu }}
        </div>

        <div class="switch-theme">
          <div class="switch-container" @click="changeTheme">
            <div class="switch-button"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {reactive} from "vue";

export default {
  name: "App",
  setup() {
    const data = reactive({
      collapse: true,
      curMenu: "导航1",
      navList: [
        {
          id: 1,
          navName: "导航1",
          icon: "icon-shengdanbingqilin"
        },
        {
          id: 2,
          navName: "导航2",
          icon: "icon-shengdanguaizhang"
        },
        {
          id: 3,
          navName: "导航3",
          icon: "icon-shengdanguo"
        },
        {
          id: 4,
          navName: "导航4",
          icon: "icon-shengdanwancan"
        },
        {
          id: 5,
          navName: "导航5",
          icon: "icon-shengdanliwu"
        },
        {
          id: 6,
          navName: "导航6",
          icon: "icon-shengdanmao"
        },
      ],
      navNormalWidth: "200px",
      navCollapseWidth: "60px",
      spanDisplay: "none",
      theme: "light",
    });

    function changeCollapse() {
      data.collapse = !data.collapse
      const navContainer = document.getElementsByClassName("nav-container")[0];
      const navList = document.getElementsByClassName("nav-list")[0];
      const contentContainer = document.getElementsByClassName("content-container")[0];
      if (data.collapse) {
        navContainer.style.width = data.navCollapseWidth;
        data.spanDisplay = "none";
        navList.style.width = data.navCollapseWidth;
        contentContainer.style.width = "calc(100% - " + data.navCollapseWidth + ")";
        contentContainer.style.left = data.navCollapseWidth;
      } else {
        navContainer.style.width = data.navNormalWidth;
        data.spanDisplay = "inline-block";
        navList.style.width = data.navNormalWidth;
        contentContainer.style.width = "calc(100% - " + data.navNormalWidth + ")";
        contentContainer.style.left = data.navNormalWidth;
      }
    }

    function changeCurMenu(item) {
      data.curMenu = item.navName;
    }

    function changeTheme() {
      const switchButton = document.getElementsByClassName("switch-button")[0];
      if (data.theme === "light") {
        data.theme = "dark";
        switchButton.style.float = "right";
      } else {
        data.theme = "light";
        switchButton.style.float = "left";
      }
    }

    return {
      data,
      changeCollapse,
      changeCurMenu,
      changeTheme
    }
  }
};
</script>

<style>
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
</style>

nav-collapse.css

.nav-container {
    width: 60px;
    height: 100vh;
    position: absolute;
    left: 0;
    top: 0;
    background-color: #000000cc;
    text-align: center;
}

.nav-list {
    list-style: none;
    float: left;
    width: 60px;
}

.nav-item {
    border-bottom: 1px solid #666666;
    color: #ffffff;
    height: 60px;
    line-height: 60px;
    width: 100%;
    font-size: 20px;
}

.nav-item:hover {
    background-color: #000000dd;
    cursor: pointer;
}

.active-nav-item {
    background-color: #000000;
}

.iconfont:before {
    font-size: 20px;
    margin-right: 5px;
    color: #ffffff;
}

.content-container {
    width: calc(100vw - 60px);
    height: 100vh;
    position: absolute;
    left: 60px;
    top: 0;
    background-color: var(--background-color);
    border-color: var(--border-color);
    color: var(--color);
}

.header {
    height: 60px;
    line-height: 60px;
    border-bottom: 1px solid var(--border-color);
    user-select: none;
}

.collapse-button {
    padding-left: 15px;
    height: 60px;
    width: 60px;
    float: left;
    cursor: pointer;
}

.icon-menu-bar:before {
    color: var(--color);
    font-size: 30px;
}

.cur-menu {
    padding-left: 15px;
    height: 60px;
    width: 120px;
    float: left;
    cursor: pointer;
    font-size: 20px;
}

.switch-theme {
    padding-right: 20px;
    height: 60px;
    width: 100px;
    float: right;
    position: relative;
}

.switch-container {
    width: 60px;
    height: 28px;
    position: absolute;
    left: 0;
    top: 16px;
    border-radius: 14px;
    border: 1px solid var(--border-color);
    background-color: var(--switch-background-color);
    cursor: pointer;
}

.switch-button {
    width: 26px;
    height: 26px;
    border-radius: 14px;
    background-color: #fff;
    float: left;
    transition: float 1s linear;
}

theme-light.css

:root {
    --background-color: #fff;
    --color: #303133;
    --border-color: #ebebeb;
    --switch-background-color: #f2f2f2;
}

theme-dark.css

:root {
    --background-color: #141414;
    --color: #E5EAF3;
    --border-color: #ebebeb;
    --switch-background-color: #f2f2f2;
}

效果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值