Collapse 折叠面板源码:
collapse.vue
<template>
<!--一组折叠面板最外层包裹div-->
<div class=\"el-collapse\" role=\"tablist\" aria-multiselectable=\"true\">
<slot></slot>
</div>
</template>
< >
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);
}
};
</ >
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=\" \">{{ }}</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>
< >
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: {
: 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);
}
}
};
</ >
继续阅读与本文标签相同的文章
上一篇 :
面试题1
下一篇 :
科技观点:区块链等前沿领域的新变化
-
多路RTSP-RTMP转RTMP官方定制版
2026-05-19栏目: 教程
-
服务器租用价格多少,决定云服务器价格的因素
2026-05-19栏目: 教程
-
企业上云的好处优势告诉你企业为什么要上云?
2026-05-19栏目: 教程
-
阿里云910会员节大促主会场全攻略
2026-05-19栏目: 教程
-
Agentless监控实践中的预警指标采集
2026-05-19栏目: 教程
