vue.js 3.2.22:菜单每行依次滑动出现的动画

一,js代码

Menu.vue

<template>
  <div style="width:calc(100vw - 25px);overflow:hidden;height: 100vh;">
    <div id="icon" class="menu_box_open blade_col1" :class="isOpen" style="position:fixed;right:30px;top:30px;" @click="menuDisp">
      <i class="menu_trigger_icon"></i>
    </div>
    <ul id="ul" class="menu_box_list blade_bg1" :class="isShow">
      <li class="menu_box_item" v-for="(item,i) in menuList" :key="i" :style="{'transition-delay': item.delay,}">
        <a :href="'#'+item.link"> {{ item.title }}</a>
      </li>
    </ul>
  </div>
</template>
<script>
import {ref} from "vue"
export default {
  name: "Menu",
  setup() {
    //定义菜单的list
    const menuList = ref([]);
    menuList.value = [
      {title:"公司业绩",link:"aaa",delay:"0.1s"},
      {title:"关键指标",link:"aaa",delay:"0.15s"},
      {title:"盈利能力",link:"aaa",delay:"0.2s"},
      {title:"运营能力",link:"aaa",delay:"0.25s"},

      {title:"偿债能力",link:"aaa",delay:"0.3s"},
      {title:"成长能力",link:"aaa",delay:"0.35s"},
      {title:"资产负债表",link:"aaa",delay:"0.4s"},
      {title:"利润表",link:"aaa",delay:"0.45s"},

      {title:"现金流量表",link:"aaa",delay:"0.5s"},
      {title:"股东情况",link:"aaa",delay:"0.55s"},
      {title:"研发投入",link:"aaa",delay:"0.6s"},
    ];
    //切换样式显示菜单
    const isShow = ref("");
    //切换样式显示Icon
    const isOpen = ref("");
    //响应对icon的点击
    const menuDisp = () => {
      //icon变为打开或关闭
      if (isOpen.value === "") {
        isOpen.value = "is_menu_open";
      } else {
        isOpen.value = "";
      }

       //menu变为显示或隐藏
         if (isShow.value === "") {
           isShow.value = "menu_box_show";
         } else {
           isShow.value = "";
         }
    }
    return {
      menuDisp,
      isShow,
      menuList,
      isOpen,
    }
  }
}
</script>

<style scoped>
/*--------------------------------------icon------------------------------------------------------*/

.menu_box_open {
  background: rgba(196, 49, 58, 0.95);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 60px;
  font-size: 0;
}

.menu_box_open .menu_trigger_icon {
  position: relative;
  height: 1px;
  width: 55px;
  display: inline-block;
  background-color: #fff;
  vertical-align: middle;
  transition: background-color 0.2s cubic-bezier(0.165, 0.84, 0.44, 1);
}

.menu_box_open i {
  color: #fff;
}
.menu_box_open .menu_trigger_icon:before {
  -webkit-transform: translateY(-1px);
  transform: translateY(-1px);
  top: -14px;
}

.menu_box_open .menu_trigger_icon:before{
  position: absolute;
  left: 0;
  height: 1px;
  width: 55px;
  content: "";
  background-color: #fff;
  transition: transform 0.3s cubic-bezier(0.19, 1, 0.22, 1);
}

.menu_box_open .menu_trigger_icon:after {
  -webkit-transform: translateY(1px);
  transform: translateY(1px);
  top: 14px;
}

.menu_box_open .menu_trigger_icon:after {
  position: absolute;
  left: 0;
  height: 1px;
  width: 55px;
  content: "";
  background-color: #fff;
  transition: transform 0.3s cubic-bezier(0.19, 1, 0.22, 1);
}

.menu_box_open.is_menu_open .menu_trigger_icon {
  background-color: rgba(255, 255, 255, 0) !important;
}

.menu_box_open.is_menu_open .menu_trigger_icon:before {
  transform: translateY(14px) rotate(
      45deg);
}

.menu_box_open.is_menu_open .menu_trigger_icon:after {
  transform: translateY(-14px) rotate(
      -45deg);
}

/*--------------------------------------menu------------------------------------------------------*/

.twelve_blade .blade_col1 {
  color: #ede9d5;
}
.menu_box_list {
  margin-top: 20px;
  right: -240px;
  top: 100px;
  width:240px;
  position: fixed;
}
.menu_box_list .menu_box_item a {
  font-size: 26px;
  flex: 1;
  color: #fff;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
ul {
  list-style: none;
}
.menu_box_list .menu_box_item {
  background: rgba(196, 49, 58, 0.95);
  font-size: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 50px;
  border-top: 1px solid rgba(255, 255, 255, 0.3);
  width: 240px;
  text-align: center;
  opacity: 0;
  -webkit-transform: translateX(0);
  transform: translateX(0);
  transition: opacity 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94), -webkit-transform 1s cubic-bezier(0.19, 1, 0.22, 1);
  transition: opacity 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94), transform 1s cubic-bezier(0.19, 1, 0.22, 1);
  transition: opacity 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94), transform 1s cubic-bezier(0.19, 1, 0.22, 1), -webkit-transform 1s cubic-bezier(0.19, 1, 0.22, 1);
}
.menu_box_list.menu_box_show .menu_box_item {
  opacity: 1;
  transform: translateX(-260px);
}
a {
  text-decoration: none;
}
</style>

说明:刘宏缔的架构森林是一个专注架构的博客,

网站:https://blog.imgtouch.com
本文: https://blog.imgtouch.com/index.php/2023/05/28/vue-js-3-2-22-cai-dan-mei-xing-yi-ci-hua-dong-chu-xian-de/

         对应的源码可以访问这里获取: https://github.com/liuhongdi/
         或: https://gitee.com/liuhongdi

说明:作者:刘宏缔 邮箱: 371125307@qq.com

二,测试效果

菜单打开前:

 

 点击后:

三,查看vue版本:

liuhongdi@lhdpc:/data/vue/audio$ npm list vue
audio@0.1.0 /data/vue/audio
├─┬ @vue/cli-plugin-babel@4.5.15
│ └─┬ @vue/babel-preset-app@4.5.15
│   └── vue@3.2.22 deduped
└─┬ vue@3.2.22
  └─┬ @vue/server-renderer@3.2.22
    └── vue@3.2.22 deduped

 

posted @ 2021-11-18 15:18  刘宏缔的架构森林  阅读(245)  评论(0编辑  收藏  举报