Merge pull request #58 from eleme/feat/next-tabs

Feat/next tabs
pull/2/head
FuryBean 2016-08-15 11:30:37 +08:00 committed by GitHub
commit 0de1650c63
7 changed files with 94 additions and 85 deletions

View File

@ -14,13 +14,13 @@ const install = function(Vue) {
{{install}} {{install}}
// Vue.use(Loading); Vue.use(Loading);
// Vue.prototype.$msgbox = MessageBox; Vue.prototype.$msgbox = MessageBox;
// Vue.prototype.$alert = MessageBox.alert; Vue.prototype.$alert = MessageBox.alert;
// Vue.prototype.$confirm = MessageBox.confirm; Vue.prototype.$confirm = MessageBox.confirm;
// Vue.prototype.$prompt = MessageBox.prompt; Vue.prototype.$prompt = MessageBox.prompt;
// Vue.prototype.$notify = Notification; Vue.prototype.$notify = Notification;
}; };
// auto install // auto install

View File

@ -1,7 +1,4 @@
{ {
"group": [
"./packages/group/index.js"
],
"select-dropdown": [ "select-dropdown": [
"./packages/select-dropdown/index.js" "./packages/select-dropdown/index.js"
], ],

View File

@ -15,8 +15,8 @@
title: '选项卡四', title: '选项卡四',
content: '选项卡四内容' content: '选项卡四内容'
}], }],
activeKey: '3', activeName: '3',
activeKey2: '' activeName2: ''
} }
} }
} }
@ -30,7 +30,7 @@
## 基础使用 ## 基础使用
<div> <div>
<el-tabs :active-key="activeKey"> <el-tabs :active-name="activeName">
<el-tab-pane label="选项卡一">选项卡一内容</el-tab-pane> <el-tab-pane label="选项卡一">选项卡一内容</el-tab-pane>
<el-tab-pane label="选项卡二">选项卡二内容</el-tab-pane> <el-tab-pane label="选项卡二">选项卡二内容</el-tab-pane>
<el-tab-pane label="选项卡三">选项卡三内容</el-tab-pane> <el-tab-pane label="选项卡三">选项卡三内容</el-tab-pane>
@ -39,7 +39,7 @@
</div> </div>
```html ```html
<el-tabs :active-key="activeKey"> <el-tabs :active-name="activeName">
<el-tab-pane label="选项卡一">选项卡一内容</el-tab-pane> <el-tab-pane label="选项卡一">选项卡一内容</el-tab-pane>
<el-tab-pane label="选项卡二">选项卡二内容</el-tab-pane> <el-tab-pane label="选项卡二">选项卡二内容</el-tab-pane>
<el-tab-pane label="选项卡三">选项卡三内容</el-tab-pane> <el-tab-pane label="选项卡三">选项卡三内容</el-tab-pane>
@ -77,7 +77,7 @@
<el-tab-pane label="选项卡四">选项卡四内容</el-tab-pane> <el-tab-pane label="选项卡四">选项卡四内容</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
{{activeKey2}} {{activeName2}}
```html ```html
<el-tabs type="card" :closable="true"> <el-tabs type="card" :closable="true">
@ -113,8 +113,8 @@
|---------- |-------- |---------- |------------- |-------- | |---------- |-------- |---------- |------------- |-------- |
| type | 风格类型 | string | card, border-card | | | type | 风格类型 | string | card, border-card | |
| closable | 真实值 | boolean | true, false | false | | closable | 真实值 | boolean | true, false | false |
| defaultActiveKey | 如果没有设置 activeKey, 则使用该值 | string | | 第一个面板 | | defaultActiveName | 如果没有设置 activeName, 则使用该值 | string | | 第一个面板 |
| activeKey | 当前选中面板的key | string | | | | activeName | 当前选中面板的 name | string | | |
| tab.click | tab 被点击的回调 | string | | | | tab.click | tab 被点击的回调 | string | | |
| tab.remove | tab 被删除的回调 | string | | | | tab.remove | tab 被删除的回调 | string | | |
@ -122,4 +122,4 @@
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- | |---------- |-------- |---------- |------------- |-------- |
| label | 选项卡标题 | string | | | | label | 选项卡标题 | string | | |
| key | 与选项卡activeKey对应的标识符 | string | | 该选项卡在选项卡中的index值,如第一个选项卡则为'1' | | name | 与选项卡 activeName 对应的标识符 | string | | 该选项卡在选项卡中的 name 值,如第一个选项卡则为'1' |

View File

@ -7,9 +7,7 @@
type: String, type: String,
required: true required: true
}, },
key: { name: String
type: String
}
}, },
data() { data() {
@ -18,7 +16,8 @@
transition: '', transition: '',
paneStyle: { paneStyle: {
position: 'relative' position: 'relative'
} },
key: ''
}; };
}, },
@ -28,17 +27,20 @@
} }
}, },
events: {
},
computed: { computed: {
show() { show() {
return this.$parent.activeKey === this.key; return this.$parent.currentName === this.key;
} }
}, },
watch: { watch: {
'$parent.activeKey'(newValue, oldValue) { name: {
immediate: true,
handler(val) {
this.key = val;
}
},
'$parent.currentName'(newValue, oldValue) {
if (this.key === newValue) { if (this.key === newValue) {
this.transition = newValue > oldValue ? 'slideInRight' : 'slideInLeft'; this.transition = newValue > oldValue ? 'slideInRight' : 'slideInLeft';
} }

View File

@ -8,20 +8,23 @@
required: true required: true
}, },
closable: Boolean closable: Boolean
},
data() {
return {
showClose: false
};
} }
}; };
</script> </script>
<template> <template>
<div class="el-tabs__item" <div
:class="{ class="el-tabs__item"
'is-active': $parent.activeKey === tab.key, :class="{
'is-disabled': tab.disabled, 'is-active': $parent.currentName === tab.key,
'is-closable': closable 'is-disabled': tab.disabled,
}">{{tab.label}}<span class="el-icon-close" v-if="closable" @click="$emit('onremove', tab, $event)"></span></div> 'is-closable': closable
}">
{{tab.label}}
<span
class="el-icon-close"
v-if="closable"
@click="$emit('onremove', tab, $event)">
</span>
</div>
</template> </template>

