【问题标题】:How to make nested Accordion?如何制作嵌套手风琴?
【发布时间】:2021-04-02 07:10:27
【问题描述】:

semantic_ui-react 库中存在组件Accordion。有一些例子,但我必须制作嵌套手风琴,它有结构:

-accordion:
    -sub_accordion1
    -sub_accordion2
    -sub_accordion3

我看到了带有面板的嵌套手风琴示例,但我不想将手风琴放入面板中。我试过了:

export default class AccordionExampleStandard extends Component {
  state = { activeIndex: 0 }

  handleClick = (e, titleProps) => {
    const { index } = titleProps
    const { activeIndex } = this.state
    const newIndex = activeIndex === index ? -1 : index

    this.setState({ activeIndex: newIndex })
  }

  render() {
    const { activeIndex } = this.state

    return (
      <Accordion>
        <Accordion.Title active={activeIndex === 0} index={0} onClick={this.handleClick}>
          <Icon name='dropdown' />
          What is a dog?
        </Accordion.Title>
        <Accordion.Content active={activeIndex === 0}>
          <Accordion.Title active={activeIndex === 1} index={1} onClick={this.handleClick}>
          <Icon name='dropdown' />
          What kinds of dogs are there?
        </Accordion.Title>
        <Accordion.Content active={activeIndex === 1}>
          Content1
        </Accordion.Content>

        <Accordion.Title active={activeIndex === 2} index={2} onClick={this.handleClick}>
          <Icon name='dropdown' />
          How do you acquire a dog?
        </Accordion.Title>
        <Accordion.Content active={activeIndex === 2}>
          Content2
        </Accordion.Content>
<Accordion.Title active={activeIndex === 3} index={3} onClick={this.handleClick}>
          <Icon name='dropdown' />
          What kinds of dogs are there?
        </Accordion.Title>
        <Accordion.Content active={activeIndex === 3}>
         Content3
        </Accordion.Content>
        </Accordion.Content>
      </Accordion>
    )
  }
}

它呈现组件,但我只能折叠主手风琴而不能折叠它的子项。如何执行此功能?

