我为展开收起功能做了动画,被老板称赞!

简介: 【8月更文挑战第23天】我为展开收起功能做了动画,被老板称赞!

需求简介

这几天接了个新项目,需要实现下图中左侧边栏的菜单切换。这种功能其实就是一个折叠面板,实现方式多种多样。
image.png
实现上面的功能,无非就是一个v-show的事儿,但没有过渡,会显得非常生硬。想添加一些过渡效果,
最简单的就是使用element ui、或者ant的折叠面板组件了。但可惜的是,我们的项目不能使用任何第三方组件库。
为了做好产品,我还是略施拳脚,实现了一个简单且丝滑的过渡效果:
Untitled.gif
老板看后,觉得我的细节处理的很好,给我一顿画饼,承诺只要我好好坚持,一定可以等到升职加薪!当然,我胃口小,老板的饼消化不了。我还是分享一下自己在不借助第三方组件的情况下,如何快速的实现这样一个效果。

技术实现方案

业务分析

仔细观察需求,我们可以分析出其实动画主要是两个部分:一级标题的箭头旋转二级标题区域的折叠展开
image.png
我们先实现一下基本的html结构:

<template>
   <div class="nav-bar-content">

      <div class="header-wrap" @click="open = !open">
          <span class="text">自动化需求计算条件输如</span>
          <span class="arrow">
              >
          </span>
      </div>

      <div v-show="open" class="content">
          <p>算法及跃变计算条件</p>
          <p>空间品质判断条件</p>
          <p>需求自动计算条件</p>
          <p>通风系统</p>
      </div>

  </div>
</template>

<script setup>
const open = ref(false);
</script>

上述代码非常简单,点击一级标题时,更改open的值,从而实现二级标题的内容区域展示与隐藏。

箭头旋转动画

Untitled.gif
实现箭头旋转动画其实非常容易,我们只要在红色面板展开时,给箭头添加一个新的类名,在这个类名中做一些动画处理即可。

<template>
  <div class="header-wrap" @click="open = !open">
      <span class="text">自动化需求计算条件输如</span>
      <span class="arrow flex-be-ce" :class="{ open: open }">
          >
      </span>
  </div>
</template>
<style lang="less" scoped>
.arrow {
   
   
    width: 16px;
    height: 16px;
    cursor: pointer;
    margin-left: 1px;
    transition: transform 0.2s ease;
}
.open {
   
   
    transform: rotate(90deg);
    transition: transform 0.2s ease;
}
</style>

上述的代码通过 CSS 的 transform 属性和动态绑定open类名实现了箭头的旋转效果。

注意:arrow也需要定义过渡效果

折叠区域动画效果

要实现折叠区域的动画效果,大致思路和上面一样。

使用vue的transition组件实现

借助vue的transition组件,我们可以实现折叠区域进入(v-show='true')和消失(v-show='fasle')的动画。一种可行的动画方案就是让面板进入前位置在y轴-100%的位置,进入后处于正常位置。
Untitled.gif

<template>
   <div class="nav-bar-content">

      <div class="header-wrap" @click="open = !open">
          <span class="text">自动化需求计算条件输如</span>
          <span class="arrow" :class="{ open: open }">
              >
          </span>
      </div>

      <div class="content-wrap">
          <Transition>
              <div v-show="open" class="content">
                  <p>算法及跃变计算条件</p>
                  <p>空间品质判断条件</p>
                  <p>需求自动计算条件</p>
                  <p>通风系统</p>
              </div>
          </Transition>
      </div>

  </div>
</template>

<script setup>

const open = ref(false);
</script>
<style lang="less" scoped>

<style lang="less" scoped>
.v-enter-active,
.v-leave-active {
   
   
    transition: transform 0.5s ease;
}
.v-enter-from,
.v-leave-to {
   
   
    transform: translateY(-100%);
}
</style>

上述效果有一点瑕疵,就是出现位置把一级标题盖住了,我们稍微修改下

<div class="content-wrap">
    <Transition>
        <div v-show="open" class="content">
            <p>算法及跃变计算条件</p>
            <p>空间品质判断条件</p>
            <p>需求自动计算条件</p>
            <p>通风系统</p>
        </div>
    </Transition>
</div>

.content-wrap {
   
   
    overflow: hidden;
}

Untitled.gif

使用动态类名的方式实现

效果好很多!但这种效果和第三方组件库的效果不太一致,我们以element的折叠面板效果为例:
Untitled.gif
我们可以发现,它的这种动画,是折叠面板的高度从0逐渐增高的一个过程。所以最简单的就是,如果我们知道折叠面板的高度,一个类名就可以搞定!

<template>
   <div class="nav-bar-content">

      <div class="header-wrap" @click="open = !open">
          <span class="text">自动化需求计算条件输如</span>
          <span class="arrow flex-be-ce" :class="{ open: open }">
              >
          </span>
      </div>

      <div class="content-wrap" :style="{ height: open ? '300px' : 0 }">
          <div class="content">
              <p>算法及跃变计算条件</p>
              <p>空间品质判断条件</p>
              <p>需求自动计算条件</p>
              <p>通风系统</p>
          </div>
      </div>

  </div>
</template>

<script setup>
const open = ref(false);
</script>

