V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhengfan2016
V2EX  ›  程序员

前端问题,假如为一个被很多地方用的基层组件加新功能,你会怎么做

  •  
  •   zhengfan2016 · 6 天前 · 1114 次点击

    假如有这样一个 NavBar 组件,被 50%以上的页面使用,下面 React 简略代码

    interface NavbarProps {
      BackAction?: ({ navigation, ...rest }) => JSX.Element
      Content?: ({ title, ...rest }) => JSX.Element
      Action?: ({ ...rest }) => JSX.Element
      title?: string
    }
    
    const Navbar = (props:NavbarProps)=>{
      const {BackAction = DefaultBackAction, Content = DefaultContent, Action = DefaultAction, title, } = props || {}
        return <div className="flex flex-row">
            <BackAction {...defaultBackActionProps}>
            <Content {...{...defaultContentProps,title}}/>
            <Action {...defaultActionProps}/>
      </div>
    }
    
    // demo
    
    return <Navbar title="title" />
    

    现在你要给这个组件的 title 加一个标题为当前播放音乐主题色的功能,但是只有 1 个页面会用到这个功能

    const color = useMusicThemeColor()
    

    请问你选择哪种方案?

    1.增加一个 isMusicTheme=true ,然后把 useMusicThemeColor 放在 NavBar 内部

     <Navbar title="title" isMusicTheme={true} />
    

    2.override Content ,把 useMusicThemeColor 放当前 page

    const color = useMusicThemeColor()
    
    ...
    
     <Navbar title="title" Content={({...rest,title})=>{
     	return <div {...rest} style={{color}}>
        	{title}
        </div>
     }} />
    
    11 条回复    2024-11-01 17:09:30 +08:00
    chenliangngng
        1
    chenliangngng  
       6 天前
    你可以把组件套一层壳,然后加上你要的功能,不当公共组件
    shintendo
        2
    shintendo  
       6 天前
    不能让 title 可以接受 JSX.Element 吗
    zhengfan2016
        3
    zhengfan2016  
    OP
       6 天前 via Android
    @shintendo 建议您阅读一下代码里 Content 组件,思考为什么 Content 组件会接收 Navbar 传过来的 title🤔
    shintendo
        4
    shintendo  
       6 天前
    @zhengfan2016 确实,没仔细看。我选择加个 titleStyle
    llwxi
        5
    llwxi  
       6 天前
    先用第二种实现,后续如果有两个组件使用到了,封装一个<MusicThemeColorText>{title}</MusicThemeColorText> 之类的组件?
    zhengfan2016
        6
    zhengfan2016  
    OP
       6 天前 via Android
    @llwxi 没错,这就是我想看到的答案。

    但是就我观察大部分前端喜欢用 1 的写法,特别是用 1 的写法来改我的代码,把整个组件改的很臃肿,让我很不爽。
    zb1141920796
        7
    zb1141920796  
       6 天前
    图省事就用 1 ,图可扩展性强一点就用 2,
    snowlee
        8
    snowlee  
       6 天前
    我会把 title 变成 reactNode, 相传啥就传啥
    lisongeee
        9
    lisongeee  
       6 天前
    没看懂你的操作,内部直接用 css 变量不行吗?

    然后直接在目标页面给 body 设置 css 变量,离开后移除此变量
    monologue520
        10
    monologue520  
       6 天前
    1.设 flag 控制,如果确定只有一个页面发生变化未尝不可,比较直观简单
    2.增加了组件拓展性,控制当前页的颜色,还有其他的页的 title 默认颜色,可以抽离一个 Title 组件维护 color 属性
    3.使用样式变量,比如 cssinjs 写法中「 const color = useMusicThemeColor()」传递一个 props 给 title 样式,最简单方便
    我个人选 3
    (用不着不爽,沟通一下就可以了)
    iOCZS
        11
    iOCZS  
       5 天前
    要是既可以简单传标题,又可以自定义标题内容就好了。vue slot 那套还是比较合适这个想法的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5348 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 07:36 · PVG 15:36 · LAX 23:36 · JFK 02:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.