React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录

  • 前言
  • Dropdown组件
    • 1. 功能分析
    • 2. 代码+详细注释
    • 3. 使用方式
    • 4. 效果展示
  • 总结


前言

今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。


Dropdown组件

1. 功能分析

(1)通过position属性,可以控制下拉选项的位置
(2)通过传入width属性, 可以自定义下拉选项的宽度
(3)通过传入className属性, 可以自定义加载动画的样式

2. 代码+详细注释

// @/components/Dropdown/index.tsx
import { useState } from 'react'
import classNames from "classnames";
import { DropDownContainer, DropDown } from './styled'
import Button from '@/Button'
// 组件的属性类型
type Options = {
  // 下拉选项的文本
  name: string
  // 下拉选项自定义类名
  value: string
}
// 组件的属性类型
type Props = {
  data: Options[]
  position?: string
  width?: string
  name: string
  className?: string
};
export default ({
  data,
  position,
  width,
  name,
}: Props) => {
  // 是否显示下拉选项
  const [showDropDown, setShowDropDown] = useState(false)
  // 下拉选项位置
  const dropdownPosition: string = position ?? 'left'
  // 下拉框宽度,默认100%
  const dropdownWidth: string = width ?? '100%'
  // 下拉选项点击事件
  const handlerItemClick = () => {
    setShowDropDown(false)
  }
  return (
    <>
      <DropDownContainer  className={classNames(className)}width={dropdownWidth} onMouseLeave={handlerItemClick}>
        <Button
          className="dropdown-button"
          onMouseOver={() => {
            setShowDropDown(true)
          }}
        >
          <div className={classNames('dropdown-button-content')}>
            <div
              className={classNames('dropdown-button-title')}
              style={{
                textTransform: 'uppercase',
              }}
            >
              {name}
            </div>
            <div className={classNames('dropdown-arrow')}>&gt;</div>
          </div>
        </Button>
        {showDropDown && (
          <DropDown position={dropdownPosition} onMouseLeave={ handlerItemClick }>
            <>
              {data.map((item, index) => (
                <>
                  <Button key={index} className={classNames('dropdown-item')} onClick={ handlerItemClick }>
                    {item.name}
                  </Button>
                  {index !== data.length - 1 && <div className={classNames('dropdown-separate')}></div>}
                </>
              ))}
            </>
          </DropDown>
        )}
      </DropDownContainer>
    </>
  )
}


------------------------------------------------------------------------------
// @/components/Dropdown/styled.tsx
import styled from "styled-components";
interface DropDownProps {
  width: string;
}
interface DropDownItemProps {
  position: string;
}
export const DropDownContainer = styled.div<DropDownProps>`
  display: flex;
  align-items: center;
  height: 100%;
  margin-top: 1px;
  padding: 10px 0;
  position: relative;
  width: ${({ width }) => width};
  @media (max-width: 750px) {
    margin-right: 0;
  }
  color: ${(props) => props.theme.primary};
  .dropdown-button-content {
    display: flex;
    align-items: center;
    .dropdown-arrow {
      font-size: 18px;
      margin-left: 4px;
      transform: rotate(90deg);
    }
  }
  &:hover {
    .dropdown-arrow {
      transform: rotate(270deg);
    }
  }
`;
export const DropDown = styled.div<DropDownItemProps>`
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 130px;
  color: #000;
  background: #fff;
  border-radius: 5px;
  box-shadow: 0 2px 4px 0 rgb(0 0 0 / 50%);
  z-index: 1000;
  position: absolute;
  top: 45px;
  left: ${({ position }) => (position === "left" ? 0 : "auto")};
  right: ${({ position }) => (position === "right" ? 0 : "auto")};
  .dropdown-item {
    display: flex;
    align-items: center;
    width: 94%;
    height: 33px;
    margin: 3px 3% 0;
    padding: 0 3%;
    font-size: 12px;
    white-space: nowrap;
    border-radius: 3px;
    cursor: pointer;
    &:hover {
      background: #f1f1f1;
      color: var(--cd-primary-color);
    }
  }
  .dropdown-separate {
    width: 88%;
    height: 0.5px;
    border: solid 0.5px #c3c3c3;
    margin: 0 6%;
  }
`;

