文章目录
- 前言
- Dropdown组件
-
- [1. 功能分析](#1. 功能分析)
- [2. 代码+详细注释](#2. 代码+详细注释)
- [3. 使用方式](#3. 使用方式)
- [4. 效果展示](#4. 效果展示)
- 总结
前言
今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。
Dropdown组件
1. 功能分析
(1)通过position属性,可以控制下拉选项的位置
(2)通过传入width属性, 可以自定义下拉选项的宽度
(3)通过传入className属性, 可以自定义加载动画的样式
2. 代码+详细注释
c
// @/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')}>></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. 使用方式
c
// 引入组件
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)右对齐
总结
下一篇讲【高阶渲染劫持组件封装】。关注本栏目,将实时更新。