实现一个Switch开关组件只需要一个div?详细记录Switch组件开发过程

最终效果图

switch

实现逻辑

一、switch容器

image-20211213231527575
// html

	<div className="dumbo-switch"></div>
  
// css

	.dumbo-switch {
  	height: 22px;
  	width: 44px;
  	border: 1px solid;
  	border-radius: 100px;
  	border: 1px solid #cccccc;
  	cursor: pointer;
	}

二、switch inner

image-20211213231422890
// html
	
// css
.dumbo-switch {
  height: 22px;
  width: 44px;
  border-radius: 100px;
  background: #1890ff;
  position: relative;

  &::after {
    position: absolute;
    background: #ffffff;
    content: '';
    box-sizing: border-box;
    border-radius: 100%;
    width: 18px;
    height: 18px;
    top: 2px;
    box-shadow: 0 2px 4px #00230b33;
  }
}

.dumbo-switch--default {
  opacity: 0.4;
  cursor: not-allowed;
  &::after {
    left: 2px;
  }
}

三、switch 选中状态

image-20211213231011945

// html

  <div className="dumbo-switch dumbo-switch--checked"></div>
  
// css
.dumbo-switch {
  height: 22px;
  width: 44px;
  border-radius: 100px;
  background: #1890ff;
  position: relative;

  &::after {
    position: absolute;
    background: #ffffff;
    content: '';
    box-sizing: border-box;
    border-radius: 100%;
    width: 18px;
    height: 18px;
    top: 2px;
    box-shadow: 0 2px 4px #00230b33;
    transition: all 0.3s ease-in-out;
  }
}

.dumbo-switch--checked {
  opacity: 1;
  cursor: pointer;
  &::after {
    left: calc(100% - 20px);
  }
}

四、抽取 props 参数
  • checked
  • onChange
  • disabled
import React from 'react';
import classnames from 'classnames';
import './index.less';

export interface IButton {
    checked: boolean;
    onChange: (checked: boolean) => void;
    disabled: boolean;
}

export default function Switch(props: IButton) {
    const { checked, onChange, disabled } = props;
    return (
        <div
            onClick={() => {
               if (!disabled) {
                    onChange(!checked)
                }
            }}
            className={classnames("dumbo-switch", {
                'dumbo-switch--default': !checked,
                'dumbo-switch--checked': checked,
                'dumbo-switch--disabled': disabled
            })}>

        </div>
    )
}

React 代码

import React from 'react';
import classnames from 'classnames';
import './index.less';

export interface IButton {
    checked: boolean;
    onChange: (checked: boolean) => void;
    disabled?: boolean;
}

export default function Switch(props: IButton) {
    const { checked, onChange, disabled = false } = props;
    return (
        <div
            onClick={() => {
                if (!disabled) {
                    onChange(!checked)
                }
            }}
            className={classnames("dumbo-switch", {
                'dumbo-switch--default': !checked,
                'dumbo-switch--checked': checked,
                'dumbo-switch--disabled': disabled
            })}>

        </div>
    )
}

.dumbo-switch {
  height: 22px;
  width: 44px;
  border-radius: 100px;
  background: #1890ff;
  position: relative;

  &::after {
    position: absolute;
    background: #ffffff;
    content: '';
    box-sizing: border-box;
    border-radius: 100%;
    width: 18px;
    height: 18px;
    top: 2px;
    box-shadow: 0 2px 4px #00230b33;
    transition: all 0.3s ease-in-out;
  }
}

.dumbo-switch--default {
  opacity: 0.4;
  &::after {
    left: 2px;
  }
}

.dumbo-switch--checked {
  opacity: 1;
  cursor: pointer;
  &::after {
    left: calc(100% - 20px);
  }
}

.dumbo-switch--disabled {
  cursor: not-allowed;
  opacity: 0.4;
}

调用方式

export const Default = ({ ...props }) => {
    const [visible, setVisible] = useState(false);
    return <div>
        <Switch checked={visible} onChange={setVisible} />
    </div>
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐闻x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值