3. 使用方式

// 引入组件
import Dropdown from '@/components/Dropdown'
// 使用
<Dropdown
  data={[
    { name: '下拉选项111111', value: '434432' },
    { name: '下拉选项222222', value: '434432' },
    { name: '下拉选项333333', value: '434432' },
 ]}
 position="left"
 width="100px"
 name="dropdown"
/>

4. 效果展示

(1)左对齐
在这里插入图片描述

(2)右对齐
在这里插入图片描述


总结

下一篇讲【高阶渲染劫持组件封装】。关注本栏目,将实时更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/739024.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

环境安装--JDK

目录 官网下载JDK JDK安装 配置环境变量 验证使用 卸载 官网下载JDK https://www.oracle.com/java/technologies/downloads https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html 注意区分&#xff1a; Java SE Development Kit 8…

C++集中营笔记(1)第一节课和第二节课

第一节课linux的使用 1.Linux 常用命令 [chenbogon ~]$ cd ~ [chenbogon ~]$ cd /home [chenbogon home]$ mkdir cpp-test mkdir: cannot create directory ‘cpp-test’: Permission denied [chenbogon home]$ sudo mkdir cpp-testWe trust you have received the usual lec…

群辉NAS使用Kodi影视墙

目录 一、KODI安装 二、修改UI语言 1、修改显示字体 2、修改语言为中文 四、添加媒体库 五、观看电影 五、高级设置 1、视图类型 2、修改点击播动作 五、补充 1、文件组织结构及命名 2、电影信息的刮削 (1)添加影片 (2)演员管理 (3)影片管理 (4)说明 K…

「51媒体」媒体邀约小常识

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 媒体邀约是组织或企业为了宣传、推广或展示其活动、产品或…

Linux tcpdump抓包必备知识

author: 放牛娃学编程 moto: 分享与热爱&#xff0c;不是大爱我不说 放牛娃每日一语: 除了你自己&#xff0c;没有人可以说你不行 别急着划开&#xff0c;这篇笔记一定能够给你带来收获 因为这里你能学到AI永远也给不了你的知识 Linux tcpdump抓包必备知识 文章目录 Linux tcp…

傅佩荣讲座视频全集百度网盘,傅佩荣讲座视频大全百度云

在当今信息爆炸的时代&#xff0c;获取知识的途径日益多元化&#xff0c;其中&#xff0c;通过网络观看各类教学视频已成为众多学习者的首选。傅佩荣教授的视频课程深受广大学者的喜爱。然而&#xff0c;对于许多初学者来说&#xff0c;如何下载傅佩荣的视频却是一个难题。本文…

nginx实现反向代理出现502的解决方法

目录 1. 出现原因 1.1. 防火墙拦截了端口 1.1.1. 使用 iptables 1.1.2. 使用 firewall-cmd&#xff08;适用于 CentOS/RHEL 7&#xff09; 1.2. docker容器中的ip和宿主机ip不一致 1. 出现原因 这里我是用的docker容器来进行nginx的启动的&#xff0c;在我们用nginx的配置…

Hyperf 在 NginxProxyManager 如何配置 websocket?

新建代理 填写域名等服务信息&#xff0c;选择支持WebSockets。 创建 SSL 编写nginx配置 location /message.io{proxy_pass http://<你的ip>:<对应端口号>;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upg…

测试内容初步认知

测试流程 了解需求--需求评审--编写测试用例--测试用例评审(产品、开发、测试)--提测测试--bug管理(devops)--集成--集成回归--发布灰度包测试(灰度周期一周)----编写测试报告--发布上线 测试岗位划分 功能测试 负责编写测试用例&#xff0c;执行手动测试&#xff0c;记录并…

