首页 > 其他分享 >自定义Menu组件

自定义Menu组件

时间:2024-12-28 19:28:00浏览次数:7  
标签:index style const 自定义 Menu number React onSelect 组件

自定义Menu组件

第一步:定义props

MenuProps 接口定义了 Menu 组件接收的 props,包括默认高亮项、样式、模式、选择项的回调函数和子组件。

export interface MenuProps{
    defaultIndex?: number;  //高亮
    className?: string;
    mode: MenuMode;   //纵向横向
    style?: React.CSSProperties;
    onSelect?: (selectedIndex:number)=>void; //选择第几项
    children:React.ReactNode;
}

第二步:简单的menu组件实现

const Menu : React.FC<MenuProps> = (props) => {
    const {
        className,
        mode='horizontal',
        style,
        children,
        defaultIndex=0,
        onSelect,
    }=props;
  
    const classes = classNames('menu',className,{
        'menu-vertical':mode==='vertical'
    })

    return (
        <ul className={classes} style={style}>
        {children}    
        </ul>
    )
}

第三步:使用useState控制激活项,添加handleClick 函数用于处理菜单项的点击事件,更新当前激活项并调用 onSelect 回调

const [currentActive,setActive]=useState(defaultIndex);

const handleClick = (index:number) => {
        //1.调用onselect 2.active变化
        setActive(index);
        if(onSelect){
            onSelect(index);
        }
    }

第四步:创建文件menuItem.tsx

完整代码如下

import React ,{useContext} from "react";
import classNames from "classnames";
import { MenuContext } from "./menu.tsx";

export interface MenuItemProps {
    index: number;
    disabled?: boolean;
    className?: string;
    style?: React.CSSProperties;
    children:React.ReactNode;
}
const MenuItem: React.FC<MenuItemProps>=(props)=>{
    const{index,disabled,className,style,children,}=props;
    const context = useContext(MenuContext)  //上下文部分
    const classes=classNames('menu-item',classNames,{
        'is-disabled':disabled,
        'is-active':context.index===index //上下文部分
    })
    const handleClick = () => {
        if(context.onSelect && !disabled){
            context.onSelect(index)
        }
    }
    return(
        <li className={classes} style={style} onClick={handleClick}>
            {children}
        </li>

    )
}
export default MenuItem

第五步:创建上下文

interface IMenuContext {
    index: number; // 当前选中的索引
    onSelect?: (selectedIndex: number) => void; // 选择项的回调
}
export const MenuContext = createContext<IMenuContext>({ index: 0 });

menu组件添加:


    const passedContext : IMenuContext = {
        index: currentActive ? currentActive : 0,
        onSelect: handleClick
    }
    return (
        <ul className={classes} style={style}>
        <MenuContext.Provider value={passedContext}>
        {children}
        </MenuContext.Provider>
        </ul>
    )

passedContext 对象的作用是将 Menu 组件的状态和行为集中在一个地方,以便通过上下文 (MenuContext.Provider) 传递给其子组件。子组件可以通过 useContext(MenuContext) 来访问 indexonSelect,从而实现状态的共享和菜单的交互。

完整版menu.tsx代码如下:

import React,{useState,createContext} from "react";
import classNames from "classnames";

type MenuMode = 'horizontal' | 'vertical'
type SelectCallback = (selectedIndex:number)=>void;

export interface MenuProps{
    defaultIndex?: number;  //高亮
    className?: string;
    mode: MenuMode;   //纵向横向
    style?: React.CSSProperties;
    onSelect?: (selectedIndex:number)=>void; //选择第几项
    children:React.ReactNode;
}

//createContext 是 React 中用于创建上下文的一个 API。
//上下文提供了一种方式,可以在组件树中传递数据,而不必通过每一层组件手动传递 props。
//这样非常适合于共享全局数据,比如用户身份、主题设置或者其他需要在多个组件中共享的状态。
interface IMenuContext{
     index: number;
     onSelect?: (selectedIndex:number)=>void;

}
export const MenuContext = createContext<IMenuContext>({index:0})

const Menu : React.FC<MenuProps> = (props) => {
    const {
        className,
        mode='horizontal',
        style,
        children,
        defaultIndex=0,
        onSelect,
    }=props;
    const [currentActive,setActive]=useState(defaultIndex);
    const classes = classNames('menu',className,{
        'menu-vertical':mode==='vertical'
    })
    const handleClick = (index:number) => {
        //1.调用onselect 2.active变化
        setActive(index);
        if(onSelect){
            onSelect(index);
        }
    }
    const passedContext : IMenuContext = {
        index: currentActive ? currentActive : 0,
        onSelect: handleClick
    }

    return (
        <ul className={classes} style={style}>
        <MenuContext.Provider value={passedContext}>
        {children}
        </MenuContext.Provider>
            
        </ul>
    )
}


