React组件 - 展开折叠组件之 react-collapse
前言:
今天给大家介绍一款 React 的展开折叠组件 react-collapse。
Ant Design、ElementUI 或者其它组件库也都有类似的组件,如果不使用这些组件,可以看一下这个组件。
效果如下:
React展开折叠组件 react-collapse
npm 地址:
react-collapse - npm (npmjs.com)
github 地址:
GitHub - nkbt/react-collapse
演示站点:
Webpack App (nkbt.github.io)
## 创建React 工程
话不多说,先创建个 react 工程。
这里使用 create-react-app 来创建。
npx create-react-app hello-react-collapse 复制代码
工程结构如下:
helloreactcollapse ├── README.md ├── node_modules │ ├── XXX ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt ├── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ └── setupTests.js └── yarn.lock 复制代码
安装 react-collapse。
yarn add react-collapse 复制代码
或者
npm install --save react-collapse 复制代码
个人喜欢用 yarn。
使用
Collapse组件构建的内容是默认加载的。
修改 App.js 的内容如下。
import { Collapse } from 'react-collapse'; function App() { return ( <> <br /> isOpened: true <br /> <Collapse isOpened={true}> <div>isOpened为true时的内容</div> </Collapse> <br /> isOpened: false <br /> <Collapse isOpened={false}> <div>isOpened为false时的内容</div> </Collapse> </> ); } export default App; 复制代码
isOpened 选项是打开的状态,true 为打开状态,false 为关闭状态。
通过控制台可以看到,isOpened 是 true 还是 false,编译后的内容都会加载,通过父级 div 的 aria-hidden 属性来控制是否显示。如果需要在不显示时卸载组件,可以使用 UnmountClosed 组件。
上面代码中的 Collapse 改为 UnmountClosed 。
import { UnmountClosed } from 'react-collapse'; function App() { return ( <> <br /> isOpened: true <br /> <UnmountClosed isOpened={true}> <div>isOpened为true时的内容</div> </UnmountClosed> <br /> isOpened: false <br /> <UnmountClosed isOpened={false}> <div>isOpened为false时的内容</div> </UnmountClosed> </> ); } export default App; 复制代码
可以看到 UnmountedClosed 的 isOpened 为 false 时,组件未被加载。
控制和访问。
原文链接:react-collapse/Accessible.js at master · nkbt/react-collapse (github.com)
样式文件App.css
body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } .app { padding: 20px; } .section { padding-top: 30px; } .subCollapse { padding: 20px; } .text { margin: 0; } .text p { margin: 0; padding: 10px; } .config { padding-bottom: 20px; } .label { padding-right: 20px; } .input { margin-right: 10px; margin-left: 10px; vertical-align: middle; } .blob { border-radius: 50vh; background: rgba(96, 125, 139, 0.6); } .log { padding: 0.5em; font-size: 0.6em; font-family: Menlo, Consolas, Monospaced, monospace; } .accessible ul { list-style: none; padding-inline-start: 0; } .ReactCollapse--collapse { max-width: 800px; border: 1px solid rgba(3, 169, 244, 0.3); border-radius: 10px; background-color: rgba(100, 255, 100, 0.1); transition: height 500ms; } .ReactCollapse--content { } 复制代码
主程序 App.js
import React, { useState, useCallback } from 'react'; import { Collapse } from 'react-collapse'; import './App.css'; function App() { const height = 100; const accessibilityIds = { checkbox: 'accessible-marker-example1', button: 'accessible-marker-example2' }; const [isCheckboxCollapseOpen, setIsCheckboxCollapseOpen] = useState(false); const [isButtonCollapseOpen, setIsButtonCollapseOpen] = useState(false); const onChange = useCallback( ({ target: { checked } }) => setIsCheckboxCollapseOpen(checked), [setIsCheckboxCollapseOpen] ); const onClick = useCallback( () => setIsButtonCollapseOpen(!isButtonCollapseOpen), [isButtonCollapseOpen] ); return ( <div className="app"> <div className="accessible"> <ul> <li> <div> <h6>With a checkbox</h6> <div className="config"> <label className="label"> Opened: <input className="input" type="checkbox" aria-controls={accessibilityIds.checkbox} checked={isCheckboxCollapseOpen} onChange={onChange} /> </label> </div> <Collapse isOpened={isCheckboxCollapseOpen}> <div style={{ height }} id={accessibilityIds.checkbox} className="blob" /> </Collapse> </div> </li> <li> <div> <h6>With a button</h6> <div className="config"> <button aria-controls={accessibilityIds.button} aria-expanded={isButtonCollapseOpen} onClick={onClick} type="button"> Reveal content </button> </div> <Collapse isOpened={isButtonCollapseOpen}> <div style={{ height }} id={accessibilityIds.button} className="blob" /> </Collapse> </div> </li> </ul> </div> </div> ); } export default App; 复制代码
效果如下:
可选项(属性)
isOpened: 必须
children: 必须,可包含一个或多个子组件,子组件可设置静态或者可变或者动态高度。
<Collapse isOpened={true}> <p>Paragraph of text</p> <p>Another paragraph is also OK</p> <p>Images and any other content are ok too</p> <img src="nyancat.gif" /> </Collapse> 复制代码
theme: 可给 ReactCollapse 组件创建的 div 设置 className。
<Collapse theme={{collapse: 'foo', content: 'bar'}}> <div>Customly animated container</div> </Collapse> 复制代码
默认样式为:
const theme = { collapse: 'ReactCollapse--collapse', content: 'ReactCollapse--content' } 复制代码
解析为下面的HTML:
<div class="ReactCollapse--collapse"> <div class="ReactCollapse--content"> {children} </div> </div> 复制代码
重要:这里不是 style 对象,是 CSS 的样式名。
onRest, onWork: 回调函数,动画完成后触发 onRest,动画开始时触发 onWork。
两个函数的参数:
const arg = { isFullyOpened: true || false, // `true` only when Collapse reached final height isFullyClosed: true || false, // `true` only when Collapse is fully closed and height is zero isOpened: true || false, // `true` if Collapse has any non-zero height containerHeight: 123, // current pixel height of Collapse container (changes until reaches `contentHeight`) contentHeight: 123 // determined height of supplied Content } 复制代码
<Collapse onRest={console.log} onWork={console.log}> <div>Container text</div> </Collapse> 复制代码
initialStyle: 初始样式
用于控制初始的组件样式。
checkTimeout:检查超时的时间,单位 ms,默认值为50ms.
在这个时间后检查高度来确认动画是否完成。
作者:bettersun
链接:https://juejin.cn/post/7021917145164415007