news 2026/5/16 21:24:14

50天50个小项目 (React19 + Tailwindcss V4) ✨| RandomChoicePicker(标签生成)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
50天50个小项目 (React19 + Tailwindcss V4) ✨| RandomChoicePicker(标签生成)

📅 我们继续 50 个小项目挑战!——RandomChoicePicker组件

仓库地址:https://gitee.com/hhm-hhm/50days50projects.git

构建一个简单的标签输入组件。用户可以在文本框中输入多个选项,并通过逗号分隔,组件会自动将其拆分成可视化的“标签”展示出来。

🌀 组件目标

  • 接收用户输入的一段文本。
  • 使用逗号,分割输入内容。
  • 动态渲染为一组“标签”(Tag)。
  • 使用 TailwindCSS 快速构建美观现代的 UI 界面。
  • 提供清晰的交互反馈。

🔧RandomChoicePicker.tsx 组件实现

import React, { useState, useEffect } from 'react' const RandomChoicePicker: React.FC = () => { const [textareaText, setTextareaText] = useState<string>('') const [tagList, setTagList] = useState<string[]>([]) // 每当 textareaText 变化时,自动分割标签 useEffect(() => { const tags = textareaText .split(',') .map((item) => item.trim()) // 去除前后空格 .filter((item) => item !== '') // 过滤空字符串 setTagList(tags) }, [textareaText]) return ( <div className="flex h-screen items-center justify-center"> <div className="w-full max-w-2xl rounded-2xl bg-gray-400 p-8 shadow-lg"> <h3 className="font-mono text-2xl text-gray-800"> Enter all of the choices divided by a comma (',').(输入所有选项,并用英文逗号,分隔) <br /> Press enter when you're done </h3> <textarea className="my-4 h-36 w-full resize-none rounded-lg bg-gray-200 p-4 text-gray-800 placeholder-gray-500 focus:ring-2 focus:ring-blue-300 focus:outline-none" placeholder="Enter choices here..." value={textareaText} onChange={(e) => setTextareaText(e.target.value)} /> {tagList.length > 0 && ( <div className="mt-4 flex flex-wrap gap-2"> {tagList.map((item, index) => ( <div key={`${item}-${index}`} // 使用 index 避免重复 key(因 item 可能重复) className="rounded-2xl bg-amber-200 px-3 py-1 text-sm font-medium text-gray-800"> {item} </div> ))} </div> )} </div> <div className="absolute right-20 bottom-10 text-red-500">CSDN@Hao_Harrision</div> </div> ) } export default RandomChoicePicker

✅ 关键实现说明

功能Vue 实现React + TS 实现
双向绑定文本域v-model="textareaText"value + onChange控制
自动分割逗号内容watchEffect+splitTag()useEffect监听textareaText
标签渲染v-for="item in tagList"{tagList.map(...)}
空值过滤无(原逻辑会保留空字符串)✅ 添加.trim()filter(item !== '')提升体验

🛠️ 改进细节

  1. 去重与清理

    • 使用.trim()去除每个选项前后的空格(如" apple ""apple")。
    • 过滤掉空字符串,避免显示空白标签。
  2. Key 策略

    • 因用户可能输入重复项(如"A, A, B"),不能仅用item作 key。
    • 改为key={item−{index}}确保唯一性,避免 React 警告。
  3. UI/UX 增强

    • 添加resize-none禁止手动调整 textarea 大小(保持布局稳定)。
    • 添加focus:ring提升交互反馈。
    • 使用flex-wrap确保标签在小屏换行。
    • 添加bg-gray-100背景色提升整体可读性。
  4. 类型安全

    • textareaText: string
    • tagList: string[]

📌 注意事项

  • 此组件目前只负责输入和解析,不包含“随机选择”逻辑(如抽一个标签)。如果你后续需要“Pick Random”功能,可以在此基础上加一个按钮调用:
    const pickRandom = () => { if (tagList.length > 0) { const random = tagList[Math.floor(Math.random() * tagList.length)]; alert(`Selected: ${random}`); } };

🎨 TailwindCSS 样式重点讲解

🎯 TailwindCSS 样式说明
类名作用
flex,items-center,justify-center居中布局整个容器
h-screen容器高度为视口全高
rounded-2xl圆角大小为 1rem
bg-gray-400bg-gray-200bg-amber-200设置背景颜色
p-8,p-4,p-1不同层级的内边距
my-4上下外边距为 1rem
w-full宽度为 100%
h-36高度为 9rem
text-2xl字体大小为 1.5rem
font-mono使用等宽字体
gap-2flex 子元素之间间隔为 0.5rem
h-8高度为 2rem
rounded-2xl圆角为 1rem

这些类名帮助我们快速构建出一个居中的响应式布局,并确保视觉上的一致性和美观性。

🦌 路由组件 + 常量定义

router/index.tsxchildren数组中添加子路由

{ path: '/', element: <App />, children: [ ... { path: '/RandomChoicePicker', lazy: () =>import('@/projects/RandomChoicePicker.tsx').then((mod) => ({ Component: mod.default, })), }, ], },

constants/index.tsx 添加组件预览常量

import demo13Imgfrom '@/assets/pic-demo/demo-13.png' 省略部分.... export const projectList: ProjectItem[] = [ 省略部分.... { id: 13, title: 'Random Choice Picker', image: demo13Img, link: 'RandomChoicePicker', }, ]

🚀 小结

作为表单组件的一部分,用于收集用户输入的多项数据。

📅 明日预告: 我们将完成AnimatedNavigation组件,一个非常有意思的动画的导航组件!🚀


原文链接:https://blog.csdn.net/qq_44808710/article/details/148615314

每天造一个轮子,码力暴涨不是梦!🚀

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/7 18:04:13

STM32 驱动 MSP20 传感器 + OLED 显示教程

本文将详细讲解如何使用 STM32 单片机驱动 MSP20 血压 / 气压 / 压力传感器&#xff0c;并将采集到的压力数据实时显示在 OLED 屏幕上。教程采用STM32F103C8T6&#xff08;最小系统板&#xff09;、I2C 接口 OLED&#xff08;0.96 寸&#xff09;、MSP20 传感器&#xff0c;代码…

作者头像 李华
网站建设 2026/5/15 6:20:49

2026年全套Java面试合集,终于整理完了!

一、Java并发面试题 1、 ThreadLocal 1.1 谈谈你对ThreadLocal的理解&#xff1f; ThreadLocal的作用主要是做数据隔离&#xff0c;填充的数据只属于当前线程&#xff0c;变量的数据对别的线程而言是相对隔离的。它不是针对程序的全局变量&#xff0c;只是针对当前线程的全局…

作者头像 李华
网站建设 2026/5/14 10:53:56

数字孪生技术有哪些实际应用?

数字孪生&#xff0c;作为一种将物理实体或系统在其全生命周期内&#xff0c;通过数据驱动在虚拟空间中构建动态镜像的技术&#xff0c;正深刻改变着众多行业的运作模式。它不仅是一个简单的三维模型&#xff0c;更是一个集成了实时数据、模拟分析、预测决策能力的综合系统。随…

作者头像 李华
网站建设 2026/5/12 8:49:35

我为什么要离开家乡,来北京打拼?(说说我自己的故事...)

建了一个新号&#xff1a;1. 讲职场与第二曲线&#xff1b;2. 聊自己的故事&#xff0c;内心的感悟。谢谢大家&#xff0c;听我的故事。希望对大伙也有帮助。最近做了一个新产品&#xff1a;70天&#xff0c;每天30分钟&#xff0c;短视频行动营&#xff08;第二曲线最佳选择&a…

作者头像 李华
网站建设 2026/5/14 19:50:01

如何在 LTspice放置 .op data 并能够设置显示的小数点个数?

简 介&#xff1a; 本文介绍了在LTspice中格式化.op数据标签的方法。通过使用round函数可以设置显示数据的小数点位数&#xff0c;使仿真结果更加简洁直观。具体操作是右键点击.op数据标签&#xff0c;使用round函数调整小数位数。这种方法能有效优化电路静态偏置量的显示效果&…

作者头像 李华