React实现点击切换组件

实现如上组件

组件代码:

TypeScript 复制代码
import { SwapOutlined } from "@ant-design/icons"
import React, { useState } from "react"
import './index.less'

interface ISwitchTypeProps {
  onChange?: (val) => boolean
  activeKey?: string
  left: { key: string, text: string }
  right: { key: string, text: string }
}
const SwitchType = ({ onChange, left, right, activeKey }: ISwitchTypeProps) => {
  const [data, setData] = useState({
    left,
    right,
    activeKey:activeKey||left.key
  })
  const changeActiveData = () => {
    const activeKey = data.activeKey === left.key ? right.key : left.key
    const changeData = () => {
      setData({
        left: { ...data.right },
        right: { ...data.left },
        activeKey
      })
    }
    if (onChange&&onChange(activeKey)) {
      changeData()
    }
    if (!onChange) {
      changeData()
    }
  }

  const changeActive = () => {
    const activeKey = data.activeKey === left.key ? right.key : left.key
    const changeData = () => {
      setData({
        ...data,
        activeKey
      })
    }
    if (onChange&&onChange(activeKey)) {
      changeData()
    }
    if (!onChange) {
      changeData()
    }
  }
  return <div className="switch-type">
    <div className={data.activeKey === data.left.key ? 'type-active' : 'type-data'} onClick={changeActive} key={data.left.key}>{data.left.text}</div>
    <div className="change-icon" onClick={changeActiveData}><SwapOutlined /></div>
    <div className={data.activeKey === data.right.key ? 'type-active' : 'type-data'} onClick={changeActive} key={data.right.key}>{data.right.text}</div>
  </div>
}

export default SwitchType

index.less样式文件

TypeScript 复制代码
.switch-type {
  display: flex;
  align-items: center;
  color: #B9BCC1;

  .change-icon {
    border-radius: 2px;
    background-color: #F1F3F5;
    width: 24px;
    height: 24px;
    line-height: 24px;
    text-align: center;
    flex-shrink: 0;
    margin: 0 8px;
    color: #555961;
    cursor: pointer;
  }

  .type-data {
    cursor: pointer;
  }

  .type-active {
    color: #555961;
    .type-data
  }
}

若想要实现如上效果,点击不切换左右顺序,只切换选中项,把onClick事件统一成changeActive就可以了

TypeScript 复制代码
import { SwapOutlined } from "@ant-design/icons"
import React, { useState } from "react"
import './index.less'

interface ISwitchTypeProps {
  onChange?: (val) => boolean
  activeKey?: string
  left: { key: string, text: string }
  right: { key: string, text: string }
}
const SwitchType = ({ onChange, left, right, activeKey }: ISwitchTypeProps) => {
  const [data, setData] = useState({
    left,
    right,
    activeKey: activeKey || left.key
  })

  const changeActive = () => {
    const activeKey = data.activeKey === left.key ? right.key : left.key
    const changeData = () => {
      setData({
        ...data,
        activeKey
      })
    }
    if (onChange && onChange(activeKey)) {
      changeData()
    }
    if (!onChange) {
      changeData()
    }
  }
  return <div className="switch-type">
    <div className={data.activeKey === data.left.key ? 'type-active' : 'type-data'} onClick={changeActive} key={data.left.key}>{data.left.text}</div>
    <div className="change-icon" onClick={changeActive}><SwapOutlined /></div>
    <div className={data.activeKey === data.right.key ? 'type-active' : 'type-data'} onClick={changeActive} key={data.right.key}>{data.right.text}</div>
  </div>
}

export default SwitchType
相关推荐
ℋᙚᵐⁱᒻᵉ鲸落3 小时前
移动端滑动手势冲突:overflow: auto导致外层横向滑动失效
前端·javascript·css·vue.js·html
默_笙5 小时前
🎃 前端学了 Next.js,后端该学啥?NestJS 就是 Node 版的蜜雪冰城
前端·javascript
前端snow6 小时前
ai agent --- 实现 openclaw 定时间效果
前端
码云之上6 小时前
换模型之后,Chatbot 为什么要自己做 compact?
前端·agent·前端工程化
星栈6 小时前
自定义 UI-UX-Pro-Max 的 CSV 知识库,把 AI 生成的后台拉回行业该有的样子
前端·agent·weui
研☆香6 小时前
简单的图片上传 删除 预览
前端
ITresearchGuest6 小时前
我用 AI 一小时写了一个世界杯数据可视化平台|前端 VibeCoding 初体验
前端·人工智能·信息可视化
慧一居士8 小时前
Vite项目中使用Less步骤,详细使用示例
前端·css
花间相见8 小时前
【LangChain组件03】—— LangChain Agents 执行与状态:工作流程与状态管理实战
java·前端·langchain
kyriewen8 小时前
面试官让我用 AI 重构一个 8 年陈的 React 组件——他说他不看代码,只看我会不会拆
前端·javascript·面试