【问题讨论】:

    标签: javascript reactjs semantic-ui semantic-ui-react


    【解决方案1】:

    既然你提到你需要一个简单的解决方案,最好使用panels,因为它们似乎会自动操纵activeIndex,这是决定手风琴展开和折叠的主要属性。如果您要像上面那样自己做,您需要维护所有层次结构并通过调整onClick 处理程序中的状态来操纵自己。因此,如果您的用例不是自定义的或复杂的,您可以尝试以下方法。

    这是一个工作演示NESTED ACCORDION SEMANTIC UI

    import { Accordion } from 'semantic-ui-react';
    
    const AccordionContent = (content) => (
      <div className="indent">
        {content}
      </div>
    )
    
    const SubAccordion1Panels = [
      {
        title: 'Sub Accordion 11',
        content: { content: AccordionContent('11 Content'), key: '11-content'} ,
        key: 'sub-accordion-11'
      }, {
        title: 'Sub Accordion 12',
        content: { content: AccordionContent('12 Contents'), key: '12-content' },
        key: 'sub-accordion-12'
      }, {
        title: 'Sub Accordion 13',
        content: { content: AccordionContent('13 Contents'), key: '13-content' },
        key: 'sub-accordion-13'
      },
    ]
    
    const SubAccordion1Content = (
      <div className="indent">
        <Accordion.Accordion
          style={{marginLeft: "20px"}}
          className="no-padding"
          panels={SubAccordion1Panels}
        />
      </div>
    )
    
    const SubAccordionPanels = [
      {
        title: 'Sub Accordion 1',
        content: { content: SubAccordion1Content, key: 'sa1-content' },
        key: 'sub-accordion-1'
      }, {
        title: 'Sub Accordion 2',
        content: { content: AccordionContent('SA2 Content'), key: 'sa2-content' },
        key: 'sub-accordion-2'
      }, {
        title: 'Sub Accordion 3',
        content: { content: AccordionContent('SA3 Content'), key: 'sa3-content' },
        key: 'sub-accordion-3'
      }
    ]
    
    const SubAccordions = (
      <div className="indent">
        <Accordion.Accordion
          className="no-padding"
          panels={SubAccordionPanels}
        />
      </div>
    )
    
    const AccordionPanels = [
      { title: 'Accordion', content: { content: SubAccordions, key: 'sub-accordions' } },
    ]
    
    const AccordionExampleNested = () => (
      <Accordion
        defaultActiveIndex={0}
        panels={AccordionPanels}
      />
    )
    
    class App extends React.Component {
      render() {
        return (
          <AccordionExampleNested />
        )
      }
    }
    

    同样对于缩进,你需要覆盖默认的css

    .indent {
      margin-left: 1em;
    }
    
    .no-padding {
      padding: 0px !important;
      margin: 0px !important;
    }
    

    【讨论】:

      【解决方案2】:

      嵌套手风琴的正确制作方法:

      import React from 'react'
      import { Accordion } from 'semantic-ui-react'
      
      const level1Panels = [
        { title: 'Level 1A', content: 'Level 1A Contents' },
        { title: 'Level 1B', content: 'Level 1B Contents' },
      ]
      
      const Level1Content = (
        <div>
          Welcome to level 1
          <Accordion.Accordion panels={level1Panels} />
        </div>
      )
      
      const level2Panels = [
        { title: 'Level 2A', content: 'Level 2A Contents' },
        { title: 'Level 2B', content: 'Level 2B Contents' },
      ]
      
      const Level2Content = (
        <div>
          Welcome to level 2
          <Accordion.Accordion panels={level2Panels} />
        </div>
      )
      
      const rootPanels = [
        { title: 'Level 1', content: { content: Level1Content, key: 'content-1' } },
        { title: 'Level 2', content: { content: Level2Content, key: 'content-2'         } },
      ]
      
      const AccordionExampleNested = () => (
        <Accordion defaultActiveIndex={0} panels={rootPanels} styled />
      )
      
      export default AccordionExampleNested
      

      【讨论】:

      • 也许他错过了文档,因为建议的剪断作品开箱即用。
      • 我看到了这个 sn-p,我在回答中写道,我不需要制作面板手风琴。我需要做简单的,没有面板。在这个 sn-p 中,我们看到“panels={rootPanels}”
      【解决方案3】:

      这是我的版本。它是 Accordion 内部 Accordion 内部的递归 Accordion(无限)。

      它也在 CodePen https://codepen.io/codeman1293/pen/OJWppQM?editors=1111

      console.clear();
      const ButtonToolbar = ReactBootstrap.ButtonToolbar;
      const Button = ReactBootstrap.Button;
      const Jumbotron = ReactBootstrap.Jumbotron;
      const Accordion = ReactBootstrap.Accordion;
      const Panel = ReactBootstrap.Panel;
      
      var baseItems = [
        { id: 1, title: "Land", body: "", parentId: 0 },
        { id: 2, title: "Sea", body: "Submarine", parentId: 0 },
        {
          id: 8,
          title: "Air",
          body: "Helicopter<br />Aeroplanes<br />Drones",
          parentId: 0
        },
        { id: 3, title: "Cars", body: "", parentId: 1 },
        { id: 4, title: "Vans", body: "Transit<br />Sprinter", parentId: 1 },
        {
          id: 5,
          title: "Boats",
          body: "Speedboat<br />Fishing Boat<br />Dinghy",
          parentId: 2
        },
        { id: 6, title: "Petrol", body: "", parentId: 3 },
        { id: 7, title: "Automatic", body: "", parentId: 6 },
        { id: 9, title: "2.0L", body: "BMW X3<br />Mercedes GLC<br />Audi Q5", parentId: 7 }
      ];
      
      const App = React.createClass({
        render() {
          const RecursiveAccordion = ({ items, recurse = false }) => {
            return (
              <Accordion>
                {items.map((item, index) => {
                  var children = baseItems.filter((i) => {
                    return i.parentId === item.id;
                  });
      
                  var hasChildren = children.length > 0;
      
                  if (item.parentId === 0) {
                    return (
                      <Panel header={item.title} eventKey={index}>
                        {hasChildren && (
                          <div>
                            <RecursiveAccordion items={children} recurse={true} />
                            <div dangerouslySetInnerHTML={{ __html: item.body }} />
                          </div>
                        )}
                        {!hasChildren && (
                          <div dangerouslySetInnerHTML={{ __html: item.body }} />
                        )}
                      </Panel>
                    );
                  }
      
                  if (recurse) {
                    return (
                      <Panel header={item.title} eventKey={index}>
                        {hasChildren && (
                          <div>
                            <RecursiveAccordion items={children} recurse={true} />
                            <div dangerouslySetInnerHTML={{ __html: item.body }} />
                          </div>
                        )}
                        {!hasChildren && (
                          <div dangerouslySetInnerHTML={{ __html: item.body }} />
                        )}
                      </Panel>
                    );
                  }
                })}
              </Accordion>
            );
          };
      
          return <RecursiveAccordion items={baseItems} recurse={false} />;
        }
      });
      
      ReactDOM.render(<App />, document.getElementById("app"));
      

      【讨论】:

        猜你喜欢
        • 2014-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多