下拉组件从0到1 | 青训营笔记

173 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天

本文主要介绍下拉组件从0到1的实现。

前言

下拉组件常见的写法就是<select><option>标签的使用。基于此,我们可以做出很不错的效果,例如:

image.png

但是,当我们想要更多样的效果,例如下拉框要变成直角。定制一些更好看的样式时,我们发现这好像很难实现。 无奈,那我们就自己做一个组件。

image (1).png

分析

我们分析一下,一个下拉组件由哪几部分组成。

  • 选中框
    • 选中文字
    • 下箭头图标
  • 候选框

实现方式

我们知道,当点击组件时,候选框会显示在选中框下方。这种方式,我们可以使用相对定位来实现。但是为了让使用效果更好,我们直接让整个组件都是相对定位。他们都相对于一个没有宽高的占位父元素做定位。

<div class="dorp-down-area">
  <div class="drop-down dorp-down"></div>
</div>

.dorp-down-area {
position: relative;
z-index: 9;
}

.dorp-down-area .drop-down {
    position: absolute;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
}

接着,我们完善一下选中框。选中框除了外边框,主要由两部分组成:文字、图标。那么我们可以使用一个flex布局,使用between方式对齐两个元素。

<li class="dropdown-toggle flex items-center justify-between" @click="isShow = !isShow">
  7天内
  <div class=" text-[#b2bac2]" i-carbon:caret-up :class="!!isShow ? 'toggled' : ''" style="transition: all .5s;" />
</li>

li {
    list-style: none;
}
.dropdown-toggle {
    box-sizing: border-box;
    min-width: 7rem;
    font-size: 1rem;
    border-radius: 2px;
    padding: 2px 10px;
    font-weight: 400;
    border: 1px solid #ebebeb;
}
.dropdown-toggle:hover {
    background-color: #fafafb;
    cursor: pointer;
}
.toggled {
    transform: rotate(-180deg);
    transition: all .5s;
}

接着就是候选框。这部分比较简单,我们直接使用

  • 标签完成候选列表。那么候选列表的样式就非常简单了。

    <ul v-if="isShow" class="dropdown-menu">
            <li class="route-active">
              <a href="/?sort=three_days_hottest">3天内</a>
            </li><li class="router-link-exact-active route-active">
              <a href="/?sort=weekly_hottest" aria-current="page">7天内</a>
            </li><li class="route-active">
              <a href="/?sort=monthly_hottest">30天内</a>
            </li><li class="route-active">
              <a href="/?sort=hottest">全部</a>
            </li>
    </ul>
    
    .dropdown-menu {
        box-sizing: border-box;
        position: absolute;
        top: 105%;
        left: 0;
        z-index: 1000;
        min-width: 7rem;
        font-size: 1rem;
        list-style: none;
        text-align: left;
        border-radius: .17rem;
        box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
        border: 1px solid #ebebeb;
        background-color: #fff;
    }
    
    .dropdown-menu li {
        overflow: hidden;
        width: 100%;
    }
    
    .dropdown-menu li a {
        display: block;
        clear: both;
        padding: .83rem;
        line-height: 1.17;
        color: #909097;
    }
    .dropdown-menu li a:hover {
        background-color: #fafafb;
    }
    a {
        text-decoration: none;
        cursor: pointer;
        color: #909090;
    }
    

    那么只需要添加相应的控制元素,使得可以控制候选框的出现与隐藏。我们这里直接用isShow元素来做一个判断。并通过单击事件改变isShow状态的值,从而控制候选框的出现与隐藏。

    优化

    其实上面代码非常粗糙,有很多地方存在一些问题。就比如说,这些CSS样式命名不规范的问题。还有代码格式的问题,我们编写一个组件,不仅需要把代码写出来,能用就行。更需要精进代码质量,努力让自己的代码有所规范,能够让别人一眼看得懂,能够让别人一看就知道咋写的,然后抄了去。

    结语

    大家可以看到,一个候选框组件非常简单就能实现我们想要的效果。我们有时候需要一个小组件,完全不需要引入一个组件库,我们只需要对着这些组件细致分析,然后用简洁的方式实现就好。