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);
  }

做这个控件时,碰到了一些细小问题,调整了项目的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上给我留言。

原文地址:https://www.cnblogs.com/idlewater/p/12425091.html

时间: 2024-10-07 09:34:16

VUE实现Studio管理后台(五):手风琴式折叠组件(Accordion)的相关文章

VUE实现Studio管理后台(九):开关(Switch)控件,输入框input系列

接下来几篇作文,会介绍用到的输入框系列,今天会介绍组普通的调用方式,因为RXEditor要求复杂的输入功能,后面的例子会用VUE的component动态调用,就没有今天的这么直观了,控件的实现原理都一样,只是调用方式的区别,今天的例子的调用代码为了写作文特殊制作的,写完作文还要恢复回去.开关控件(Switch)的实现效果: 给组件取个好听的名字,叫RxSwitch吧.调用代码: <RxSwitch :onValue = "'on-value'" :offValue = "

Vue Element+Node.js开发企业通用管理后台系统

第1章 课程介绍介绍项目背景.达到的目标.技术栈和功能演示 第2章 课程分析课程分析 第3章 Vue进阶(上)对Vue的进阶知识进行讲解,包括$emit和$on.directive指令.组件化.Vue插件等相关内容. 第4章 Vue进阶(下)对Vue的进阶知识进行讲解,包括组件通信.过滤器.监听器.Vue2.6重要新特性等相关内容. 第5章 Element-UI入门对Element-UI的内容进行讲解,包括如何搭建Element-UI使用环境,如何使用插件快速集成Element-UI,并通过el

Vue Element+Node.js开发企业通用管理后台系统完整教程

资源获取链接:点击获取完整教程 Vue Element+Node.js开发企业通用管理后台系统 综合应用 Vue 和 Node 技术,基于 Element-UI 组件库搭建“小慕读书“的管理后台,通过 Node 实现了电子书上传和解析功能以及权限管理.课程对 Vue 和 Node 有较为深入的应用,不仅会教大家如何实现功能,更会讲解技术背后的原理,帮助大家做到举一反三.课程面向中高级开发者,提供完整的开发文档和API支持,让大家可以快速上手实战 准备阶段 准备工作 Nginx 服务器MySQL

管理后台的登录功能-重新思考

每个网站.APP都几乎必然有其管理后台,其中管理的内容则是公司的核心技术财产.而登录模块则是这扇大门,其安全的重要性可想而知.我们知道,功能越多,安全性就会越低,所以我们有必要重新审视一下,管理后台的登录界面到底需要些什么功能. 一.功能模块的取舍 1.基本的账号密码登录.这个无可避免是必然需要的了. 2.图片验证码.验证码的目的是为了阻止机器人暴力撞库,作为管理后台很有必要,而且是要每次登录请求都需重新验证. 3.填完用户名或密码时,Ajax实时验证.这个功能常见于一些自动管理后台的注册模块,

理解Vue的状态管理模式Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 状态管理模式.集中式存储管理,一听就很高大上,蛮吓人的.在我看来 vuex 就是把需要共享的变量全部存储在一个对象里面,然后将这个对象放在顶层组件中供其他组件使用.这么说吧,将vue想作是一个js文件.组件是函数,那么vuex就是一个全局变量,只是这个"全局变量"包含了一些特定的规则而已. 在vue的组件化开发中,经常会遇到需要将

Part 2:模型与管理后台

接着第一部分,本节将讲述如何安装数据库,编写第一个模型以及简要的介绍下Django自动生成的后台管理admin站点. 一.数据库安装 打开mysite/settings.py配置文件,这是整个Django项目的设置中心.Django默认使用SQLite数据库,因为Python源生支持SQLite数据库,所以你无须安装任何程序,就可以直接使用它.当然,如果你是在创建一个实际的项目,可以使用类似PostgreSQL的数据库,避免以后数据库迁移的相关问题. # mysite/settings.py #

Django2.1.2创建默认管理后台

1.在app的models.py中添加以下代码: from django.db import models # Create your models here. # Register your models here. class UserType(models.Model): name = models.CharField(max_length=32) class UserInfo(models.Model): username = models.CharField(max_length=32

git-拉取项目---基于Ant-Design-Pro-2-0-的CMS管理后台入门系列

git 拉取项目CMS管理后台项目 github 项目地址:luwei.web.study-ant-design-pro 企业内部项目地址:study.ant-design-pro 注:github 上的项目暂不支持后台数据渲染对接的步骤,仅使用静态数据展示. 项目下载方式: 使用 git clone 拉取 download zip image 在此不做过多解释,若不了解 git 基本操作命令,请移步至 廖雪峰 - Git教程 文件简介 ├── config                   

TOM企业邮箱管理后台全新升级,五大亮点独家揭秘

2019年是TOM邮箱的第21年,也是里程碑式跨越的一年.近日,新版管理后台即将正式和大家见面啦~本次升级覆盖全面,包括移动办公.邮箱搬家.邮件群组.邮箱管理.企业定制等多个特色功能.在21周年庆期间,伴随着企邮周年庆活动以及扶贫事业,企业邮箱管理后台2.0版更多实用功能将华丽呈现.看点一:新版管理后台界面操作更流畅新版后台优化了整体布局.改版后的页面主次分明.设置多个快捷入口,可以快速找到功能操作入口.同时全新的架构和分类,按企业用户的需求进行功能模块的再划分,给用户带来更好的交互视觉体验.看