<style lang="less" scoped>
.content-wrap {
   
   
    height: 0;
    transition: height 0.5s ease;
}
</style>

Untitled.gif
如果这个折叠面板的内容通过父组件传递,高度是动态的,我们只需要使用js计算这里的高度即可:

<template>
   <div class="nav-bar-content">

      <div class="header-wrap" @click="open = !open">
          <span class="text">自动化需求计算条件输如</span>
          <span class="arrow flex-be-ce" :class="{ open: open }">
              >
          </span>
      </div>

      <div class="content-wrap" :style="{ height: open ? '300px' : 0 }">
          <div class="content" ref="contentRef">
              <slot></slot>
          </div>
      </div>

  </div>
</template>

<script setup>
const open = ref(false);
const contentRef = ref();
const height = ref(0);
onMounted(() => {
   
   
    height.value = contentRef.value.offsetHeight + 'px';
});
</script>

<style lang="less" scoped>
.content-wrap {
   
   
    height: 0;
    transition: height 0.5s ease;
}
</style>

这样,我们就通过几行代码就实现了一个非常简单的折叠面板手风琴效果!
Untitled.gif

总结

要想实现一个折叠面板的效果,最简单的还是直接使用第三方组件库,但是如果项目不能使用其他组件库的话,手写一个也是非常简单的!也希望大家能在评论区给出更好的实现方式,供大家学习!

相关文章
|
缓存
若依 this.$router.push 同地址不同参,页面不刷新问题
若依 this.$router.push 同地址不同参,页面不刷新问题
1495 0
|
Web App开发 JavaScript 前端开发
网页VUE纯前端在线预览编辑Office,支持doc/docx、xls/xlsx、ppt/pptx、pdf等格式
随着互联网技术的不断发展,越来越多的企业开始采用在线办公模式,微软Office Word 是最好用的文档编辑工具,然而doc、docx、xls、xlsx、ppt、pptx等格式的Office文档是无法直接在浏览器中直接打开的,如果可以实现Web在线预览编辑OffIce,肯定会还带来了更高效、便捷的办公体验,为我们的工作带来了更多可能性。
3024 0
|
前端开发 JavaScript
纯css动画 —— 展开、收起
纯css动画 —— 展开、收起
744 2
|
数据格式
使用小技巧实现el-table组件的合并行功能,ElementUI和ElementPlus都适用
本文介绍了在ElementUI和ElementPlus中使用`el-table`组件实现合并行功能的技巧,包括多列合并和单列合并的方法,并提供了相应的示例代码和运行效果。
9162 1
使用小技巧实现el-table组件的合并行功能,ElementUI和ElementPlus都适用
|
8月前
|
存储 人工智能 搜索推荐
评测 | AI 剧本生成与动画创作
随着短视频行业的快速发展,内容的即时性和创意性备受关注。传统动画制作流程复杂、耗时且成本高,难以跟上热点话题的变化。阿里云的“AI剧本生成与动画创作”解决方案通过AI自动化生成剧本、插图和语音,借助云计算的强大算力,大幅提速创作流程,降低成本,帮助短视频内容更高效、更有创意地生产。 本文将详细介绍该解决方案的部署和实际体验,涵盖从注册阿里云账号、开通相关服务到部署应用的全过程,并分享使用感受。尽管部署简单直观,生成的动画效果目前仍存在不足,但在创意动画和快速生成方面已展现出一定潜力。未来,随着技术的不断优化,期待AI动画创作能带来更高质量的作品,推动行业创新和发展。
349 5
评测 | AI 剧本生成与动画创作
|
存储 前端开发 Java
Spring Boot 集成 MinIO 与 KKFile 实现文件预览功能
本文详细介绍如何在Spring Boot项目中集成MinIO对象存储系统与KKFileView文件预览工具,实现文件上传及在线预览功能。首先搭建MinIO服务器,并在Spring Boot中配置MinIO SDK进行文件管理;接着通过KKFileView提供文件预览服务,最终实现文档管理系统的高效文件处理能力。
1444 11
|
JavaScript
vue父子组件传值,父组件内容更新子组件内容不实时更新
vue父子组件传值,父组件内容更新子组件内容不实时更新
3667 0
|
人工智能 JavaScript 前端开发
如何创建一个Vue聊天机器人 – 分步指南
如何创建一个Vue聊天机器人 – 分步指南
如何创建一个Vue聊天机器人 – 分步指南
|
12月前
|
JavaScript
vue中使用echarts绘制双Y轴图表时,刻度没有对齐的两种解决方法
vue中使用echarts绘制双Y轴图表时,刻度没有对齐的两种解决方法
2730 0
|
JavaScript
如何对ElementUI、ElementPlus中的Tree树组件进行美化,如增加辅助线、替换展开收起图标、点击节点后文字高亮等效果?本文给你答案!
本文介绍了如何对ElementUI和ElementPlus的Tree树组件进行美化,包括增加辅助线、替换展开收起图标、点击节点后文字高亮等效果,并提供了详细的代码示例和实现效果。
3119 0
如何对ElementUI、ElementPlus中的Tree树组件进行美化,如增加辅助线、替换展开收起图标、点击节点后文字高亮等效果?本文给你答案!