Diffutoon:动漫风格视频转绘

Diffutoon 是 DiffSynth Studio 的一个子项目&#xff0c;用于将真人视频转为动漫风格&#xff08;三渲二&#xff09;

Springboot整合阿里云ONS RocketMq(4.0 http)

1. 引入依赖 <!--阿里云ons&#xff0c;方便的接入到云服务--> <dependency><groupId>com.aliyun.openservices</groupId><artifactId>ons-client</artifactId><version>1.8.4.Final</version> </dependency>2. 配置 配…

MyBatis系列之分页插件及问题

概述 无论是C端产品页面&#xff0c;还是后台系统页面&#xff0c;不可能一次性将全部数据加载出来。后台系统一般都是PC端登录&#xff0c;用Table组件&#xff08;如Ant Design Table&#xff09;渲染展示数据&#xff0c;可点击列表的下一页&#xff08;或指定某一页&#…

Spring Boot集成Redisson

文章目录 Spring Boot集成Redisson1. Redisson概述2. Redission作用3. 集成Redission前提&#xff1a;步骤 1: 添加依赖步骤 2: 配置Redisson 4. 结论 Spring Boot集成Redisson 1. Redisson概述 Redisson是一个在Redis基础上实现的Java驻内存数据网格&#xff08;In-Memory D…

C语言入门课程学习笔记9:指针

C语言入门课程学习笔记9 第41课 - 指针&#xff1a;一种特殊的变量实验-指针的使用小结 第42课 - 深入理解指针与地址实验-指针的类型实验实验小结 第43课 - 指针与数组&#xff08;上&#xff09;实验小结 第44课 - 指针与数组&#xff08;下&#xff09;实验实验小结 第45课 …

替代LTC4449高速同步N道沟MOSFET驱动器|具有轨对轨栅极驱动

1. 产品特性 ➢ 15ns 典型传播延迟 ➢ 5ns 高侧/低侧匹配 ➢ 轨至轨栅极驱动 ➢ 自适应死区和直通保护 ➢ 3A 峰值拉电流和 4.5A 峰值灌电流 ➢ 驱动 2 颗 NMOS 组成的半桥 ➢ 欠压保护 ➢ 过热保护 2. 功能描述 PC4449 产品手册 PC4449是一款专为高频率、高效率的应…

教育护眼灯品牌排行有哪些上榜?中国十大教育照明品牌分享

在当前的时代背景下&#xff0c;孩子们的课业负担依然沉重。随着他们年龄的增长&#xff0c;作业量不断增加&#xff0c;对视力的需求也随之上升。加之&#xff0c;现今许多作业需借助电子屏幕完成&#xff0c;孩子们面临视力问题的风险因而愈加提早。家长们逐渐认识到&#xf…

轻量级在线服装3D定制引擎Myway简介

我写的面向web元宇宙轻量级系列引擎中的另外一个&#xff0c;在线3D定制引擎Myway 3D。 用于在线商品定制&#xff0c;比如个性化服装的定制、日常用品&#xff08;如杯子&#xff09;、家装&#xff08;被套&#xff09;等物品的在线定制。 特性列表&#xff1a; 可更换衣服…

什么是中间件?常见中间件有哪些?

中间件是什么 中间件是一种独立的系统软件或服务程序&#xff0c;分布式应用软件借助这种软件在不同的技术之间共享资源。中间件位于客户机/ 服务器的操作系统之上&#xff0c;管理计算机资源和网络通讯。是连接两个独立应用程序或独立系统的软件。相连接的系统&#xff0c;即…

STM32 - LED灯 蜂鸣器

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…

adb 查看哪些应用是双开的

adb shell pm list users 得到 这 里有 user 0 ,11,999 其中0是系统默认的&#xff0c;11是平行空间的&#xff0c;999是双开用户 pm list packages --user 999 -3 得到了999用户安装第三方应用的包名 pm list packages --user 11 -3 得到了隐私空间用户安装第三方应用的…