export default Menu

标签:index,style,const,自定义,Menu,number,React,onSelect,组件
From: https://blog.csdn.net/czy0316/article/details/144756868

相关文章

  • 7-Gin 中自定义控制器 --[Gin 框架入门精讲与实战案例]
    在Gin框架中,"控制器"通常指的是处理HTTP请求的逻辑。虽然Gin本身没有像一些其他框架(例如Django或RubyonRails)那样明确地定义"控制器"的概念,但你可以通过组织代码来实现类似的功能。Gin使用路由组和中间件来帮助组织你的应用程序逻辑。为了创建自定义控制器,你......
  • 如何使用飞书自定义机器人通知消息
         大家有没有这样的需求,就是正在执行某个任务的时候希望任务完成之后给个通知,或者是软件运行报错的时候每天定期收集错误日志。平时我们工作用的飞书,所有现在用飞书机器人把消息通知出来,非常简单好用的消息通知。类似这样的消息通知还有企业微信也有。飞书拉群......
  • cocoscreator自定义effect,实现图片溶解效果
    【游戏开发教程|  10堂课入门CocosCreatorShader|新手学习路线推荐】 webgl-shader入门  基础结构 ......
  • Kong中实现已登录用户自动跳转到指定页面功能(自定义插件开发教程)
    言简意赅的讲解Kong插件支持:使用生态插件与自定义开发解决的痛点之前给大家讲解得Kong作为领先的API网关,凭借其强大的插件架构,为开发者提供了极大的灵活性和扩展性。本文将详细介绍Kong对插件的支持,不仅涵盖如何使用其生态系统中的丰富插件,还将深入探讨如何开发自定义插件,......
  • 19章9节:一步一步构建高效读取NHANES数据的自定义函数
    解决研究者在分析NHANES数据时,常常面临的繁琐数据下载和处理问题。本篇文章以R语言为工具,带领读者一步步拆解构建高效读取NHANES数据的自定义函数。从函数设计到代码实现,每一步都提供详尽的说明和示例,帮助大家深入理解如何灵活地自动化处理NHANES数据,从而显著提高数据处理的效......
  • 组件讲解-图形验证码使用(应对高并发场景)
    背景在如今越来越多人使用互联网程序的背景下,很多的项目也为了应对高并发而想出了各种应对方案,其中就包括防刷和并发缓解,不少公司为了验证不是机器人或者绑定手机号,用的是短发发送验证码的方法。这种现在基本上是通用的方案了但还有种情况,比如说热门的促销或者活动,使得大量......
  • nacos根据业务需要自定义命名空间
    创建个订单的命名空间 配置列表这里就有了   代码 浏览器访问但是,在实际使用的过程中,业务链是相互调用的,有的配置需要归类在同一命名空间下,下订单需要用户信息吧,或者把公共的配置放到一个单独的命名空间下去调用,向数据库,redis,Mq都可以抽成一个公共的配置。不......
  • Apifox 12月更新|接口的测试覆盖情况、测试场景支持修改记录、迭代分支能力升级、自定
    Apifox新版本上线啦!!!在快速迭代的开发流程中,接口测试工具的强大功能往往决定了项目的效率和质量。而Apifox在12月的更新中,再次引领潮流,推出了一系列重磅功能!测试覆盖情况分析、场景修改记录、自定义权限等功能的加入,为开发者和测试人员带来了新的工作方式。这些功能具体......
  • el-select组件改造成多选显示多个标签加数字标签的形式并且点击某个默认值不允许删除
     单独设置一个文件当做公共组件调用<template><main><el-selectref="select"v-model="values"multiplestyle="width:100%":placeholder="placeholder"@change="handleChang......
  • 动/静二维码/条形码,自定义批量生成/识别
    许多人在使用二维码时,常常会感到系统生成的二维码过于单调,缺乏个性。尤其是对于那些涉及个人品牌、市场营销或创意项目的人来说,搭配自己喜欢的图案、配色,甚至是gif等内容定制一个独特而吸引眼球的二维码会更具创意;分享一款动/静态二维码、条形码批量生成工具:批量二维码生......