zoukankan      html  css  js  c++  java
  • element-ui Collapse 折叠面板源码分析整理笔记(十)

    Collapse 折叠面板源码:

    collapse.vue

    <template>
        <!--一组折叠面板最外层包裹div-->
      <div class="el-collapse" role="tablist" aria-multiselectable="true">
        <slot></slot>
      </div>
    </template>
    <script>
      export default {
        name: 'ElCollapse',
    
        componentName: 'ElCollapse',
    
        props: {
          accordion: Boolean, //是否手风琴模式
          value: {  //当前激活的面板(如果是手风琴模式,绑定值类型需要为string,否则为array)
            type: [Array, String, Number],
            default() {
              return [];
            }
          }
        },
    
        data() {
          return {
            activeNames: [].concat(this.value) //当前激活的面板名称数组
          };
        },
    
        provide() {
          return {
            collapse: this
          };
        },
    
        watch: {
          value(value) {
            this.activeNames = [].concat(value);
          }
        },
    
        methods: {
          setActiveNames(activeNames) {
            // 返回activeNames数组的副本
            activeNames = [].concat(activeNames);
            //如果是手风琴模式返回activeNames[0],不是则返回整个数组
            let value = this.accordion ? activeNames[0] : activeNames;
            this.activeNames = activeNames;
            //触发父组件的input方法
            this.$emit('input', value);
            //触发父组件的change方法
            this.$emit('change', value);
          },
          handleItemClick(item) {
            // 如果是手风琴模式
            if (this.accordion) {
              this.setActiveNames(
                (this.activeNames[0] || this.activeNames[0] === 0) &&
                this.activeNames[0] === item.name
                  ? '' : item.name
              );
            } else { //如果不是手风琴模式
              let activeNames = this.activeNames.slice(0);
              let index = activeNames.indexOf(item.name);
              if (index > -1) { //如果该面板已经是激活状态,就将其从activeNames数组中删除
                activeNames.splice(index, 1);
              } else {  //如果该面板还未是激活状态,就将其push进activeNames数组中
                activeNames.push(item.name);
              }
              this.setActiveNames(activeNames);
            }
          }
        },
    
        created() {
          this.$on('item-click', this.handleItemClick);
        }
      };
    </script>
    

    collapse-item.vue

    <template>
        <!--每个折叠面板最外层包裹div-->
      <div class="el-collapse-item" :class="{'is-active': isActive}">
    
        <div role="tab" :aria-expanded="isActive" :aria-controls="`el-collapse-content-${id}`" :aria-describedby ="`el-collapse-content-${id}`">
            <!--面板头部,包含面板标题和箭头图标-->
            <div class="el-collapse-item__header"
            @click="handleHeaderClick"
            role="button"
            :id="`el-collapse-head-${id}`"
            tabindex="0"
            @keyup.space.enter.stop="handleEnterClick"
            :class="{
              'focusing': focusing,
              'is-active': isActive
            }"
            @focus="handleFocus"
            @blur="focusing = false"
          >
             <!--折叠面板的标题-->
            <slot name="title">{{title}}</slot>
             <!--折叠面板的收起或折叠的箭头图标-->
            <i class="el-collapse-item__arrow el-icon-arrow-right" :class="{'is-active': isActive}"></i>
          </div>
        </div>
        <!--折叠面板内容区域 el-collapse-transition组件主要是为了添加内容显示隐藏时的动画效果-->
        <el-collapse-transition>
          <div class="el-collapse-item__wrap" v-show="isActive"
            role="tabpanel"
            :aria-hidden="!isActive"
            :aria-labelledby="`el-collapse-head-${id}`"
            :id="`el-collapse-content-${id}`"
          >
            <div class="el-collapse-item__content">
              <slot></slot>
            </div>
          </div>
        </el-collapse-transition>
      </div>
    </template>
    <script>
      import ElCollapseTransition from 'element-ui/src/transitions/collapse-transition';
      import Emitter from 'element-ui/src/mixins/emitter';
      import { generateId } from 'element-ui/src/utils/util';
    
      export default {
        name: 'ElCollapseItem',
    
        componentName: 'ElCollapseItem',
    
        mixins: [Emitter],
    
        components: { ElCollapseTransition },
    
        data() {
          return {
            contentWrapStyle: {
              height: 'auto',
              display: 'block'
            },
            contentHeight: 0,
            focusing: false,
            isClick: false
          };
        },
    
        inject: ['collapse'],
    
        props: {
          title: String,
          name: {
            type: [String, Number],
            default() {
              return this._uid;
            }
          }
        },
    
        computed: {
          // 返回当前面板是否被激活
          isActive() {
            // 判断当前面板的名称是否在activeNames中
            return this.collapse.activeNames.indexOf(this.name) > -1;
          },
          id() {
            // 返回随机数id
            return generateId();
          }
        },
    
        methods: {
          handleFocus() {
            setTimeout(() => {
              if (!this.isClick) {
                this.focusing = true;
              } else {
                this.isClick = false;
              }
            }, 50);
          },
          handleHeaderClick() {
            // 触发父组件的item-click事件
            this.dispatch('ElCollapse', 'item-click', this);
            this.focusing = false;
            this.isClick = true;
          },
          handleEnterClick() {
            this.dispatch('ElCollapse', 'item-click', this);
          }
        }
      };
    </script>
    
  • 相关阅读:
    unreal python commandlet print log
    三维空间坐标系变换公式
    Android Volley初探:Volley基本用法
    Android View学习笔记(四):Scroller的原理剖析及使用(下)
    Android View学习笔记(三):Scroller的原理剖析及使用(上)
    Android View学习笔记(二):View滑动方式总结
    Android View学习笔记(一):View基础知识
    获取NavigationBar状态与高度
    解决RecyclerView.getChildAt(Position)崩溃
    RecyclerView瀑布流的那些坑
  • 原文地址:https://www.cnblogs.com/fangnianqin/p/10109185.html
Copyright © 2011-2022 走看看