mirror of
https://github.com/ElemeFE/element.git
synced 2025-12-16 11:44:01 +08:00
add collapse
This commit is contained in:
13
packages/collapse/_index.js
Normal file
13
packages/collapse/_index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import ElCollapse from './src/collapse';
|
||||
import ElCollapseItem from './src/collapse-item.vue';
|
||||
|
||||
/* istanbul ignore next */
|
||||
export default function install(Vue) {
|
||||
Vue.component(ElCollapseItem.name, ElCollapseItem);
|
||||
Vue.component(ElCollapse.name, ElCollapse);
|
||||
};
|
||||
|
||||
export {
|
||||
ElCollapse,
|
||||
ElCollapseItem
|
||||
};
|
||||
18
packages/collapse/cooking.conf.js
Normal file
18
packages/collapse/cooking.conf.js
Normal file
@@ -0,0 +1,18 @@
|
||||
var cooking = require('cooking');
|
||||
var path = require('path');
|
||||
var config = require('../../build/config');
|
||||
|
||||
cooking.set({
|
||||
entry: {
|
||||
index: path.join(__dirname, '_index.js')
|
||||
},
|
||||
dist: path.join(__dirname, 'lib'),
|
||||
template: false,
|
||||
format: 'umd',
|
||||
moduleName: 'ElCollapse',
|
||||
extends: ['vue2'],
|
||||
alias: config.alias,
|
||||
externals: { vue: config.vue }
|
||||
});
|
||||
|
||||
module.exports = cooking.resolve();
|
||||
9
packages/collapse/index.js
Normal file
9
packages/collapse/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import ElCollapse from './src/collapse';
|
||||
|
||||
/* istanbul ignore next */
|
||||
ElCollapse.install = function(Vue) {
|
||||
Vue.component(ElCollapse.name, ElCollapse);
|
||||
};
|
||||
|
||||
export default ElCollapse;
|
||||
|
||||
15
packages/collapse/package.json
Normal file
15
packages/collapse/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "element-collapse",
|
||||
"version": "1.0.0",
|
||||
"description": "A row component for Vue.",
|
||||
"keywords": [
|
||||
"element",
|
||||
"vue",
|
||||
"component"
|
||||
],
|
||||
"main": "./lib/index.js",
|
||||
"repository": "https://github.com/ElemeFE/element/tree/master/packages/collapse",
|
||||
"author": "haiping.zeng@ele.me",
|
||||
"license": "MIT",
|
||||
"dependencies": {}
|
||||
}
|
||||
106
packages/collapse/src/collapse-item.vue
Normal file
106
packages/collapse/src/collapse-item.vue
Normal file
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<div class="el-collapse-item" :class="{'is-active': isActive}">
|
||||
<div class="el-collapse-item__header" @click="handleHeaderClick">
|
||||
<i class="el-collapse-item__header__arrow el-icon-arrow-right"></i>
|
||||
<slot name="title" :title="title">{{title}}</slot>
|
||||
</div>
|
||||
<div class="el-collapse-item__wrap" ref="content" :style="contentStyle">
|
||||
<div class="el-collapse-item__content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { once } from 'wind-dom';
|
||||
import Emitter from 'element-ui/src/mixins/emitter';
|
||||
|
||||
function uid() {
|
||||
function S4() {
|
||||
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
||||
}
|
||||
return `${S4()}${S4()}-${S4()}-${S4()}-${S4()}-${S4()}${S4()}${S4()}`;
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'ElCollapseItem',
|
||||
|
||||
componentName: 'ElCollapseItem',
|
||||
|
||||
mixins: [Emitter],
|
||||
|
||||
data() {
|
||||
return {
|
||||
contentStyle: {},
|
||||
contentHeight: 0
|
||||
};
|
||||
},
|
||||
|
||||
props: {
|
||||
title: String,
|
||||
name: {
|
||||
type: [String, Number],
|
||||
default() {
|
||||
return uid();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isActive() {
|
||||
return this.$parent.activeNames.indexOf(this.name) > -1;
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
'isActive'(value) {
|
||||
value ? this.open() : this.close();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
open() {
|
||||
const contentElm = this.$refs.content;
|
||||
const contentStyle = this.contentStyle;
|
||||
|
||||
contentStyle.display = 'block';
|
||||
this.$nextTick(_ => {
|
||||
contentStyle.height = this.contentHeight + 'px';
|
||||
once(contentElm, 'transitionend', () => {
|
||||
contentStyle.height = 'auto';
|
||||
});
|
||||
});
|
||||
},
|
||||
close() {
|
||||
const contentElm = this.$refs.content;
|
||||
const contentHeight = contentElm.clientHeight;
|
||||
const contentStyle = this.contentStyle;
|
||||
|
||||
this.contentHeight = contentHeight;
|
||||
this.$set(this.contentStyle, 'height', contentHeight + 'px');
|
||||
|
||||
this.$nextTick(_ => {
|
||||
contentStyle.height = '0';
|
||||
once(contentElm, 'transitionend', () => {
|
||||
this.$set(this.contentStyle, 'display', 'none');
|
||||
});
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.contentHeight = this.$refs.content.clientHeight;
|
||||
|
||||
if (!this.isActive) {
|
||||
this.$set(this.contentStyle, 'height', '0');
|
||||
this.$set(this.contentStyle, 'display', 'none');
|
||||
}
|
||||
},
|
||||
handleHeaderClick() {
|
||||
this.dispatch('ElCollapse', 'item-click', this);
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.init();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
62
packages/collapse/src/collapse.vue
Normal file
62
packages/collapse/src/collapse.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="el-collapse">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'ElCollapse',
|
||||
|
||||
componentName: 'ElCollapse',
|
||||
|
||||
props: {
|
||||
accordion: Boolean,
|
||||
value: {
|
||||
type: [Array, String],
|
||||
default() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
activeNames: [].concat(this.value)
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
value(value) {
|
||||
this.activeNames = [].concat(value);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
setActiveNames(activeNames) {
|
||||
let value = this.accordion ? activeNames[0] : activeNames;
|
||||
this.activeNames = [].concat(value);
|
||||
this.$emit('input', value);
|
||||
this.$emit('change', value);
|
||||
},
|
||||
handleItemClick(item) {
|
||||
if (this.accordion) {
|
||||
this.setActiveNames(this.activeNames[0] === item.name ? '' : item.name);
|
||||
} else {
|
||||
let activeNames = this.activeNames.slice(0);
|
||||
let index = activeNames.indexOf(item.name);
|
||||
|
||||
if (index > -1) {
|
||||
activeNames.splice(index, 1);
|
||||
} else {
|
||||
activeNames.push(item.name);
|
||||
}
|
||||
this.setActiveNames(activeNames);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.$on('item-click', this.handleItemClick);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user