组件实战系列——一、使用React实现一个Collapse组件
时间:2023-04-04 23:12:13
HTML5
编写组件的能力是衡量前端工程师水平的重要指标,无论是基础组件还是业务组件。作者还喜欢在空闲时间编写组件。为了帮助初学者手写React组件,也为了分享自己写组件的心得和想法,我决定开一个系列,即:组件实战系列,分享一些公共组件和组件的实现方法和实现技巧业务组件。作为本系列的第一篇文章,我来分享一下如何从零到一个实现一个折叠面板(Collapse)组件。Collapse基本UI将Collapse面板绘制为基本组件。可折叠区域,单击标题区域可折叠和展开内容区域。为了组件的美观,可以在标题右侧添加一个箭头图标,以便在展开和折叠时旋转它。为了降低环境搭建成本,实际使用了create-react-app环境。创建一个create-react-app开发环境非常简单。你只需要在安装node的系统中执行如下命令npxcreate-react-app项目名。名称必须是英文,create-react-app会自动为我们创建一个目录。项目创建完成后,在src目录下创建一个名为Collapse.jsx的文件,输入以下代码:(初学者可以选择复制)importReact,{useState}from"react";import"./style.css";constCollapsablePanel=()=>{const[isCollapsed,setIsCollapsed]=useState(true);consttogglePanel=()=>{setIsCollapsed((prevState)=>!prevState);};返回(25px"viewBox="0010241024"style={{color:'#6495ed'}}>
div>);};导出默认CollapsablePanel;239,239);padding-top:40vh;}.pannel{width:400px;text-align:left;}.heading{background-color:#bfa;边框顶部-lborder-top-right-radius:10px;颜色:#000;字体大小:20px;行高:20px;border:1pxsolidrgb(212,240,205);;显示:弹性;对齐项目:居中;证明内容:空格之间;cursor:pointer;}.content{字体大小:20px;背景:#fff;边框:1px实心#fff;边框顶部:无;填充:020px;颜色:#000000;overflow:hidden;}.contentInner{padding:20px0;}创建完以上两个文件后,在index.js中挂载创建的Collapse组件:(原代码无所谓,删除即可)importReactfrom'react';从'react-dom/client'导入ReactDOM;从'./components/Collapse'导入Collapse;constroot=ReactDOM.createRoot(document.getElementById('root'));root.render(<折叠/>);创建完成后,使用yarnstart命令启动应用,可以看到绘制的Collapse组件的外观:Collapse的基本UI绘制完成,回顾一下都做了哪些操作:首先是一个状态定义namedisCollapsed用于存储组件的展开和关闭状态,声明了一个名为togglePanel的方法,当用户点击标题时可以调用该方法实现面板的展开和关闭。然后,命名pannel、heading、contentdiv容器及其相关子容器的样式,并在style.css中设置容器的样式。组件中的ICON直接使用svg标签绘制,避免引入svg包导致组件体积变大。有很多方法可以在内容区域中实现动画。可以使用css的transition属性,也可以使用React生态中的各种动画库。在React生态中,有一个非常流行的动画库叫react-spring,它不仅功能强大,还支持hook调用。本文使用这个动画库来实现内容区域展开动画和按钮旋转动画。安装react-spring动画库yarnaddreact-spring安装完react-spring动画库后,可以定义一个方法让spring帮我们生成动画样式constpanelContentAnimatedStyle=useSpring({height:isCollapsed?0:200,});然后将内容区的标签名从
改为
(和useSpring一样,animated也是react-spring的一个对象),添加新建的panelContentAnimatedStyle:importReact,{useState}from"react";import{useSpring,animated}from"react-spring";import"./style.css";constCollapsablePanel=()=>{const[isCollapsed,setIsCollapsed]=useState(true);consttogglePanel=()=>{setIsCollapsed((prevState)=>!prevState);};constpanelContentAnimatedStyle=useSpring({height:isCollapsed?0:180,});返回(;/span>