在本文中,我们将利用 React.js 的全部功能来创建手风琴组件 - 一种经常在 Web 和移动应用程序中使用的用户界面设备,以用户友好且节省空间的方式排列和显示内容。
为了充分了解本文,您需要具备以下条件:
-
安装了 Node.js。您可以从官方网站下载并安装Node.js ,并在此处了解如何安装Node.js。
-
对 HTML、CSS 和 JavaScript 有基本了解。
-
React.js 的基础知识。
-
代码编辑器(最好是Visual Studio Code)。
项目设置 {#projectsetup}
我们将使用 React.js 来创建我们的手风琴组件。要使用 React.js,我们需要创建一个 React 环境,我们将通过命令提示符来完成此操作。
打开终端应用程序并导航到桌面(或其他位置,如果您愿意)。然后运行以下命令来创建您的 React 应用程序:
npx create-react-app accordion-component
安装软件包后,我们将看到如下图所示的内容。
现在,如果我们检查项目文件夹,我们将找到一个/accordion-component/
以安装的所有软件包命名的文件夹。
文件夹结构 {#folderstructure}
/accordion-component/
在代码编辑器中打开新文件夹。还要在浏览器中打开 React 应用程序。我们可以通过代码编辑器中的内置终端输入命令以npm run start
在浏览器上运行应用程序来执行此操作。
注意:如果您使用的是 Visual Studio,则可以使用快捷方式 ( ctrl++ shift)`打开终端。如果您的代码编辑器没有内置终端的功能,您可以只在命令提示符应用程序中运行命令。)
接下来让我们编辑那些会阻碍应用程序执行的不必要的文件和代码块。首先,打开并删除包含在类名为 的元素App.js
中的整个标头元素,因此我们现在有一个空元素。然后打开并删除这两个文件的内容。(如果您再次查看该网页,您会发现它现在是空白的,这正是我们现在想要的。)<div>``App``<div>``App.css``index.css
接下来,我们在文件夹目录/AccordionComponent/
下创建一个名为 的新文件夹/src/
。在 /AccordionComponent/
文件夹中,创建一个名为Accordion.js
组件的文件和另一个名为AccordionData.js
存储用于手风琴的文本的文件。然后转到该App.js
文件并导入该Accordion.js
文件。导入文件后,我们将其渲染在<div>
元素内,如下所示:
import './App.css';
import Accordion from './AccordionComponent/Accordion';
function App() {
return (
<div className="App">
<Accordion />
</div>
);
}
export default App;
完成后,转到该Accordion.js
文件并创建一个名为 的组件AccordionItem
。在return
关键字内部,我们将创建一个以"Accordion"作为内容 ( <h1>Accordion</h1>
) 的标题元素,并在其下方创建另一个名为 的组件Accordion
。完成此操作后,我们将AccordionItem
在 main 的内部渲染我们的组件Accordion
,确保渲染的组件包装在<div>
类名为 的元素中container
。然后我们导出主要Accordion
组件。现在我们有这样的东西:
import React from 'react';
// accordionitem component
const AccordionItem = () => {
return(
<h1>Accordion</h1>
)
}
// main Accordion component
const Accordion = () => {
return (
<div>
<AccordionItem />
</div>
)
}
export default Accordion;
如果我们查看网页,我们会在屏幕上看到标题。
接下来,我们将创建一个对象数组,其中包含AccordionData.js
文件内的问题和答案文本。通过将手风琴数据存储在对象数组中,我们确保数据是动态存储的并且手风琴组件是可重用的。以下是手风琴数据。您可以将其直接复制并粘贴到您的AccordionData.js
文件中:
const data = [
{
question: 'What are accordion components?',
answer: 'Accordion components are user interface elements used for organizing and presenting content in a collapsible manner. They typically consist of a header, content, and an expand/collapse action.' ,
},
{
question: 'What are they used for?',
answer: 'They are commonly employed in various contexts, including FAQs, product descriptions, navigation menus, settings panels, and data tables, to save screen space and provide a structured and user-friendly interface for presenting information or options.',
},
{
question: 'Accordion as a musical instrument',
answer: 'The accordion is a musical instrument with a keyboard and bellows. It produces sound by air passing over reeds when the player expands or compresses the bellows, used in various music genres.',
},
{
question: 'Can I create an accordion component with a different framework?',
answer: 'Yes of course, it is very possible to create an accordion component with another framework.',
}
];
export default data;
在上面的代码中,我们有一个对象数组,其中包含将在手风琴组件中显示的数据。该question
属性包含问题或标题文本,而answer
属性包含单击或展开问题时显示的答案或内容。确保导入Accordion.js
文件中的组件。这就是文件的全部内容AccordionData.js
。
手风琴组件布局 {#accordioncomponentlayout}
让我们创建手风琴组件的布局。
我们首先必须react-icons
从 npm 注册表安装到我们的项目:
npm install react-icons
我们还需要导入useState
和useRef
挂钩。我们可以通过将其粘贴到文件顶部来做到这一点:
import React, { useRef, useState } from 'react'
HTML 结构将在组件内部呈现AccordionItem
。我们将四个 props 传递给AccordionItem component
: question
, answer
, isOpen
, 和onClick
。
让我们分解这些道具,看看它们的用途:
-
question
。此道具代表手风琴项目的问题部分的文本或内容。 -
answer
。此道具表示手风琴项目的答案部分的文本或内容。 -
isOpen
。该属性是一个布尔值,指示手风琴项目当前是打开(展开)还是关闭(折叠)。它控制答案内容是可见还是隐藏。 -
onClick
。此道具是一个回调函数,当用户与手风琴项目交互时执行。它通常用于isOpen
当用户单击项目以展开或折叠它时切换状态。
AccordionComponent 主体 {#theaccordioncomponentbody}
在文件顶部Accordion.js
,确保从react-icons包中导入箭头图标,如下所示:
import { RiArrowDropDownLine } from 'react-icons/ri'
这将是单个手风琴项目的结构:
const AccordionItem = ({ question, answer, isOpen, onClick }) => {
const contentHeight = useRef()
return(
<div className="wrapper" >
<button className={`question-container ${isOpen ? 'active' : ''}`} onClick={onClick} >
<p className='question-content'>{question}</p>
<RiArrowDropDownLine className={`arrow ${isOpen ? 'active' : ''}`} />
</button>
<div ref={contentHeight} className="answer-container" style={
isOpen
? { height: contentHeight.current.scrollHeight }
: { height: "0px" }
}>
<p className="answer-content">{answer}</p>
</div>
</div>
)}
在此代码片段中,手风琴项位于<div>
具有类 name 的父级中wrapper
。这种结构允许以可折叠的方式显示问题及其答案。
我们将useRef
钩子存储在一个名为 的变量中contentHeight
,以便可以将其传递到元素ref
的属性中answer-container
。我们这样做是为了能够根据答案内容的滚动高度动态调整容器的高度。
让我们分解一下代码结构。
-
按钮元素(
<button>
)。这是手风琴项目的交互部分,用户单击它可以切换答案的可见性。它有一个类名question-container
。active
如果prop 为 true,则类名有条件地设置为isOpen
,用于在答案打开时以不同的方式设置按钮的样式。 -
提问内容。问题内容由
<p>
带有 class 的元素组成question-content
。问题的文本取自问题道具。 -
箭头图标(
<RiArrowDropDownLine />
)。用于切换的箭头图标显示在问题的右侧。类名有条件地设置为active
如果isOpen
prop 为 true,则可用于在答案打开时以不同方式旋转或设置箭头样式。 -
回答div。后面
<button>
是一个<div>
带有类名的元素answer-container
。该 div 有一个ref
设置为contentHeight
变量的属性,允许它测量其scrollHeight
. style 属性用于根据项目是打开还是关闭动态设置此容器的高度。当isOpen
为 true 时,它将具有等于其内容的高度scrollHeight
,使答案可见。当isOpen
为 false 时,高度为0px
,隐藏答案内容。 -
回答内容。答案内容由
<p>
class 元素组成answer-content
。答案的文本取自answer prop。
设计我们的手风琴组件 {#stylingouraccordioncomponent}
现在我们已经完成了标记,让我们设计我们的手风琴组件的样式。样式可以在下面的代码块中找到:
* {
padding: 0;
margin: 0;
box-sizing: border-box;}body {
background-color: #f2f2f2;}.container {
max-width: 650px;
width: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);}.wrapper {
border-bottom: 1px solid black;
overflow: hidden;}.wrapper .question-container {
width: 100%;
text-align: left;
padding: 20px 10px;
display: flex;
align-items: center;
justify-content: space-between;
font-weight: 500;
font-size: 20px;
background: transparent;
border: none;
cursor: pointer;}.question-container.active {
color: #1db954;
background-image: linear-gradient(90deg,transparent,rgba(0,0,0,0.04),transparent);}.wrapper .question-container:hover {
background-image: linear-gradient(90deg,transparent,rgba(0,0,0,0.04),transparent);}.wrapper .arrow {
font-size: 2rem;
transition: .5s ease-in-out;}.arrow.active {
rotate: 180deg;
color: #1db954;}.wrapper .answer-container {
padding: 0 1rem;
transition: height .7s ease-in-out;}.wrapper .answer-content {
padding: 1rem 0;
font-size: 20px;
font-style: italic;}
通过上面的样式,我们现在有了accordionItem
. 现在让我们从文件中导入数据AccordionData
并声明手风琴组件的基本功能。我们在主要Accordion
组件内执行此操作。
手风琴主要部件结构 {#mainaccordioncomponentstructure}
下面的代码定义了名为 的功能组件Accordion
:
const Accordion = () => {
const [activeIndex, setActiveIndex] = useState(null);
const handleItemClick = (index) => {
setActiveIndex((prevIndex) => (prevIndex === index ? null : index));
};
return (
<div className='container'>
{data.map((item, index) => (
<AccordionItem
key={index}
question={item.question}
answer={item.answer}
isOpen={activeIndex === index}
onClick={() => handleItemClick(index)}
/>
))}
</div>
)
};
export default Accordion;
该组件的目的是创建显示项目列表的手风琴式界面,每个项目都包含一个问题及其相应的答案。用户可以单击问题来展开或折叠其答案。让我们逐步分解代码。
-
const [activeIndex, setActiveIndex] = useState(null);
。该行使用钩子设置一段组件状态useState
。activeIndex
表示当前活动(打开)的手风琴项目的索引,或者null
如果没有项目打开。setActiveIndex
是用于更新此状态的函数。 -
const handleItemClick = (index) => { ... }
。该handleItemClick
函数负责处理手风琴项目上的点击。它需要一个index
参数,该参数表示被单击的项目的索引。在函数内部,
setActiveIndex
使用切换状态的函数进行调用activeIndex
。如果单击的项目的索引 (index
) 与当前活动索引 (prevIndex
) 匹配,则它设置activeIndex
为null
,从而有效地关闭该项目。如果它们不匹配,则会设置activeIndex
为单击项目的索引,然后打开它。这种方法确保一次只能打开一个手风琴项目,因为如果我们打开一个手风琴项目,它会关闭任何先前打开的手风琴项目。
-
声明
return
。该组件返回定义 Accordion 接口结构的 JSX。最外面<div>
的类名container
是所有折叠项目的容器。 -
{data.map((item, index) => ( ... ))}
。data
此代码映射从文件中检索到的名为的数组AccordionData.js
。对于data
数组中的每个项目,它都会呈现一个AccordionItem
组件。该key
属性设置index
为确保每个项目都有一个唯一的键以进行 React 的渲染优化。question
、answer
、isOpen
和属性onClick
将传递给AccordionItem
组件。和属性包含要为每个项目显示question
的answer
文本。如果项目的索引与当前活动的索引匹配(表明它应该打开),则将 prop 设置为,并且该propisOpen
是一个回调函数,当单击该项目时会触发该函数。true``onClick``handleItemClick
-
export default Accordion;
。该行导出Accordion
组件,以便可以在应用程序的其他部分导入和使用它。我们之前已经在文件中渲染了该组件App.js
。
总之,该Accordion
组件管理当前活动的折叠项的状态,并使用此状态来控制打开和关闭行为。AccordionItem
它根据获得的数据动态生成组件列表,允许用户通过单击每个问题来与手风琴界面交互以显示或隐藏他们的答案。
我们的成品 {#ourfinishedproduct}
我们现在有了一个漂亮且功能齐全的手风琴组件!本教程的完整源代码可在CodeSandbox【https://codesandbox.io/s/accordion-component-8cfpvx】上找到。
结论 {#conclusion}
在本文中,我们研究了如何利用 React.js 创建动态且用户友好的手风琴组件。手风琴是一种常见的用户界面元素,用于整齐地组织和显示内容。
我们首先创建一个 React 项目,组织组件,并为其设计最终外观的样式。我们深入了解了系统的内部运作,包括状态管理和处理用户交互。此外,为了可扩展性和可重用性,我们涵盖了将手风琴数据存储在另一个文件中的概念。
希望您现在对如何使用 React.js 开发功能丰富的折叠组件有了深入的了解。快乐编码!