zoukankan      html  css  js  c++  java
  • VUE实现Studio管理后台(五):手风琴式折叠组件(Accordion)

    作为一个有目标的人(目标是做一个好用的Bootstrap可视化编辑器,第一个版本已经实现,演示地址:https://vular.cn/rxeditor/,代码地址:https://github.com/vularsoft/rxeditor),工作比较积极,思维也比较活跃,睡眠相对较少。今早6:30就起床了,吃早饭前,实现了一个手风琴式折叠组件,具体效果如下:

    一般情况,这样的控件有两种表现形式:

    1、排他展开,也就是一次只有一个项目展开,其它闭合,类似QQ的好友分组。

    2、随意展开,不拍它,可以同时展开多个

    只实现第二种方式,相对比较容易,每个子项目控制自己的状态就可以,不用跟其它项目交互。我的目标式做一个控件,两种方式都支持,通过属性参数multiple确定是否可以同时展开多个。

    添加新的文件跟目录:

    跟上次实现Tabs控件一样,有一个通用的子组件:CollapsibleItem,基于这个组件实现折叠组件:SimpleAccordion。如果以后像实现其它风格的折叠组件,可以共用CollapsibleItem组件。根据我个人的习惯,首先设想这个组件的使用方式,应该是这样:

    <SimpleAccordion :multiple='true'> 
        <CollapsibleItem>
        <template #heading>标题1</template>
        <template #body>内容1....</template>
        </CollapsibleItem>
        <CollapsibleItem>
        <template #heading>标题2</template>
        <template #body>内容2....</template>
        </CollapsibleItem>
    </SimpleAccordion>

    按照这样的需求,先写SimpleAccordion 的模板代码:

    <template>
      <div class="simple-accordion">
        <slot></slot>
      </div>
    </template>

    看起来非常简单,接下来再写CollapsibleItem的模板代码:

    <template>
      <div class="collapsible-item" :class="!isActive ? 'item-collapse' : ''">
        <div class="item-heading" @click="click">
          <slot name="heading"></slot>
        </div>
        <div class="item-body">
          <slot name="body"></slot>
        </div>
      </div>
    </template>

    两个slot分别对应每个折叠项的标题跟内容。如果该项被折叠的话,那么放置css class: item-collapse。标题容器DIV接收click事件。脚本代码:

    export default {
      name: 'CollapsibleItem',
      props: {
        selected: { default: false}
      },
      data() {
        return {
          isActive: false
        };
      },
    
      methods: {
        click() {
          this.$emit('itemClick', this)
        }
      },
        
      mounted() {
        this.isActive = this.selected;
      }
    }

    其他部分跟tabs控件一样,并不难理解,需要注意的是click方法,这个方法接收到鼠标点击事件后,在分发给它的父组件,本例中父组件就是SimpleAccordion。

    再看SimpleAccordion的脚本代码:

    export default {
      name: 'SimpleAccordion',
      props: {
        multiple: { default: false}
      },
      data() {
        return {items: [] }
      },
      created() {
        this.items = this.$children
      },
      mounted () {
        this.items.forEach(item=>{
          item.$on('itemClick', this.itemClick)
        })
      },
      methods: {
        itemClick(clickedItem) {
          clickedItem.isActive = !clickedItem.isActive
          if(!this.multiple){
            this.items.forEach(item => {
              if(item !== clickedItem){
                item.isActive = false
              }
            })
          }
        }
      }
    }

    在mounted的方法中,在所有的子项上注册事件“itemClick”,这个事件在子组件中分发。事件处理方法itemClick根据需要,激活相应的项目。

    这样这个控件就完成了,对应的CSS:

    .simple-accordion{
        flex: 1;
        width: 100%;
        overflow: auto;
        height: 0;
        display: flex;
        flex-flow: column;
        margin-top: 2px;
      }
      .simple-accordion .collapsible-item{
        display: flex;
        flex-flow: column;
        width: 100%;
      }
      .simple-accordion .item-heading{
        display: flex;
        flex-flow: row;
        flex-wrap: wrap;
        align-items: center;
        font-size: 12px;
        color:#f0f1ef;
        padding-left: 10px;
        padding-top:10px;
        padding-bottom:10px;
        padding-right:20px;
        position: relative;
        border-top:#484848 solid 1px;
        border-bottom:#282828 solid 1px;
        cursor: default;
      }
    
      .simple-accordion .item-heading:hover{
        background: #383838;
      }
    
      .simple-accordion .collapsible-item .item-heading span{
        margin-right: 5px;
      }
    
      .simple-accordion .collapsible-item .item-heading small{
        white-space:nowrap;
        color: #aaa;
        font-size: 11px;
      }
    
    
      .simple-accordion .collapsible-item .item-heading::after{
        position: absolute;
        content: '';
        width: 0; 
        height: 0;
        top: calc(50% -1px);
        right: 19px;
        border-width: 4px;
        border-style: solid;
        border-color: #f0f1ef transparent transparent  transparent;
      }
    
      .simple-accordion .item-body{
        border-top:#282828 solid 1px;
        padding: 10px;
      }
    
      .simple-accordion .collapsible-item.item-collapse .item-heading::after{
        position: absolute;
        content: '';
        width: 0; 
        height: 0;
        top: calc(50% -1px);
        right: 17px;
        border-width: 4px;
        border-style: solid;
        border-color:transparent transparent  transparent #f0f1ef;
      }
    
      .simple-accordion .collapsible-item.item-collapse .item-body{
        display: none;
      }
    
      .simple-accordion .item-body .element{
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
        cursor: move;
        color: #c2c2c2;
        font-size: 13px;
        padding:5px 5px;
        margin:3px;
        display: flex;
        flex-flow: row;
        justify-content: space-between;
        align-items: center;
      }
    
      .simple-accordion .item-body .element:hover{
        color: #75b325;
        box-shadow: 2px 2px 5px 0px rgba(0, 0, 0, 0.4); 
      }
    View Code

    做这个控件时,碰到了一些细小问题,调整了项目的CSS,其中比较重要的有以下几点:

    1、窗口拖动时,拖动把手会被挤没,在把手的CCS中添加:

      flex-shrink: 0;

    这样可以避免handle被挤小挤没

    2、SimpleAccordion宽度设为100%,他会把父组件WidgetTabs撑大,失去拖放效果。后来追踪到是WidgetTabs的父元素没有设置宽度,从widgettabs到固定宽度的父容器,全部设置宽度100%:

    .left-inner{
    
      width:100%;
    
    }
    
    .top-area{
    
      width:100%;
    
    }

    3、用于显示展开闭合的箭头,使用css绘制,具体绘制原理,请自行百度。

    整个项目在这个历史节点的代码,请到我的Github上查看:https://github.com/vularsoft/studio-ui

    找到该历史节点的方法:

    RXEditor是一个Boostrap代码可视化编辑工具,本系列记录了该软件的开发过程,有问题的朋友请在ithub上给我留言。

  • 相关阅读:
    VMware设置共享文件夹
    非奇异阵
    ICP算法使用遇到的问题
    osgEarth编译的一些问题
    [OpenCV](1)安装与测试
    [PCL]1 PCL点云库安装
    【转载】:【C++跨平台系列】解决STL的max()与numeric_limits::max()和VC6 min/max 宏冲突问题
    matlab将多条曲线绘制在一起
    C++问题
    SLAM学习笔记(3)相关概念
  • 原文地址:https://www.cnblogs.com/idlewater/p/12425091.html
Copyright © 2011-2022 走看看