CarouseIndicator 组件应用:0行JS代码实现好看的手风琴式折叠卡片效果

avatar
前端组件库 @华为

Kagol

前两天写了一篇前端积木理论的实战文章,以DevUI组件库的Carousel走马灯组件为例,详细地阐述了如何将积木理论运用到组件开发中,里面提到抽象分层的思想,通过抽象的思想将Carousel组件最核心的交互抽象成usePage这个Composable,通过分层的思想将Carousel组件划分成CarouselIndicator/CarouselPagination两个子组件。

为什么CarouselIndicator组件要单独定义v-model呢?

当提到CarouselIndicator的具体实现原理时,贪财庸俗之人同学提了一个问题:

为什么CarouselIndicator组件不直接用Carousel组件的pageIndex,而是自己定义一个v-model双向绑定?

image.png

这个问题我觉得问得非常好!

说明这位同学确实认真看了这篇文章,并且有自己的思考,我当时回复得很简单:

为了避免CarouselIndicator与Carousel组件产生耦合。

下午吃完晚饭一边散步一边刷掘金的时候,突然刷到battleKing同学去年8月份写的一篇文章:

手风琴式折叠卡片展示效果

battleKing同学的文章写得非常不错,代码清晰易懂,点赞!

我想了下,这不就是一个CarouselIndicator吗?

所以为了更清楚地解释贪财庸俗之人小伙伴提出的那个问题:

为什么CarouselIndicator组件不直接用Carousel组件的pageIndex,而是自己定义一个v-model双向绑定?

我打算用CarouselIndicator组件实现一下手风琴式折叠卡片的效果。

单独使用CarouselIndicator组件实现手风琴式折叠卡片效果

由于CarouselIndicator组件其实是一个独立的组件,并不与Carousel组件有任何耦合,因此可以单独使用。

还是在App.vue文件中

// 引入DCarouselIndicator组件和usePage
<script setup lang="ts">
import { DCarouselIndicator, usePage } from './components/carousel'
const { pageIndex, setPageIndex } = usePage(1)
</script>

<template>
<DCarouselIndicator>
  // 中间的dom元素直接从battleKing同学的文章中拷贝即可
  // 《手风琴式折叠卡片展示效果》:https://juejin.cn/user/3677241439685368
  <div class="box">
    <div :class="['panel', pageIndex === 1 ? 'active' : '']" @click="setPageIndex(1)">
      <h3>Explore The World</h3>
    </div>
    <div :class="['panel', pageIndex === 2 ? 'active' : '']" @click="setPageIndex(2)">
      <h3>Wild Forest</h3>
    </div>
    <div :class="['panel', pageIndex === 3 ? 'active' : '']" @click="setPageIndex(3)">
      <h3>Sunny Beach</h3>
    </div>
    <div :class="['panel', pageIndex === 4 ? 'active' : '']" @click="setPageIndex(4)">
      <h3>City on Winter</h3>
    </div>
    <div :class="['panel', pageIndex === 5 ? 'active' : '']" @click="setPageIndex(5)">
      <h3>Mountains - Clouds</h3>
    </div>
  </div>
</DCarouselIndicator>
</template>

<style>
// 样式也直接从battleKing同学的文章中直接拷贝,啥也不用改
.box {
  display: flex;
  width: 90vw;
}

.panel {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  height: 40vh;
  border-radius: 50px;
  color: #fff;
  cursor: pointer;
  flex: 0.5;
  margin: 10px;
  position: relative;
  -webkit-transition: all 700ms ease-in;
  transition: all 700ms ease-in;
}
.panel:nth-child(1){
  background-image: url("https://picsum.photos/1350/900?random=1");
}
.panel:nth-child(2){
  background-image: url("https://picsum.photos/1350/900?random=2");
}
.panel:nth-child(3){
  background-image: url("https://picsum.photos/1350/900?random=3");
}
.panel:nth-child(4){
  background-image: url("https://picsum.photos/1350/900?random=4");
}
.panel:nth-child(5){
  background-image: url("https://picsum.photos/1350/900?random=5");
}

.panel h3 {
  font-size: 24px;
  position: absolute;
  bottom: 20px;
  left: 20px;
  margin: 0;
  opacity: 0;
}

.panel.active {
  flex: 5;
}

.panel.active h3 {
  opacity: 1;
  transition: opacity 0.3s ease-in 0.4s;
}
</style>

手风琴式折叠卡片实现效果

最终效果如下:

2022-01-11 22.35.37.gif

是不是非常简单,几乎不用写什么逻辑代码,就实现了手风琴式折叠卡片的效果,希望贪财庸俗之人同学能理解为什么CarouselIndicator要和Carousel解耦。

积木理论最核心的思想就是:

让每一个组件都像积木一样可以随意拼接和组合使用,组件之间是独立和内聚的,不与其他组件有任何耦合。

这样我们开发前端页面,就像搭积木一样简单,只需要把组件拼起来就可以啦。

觉得有用就给我点个赞吧,你的点赞是对我最大的鼓励,后续我也会持续输出更多DevUI组件设计干货文章,尽情期待!

优化思路

目前的做法在写法上不够简洁,引入了usePage,其实这部分逻辑可以放在CarouselIndicator组件里面,使用起来大致是这样:

<DCarouselIndicator>
  <div class="panel">
    <h3>Explore The World</h3>
  </div>
  <div class="panel">
    <h3>Wild Forest</h3>
  </div>
  <div class="panel">
    <h3>Sunny Beach</h3>
  </div>
  <div class="panel">
    <h3>City on Winter</h3>
  </div>
  <div class="panel">
    <h3>Mountains - Clouds</h3>
  </div>
</DCarouselIndicator>

DevUI 招募贡献者啦

这么简洁好用灵活Carousel组件来自哪里呢?

当然来自我们DevUI组件库啦!

欢迎对开源感兴趣的小伙伴加入我们DevUI开源组织,目前我们已经有以下组件库生态相关的开源产品:

  • Ng DevUIAngular12版本DevUI组件库,一个面向企业中后台产品的开源前端解决方案
  • Vue DevUIVue3版本DevUI组件库,基于Vite+Vue3+TypeScript+JSX技术栈
  • React DevUIReact18版本的DevUI组件库,由社区开发者xiejay创建,目前已完成20多个组件,欢迎对React感兴趣的小伙伴加入!
  • DevUI Admin:灵活可定制的Admin系统,基于DevUI组件库和设计体系
  • DevUI Icons:DevUI图标库
  • DevUI Helper:DevUI代码助手,提供丝滑的代码补全体验。

目前一共有超过80位贡献者加入我们DevUI啦,也欢迎热爱学习、热爱开源、热爱广交朋友的你加入我们!

比心

往期文章推荐

用积木理论设计一个灵活好用的Carousel走马灯组件

前端开发的积木理论——像搭积木一样做前端开发

DevUI开源的故事

建设一个温暖的开源社区

DevUI开源2021年度总结