View File

@ -11,12 +11,8 @@
props: { props: {
type: String, type: String,
tabPosition: String, tabPosition: String,
defaultActiveKey: { defaultActiveName: String,
type: String activeName: String,
},
activeKey: {
type: String
},
closable: false, closable: false,
tabWidth: 0 tabWidth: 0
}, },
@ -25,34 +21,22 @@
return { return {
tabs: [], tabs: [],
children: null, children: null,
activeTab: null activeTab: null,
currentName: 0,
barStyle: ''
}; };
}, },
computed: { watch: {
barStyle: { activeName: {
cache: false, immediate: true,
get() { handler(val) {
if (this.type) return {}; this.currentName = val || 0;
var style = {};
var offset = 0;
var tabWidth = 0;
this.tabs.every((tab, index) => {
let $el = this.$refs.tabs[index].$el;
if (tab.key !== this.activeKey) {
offset += $el.clientWidth;
return true;
} else {
tabWidth = $el.clientWidth;
return false;
}
});
style.width = tabWidth + 'px';
style.transform = `translateX(${offset}px)`;
return style;
} }
},
'currentName'() {
this.calcBarStyle();
} }
}, },
@ -67,27 +51,49 @@
this.tabs.splice(index, 1); this.tabs.splice(index, 1);
} }
if (tab.key === this.activeKey) { if (tab.key === this.currentName) {
let deleteIndex = this.$children.indexOf(tab); let deleteIndex = this.$children.indexOf(tab);
let nextChild = this.$children[deleteIndex + 1]; let nextChild = this.$children[deleteIndex + 1];
let prevChild = this.$children[deleteIndex - 1]; let prevChild = this.$children[deleteIndex - 1];
this.activeKey = nextChild ? nextChild.key : prevChild ? prevChild.key : '-1'; this.currentName = nextChild ? nextChild.key : prevChild ? prevChild.key : '-1';
} }
this.$emit('tab.remove', tab); this.$emit('tab.remove', tab);
}, },
handleTabClick(tab) { handleTabClick(tab) {
this.activeKey = tab.key; this.currentName = tab.key;
this.$emit('tab.click', tab); this.$emit('tab.click', tab);
},
calcBarStyle() {
if (this.type) return {};
var style = {};
var offset = 0;
var tabWidth = 0;
this.tabs.every((tab, index) => {
let $el = this.$refs.tabs[index].$el;
if (tab.key !== this.currentName) {
offset += $el.clientWidth;
return true;
} else {
tabWidth = $el.clientWidth;
return false;
}
});
style.width = tabWidth + 'px';
style.transform = `translateX(${offset}px)`;
this.barStyle = style;
} }
}, },
ready() {
if (!this.activeKey) { mounted() {
this.activeKey = this.defaultActiveKey || this.$children[0].key; if (!this.currentName) {
this.currentName = this.defaultActiveName || this.$children[0].key;
} }
this.$children.forEach(tab => { this.$children.forEach(tab => this.tabs.push(tab));
this.tabs.push(tab); this.$nextTick(() => this.calcBarStyle());
});
} }
}; };
</script> </script>
@ -97,13 +103,17 @@
<div class="el-tabs__header"> <div class="el-tabs__header">
<el-tab <el-tab
v-for="tab in tabs" v-for="tab in tabs"
v-ref:tabs ref="tabs"
:tab="tab" :tab="tab"
:closable="closable" :closable="closable"
@onremove="removeTab" @onremove="removeTab"
@click="handleTabClick(tab)" @click.native="handleTabClick(tab)">
></el-tab> </el-tab>
<div class="el-tabs__active-bar" v-bind:style="barStyle" v-if="!this.type && tabs.length > 0"></div> <div
class="el-tabs__active-bar"
:style="barStyle"
v-if="!this.type && tabs.length > 0">
</div>
</div> </div>
<div class="el-tabs__content"> <div class="el-tabs__content">

View File

@ -1,4 +1,3 @@
import Group from '../packages/group/index.js';
import SelectDropdown from '../packages/select-dropdown/index.js'; import SelectDropdown from '../packages/select-dropdown/index.js';
import Pagination from '../packages/pagination/index.js'; import Pagination from '../packages/pagination/index.js';
import Dialog from '../packages/dialog/index.js'; import Dialog from '../packages/dialog/index.js';
@ -52,7 +51,6 @@ import Spinner from '../packages/spinner/index.js';
const install = function(Vue) { const install = function(Vue) {
if (install.installed) return; if (install.installed) return;
Vue.component(Group.name, Group);
Vue.component(SelectDropdown.name, SelectDropdown); Vue.component(SelectDropdown.name, SelectDropdown);
Vue.component(Pagination.name, Pagination); Vue.component(Pagination.name, Pagination);
Vue.component(Dialog.name, Dialog); Vue.component(Dialog.name, Dialog);
@ -109,14 +107,13 @@ const install = function(Vue) {
Vue.prototype.$notify = Notification; Vue.prototype.$notify = Notification;
}; };
auto install // auto install
if (typeof window !== 'undefined' && window.Vue) { if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue); install(window.Vue);
}; };
module.exports = { module.exports = {
install install,
Group,
SelectDropdown, SelectDropdown,
Pagination, Pagination,
Dialog, Dialog,