用React手写一个手风琴组件
时间:2023-03-28 01:01:04
HTML
知识点情感语法react语法css语法typescript类型语法效果来看看我们实现的效果图:结构分析根据上图,我们来分析一下,一个手风琴组件应该包含一个accordion容器组件和多个accordion子组件。因此,假设我们已经实现了所有的逻辑并编写了demo,代码应该如下所示:LoremipsumDolorsitamet根据上面的结构我们可以知道,首先容器组件Accordion会暴露一个defaultIndex属性,一个onItemClick事件。顾名思义,defaultIndex表示默认展开的子元素组件AccordionItem的索引,onItemClick表示点击各个子元素组件触发的事件。然后,我们可以看到子元素组件有一个label属性和一个index属性。显然,label代表当前子元素的标题,index代表当前子元素组件的索引值,我们的Loremipsum就是子元素的内容。根据这些分析,我们先实现AccordionItem组件。AccordionItem子组件首先,我们定义子组件的结构。函数组件写法如下:constAccordionItem=(props)=>{//returnelement};子元素组件分为三个部分,一个容器元素,一个标题元素和一个内容元素,所以我们可以这样写结构:
知道结构后,我们就知道props会有哪些属性。首先是index属性,类型为string或number,然后是属性isCollapsed,判断内容是否展开,类型为布尔值。其次,我们还有渲染标题的属性标签。它应该是一个类型为ReactNode的React节点。同样,还有一个content属性是children,type也应该是ReactNode。最后,我们要暴露的事件方法是handleClick,它的类型应该是方法,所以我们可以定义如下接口:interfaceAccordionItemType{index:string|数字;标签:字符串;已折叠:布尔值;//SyntheticEvent表示react合成事件对象的类型handleClick(e:SyntheticEvent):void;children:ReactNode;}接口定义好后,我们再获取接口中的值(使用对象解构),这些值是可选的,即:const{label,isCollapsed,handleClick,children}=props;此时我们的AccordionItem子组件应该如下:constAccordionItem=(props:Partial
)=>{const{label,isCollapsed,handleClick,children}=props;返回(?'collapsed':'expanded'}`}>{children} );};这里我们可以使用emotion/css来写css类命名样式,代码如下:constbaseStyle=css`line-height:1.5715;`;constAccordionItemContainer=css`border-bottom:1pxsolid#d9d9d9;`;constAccordionItemHeader=cx(baseStyle,css`position:relative;display:flex;flex-wrap:nowrap;align-items:flex-start;padding:12px16px;color:rgba(0,0,0,0.85);cursor:pointer;transition:all0.3s,visibility0s;box-sizing:border-box;`,);constAccordionItemContent=CSS颜色:#000000d9;背景色:#fff;博rder-top:1pxsolid#d9d9d9;过渡:所有0.3秒缓入缓出;填充:16px;&.collapsed{显示:无;}&.expanded{显示:块;}`;上面的css后面跟着一个template字符串后面跟着css样式就是emotion/css语法,cx就是组合样式。款式都是常规款,没什么好说的。这里有一个难点,就是display:none和display:block没有过渡效果,所以可以用Visibility:hidden和opacity:0来代替,但是这里为了简单起见,没有考虑动画效果,所以这个问题先不管了,后面有时间再优化。至此,这个子组件就完成了,也就是说我们的手风琴组件已经完成了一半。接下来我们看一下容器组件Accordion的写法。首先我们来写一下Accordion容器组件的结构:constAccordion=(props)=>{//后续代码};让我们分析一下需要传递给Accordion组件的属性。显然有defaultIndex、onItemClick和children,所以我们可以定义如下接口:interfaceAccordionType{defaultIndex:number|细绳;onItemClick(key:number|string):void;children:JSX.Element[];}注意这里的children应该不是ReactNode,而是JSX.Element元素数组,这是为什么呢,这个问题我们后面再解释。既然我们知道了道具的属性,我们就可以获取它们了。代码如下:constAccordion=(props:Partial