Merge pull request #255 from baiyaaaaa/master

Dropdown Reconstruction
This commit is contained in:
杨奕 2016-10-08 10:32:38 +08:00 committed by GitHub
commit 95302e3395
9 changed files with 181 additions and 150 deletions

View File

@ -4,6 +4,7 @@
"dialog": "./packages/dialog/index.js",
"autocomplete": "./packages/autocomplete/index.js",
"dropdown": "./packages/dropdown/index.js",
"dropdown-menu": "./packages/dropdown-menu/index.js",
"dropdown-item": "./packages/dropdown-item/index.js",
"menu": "./packages/menu/index.js",
"submenu": "./packages/submenu/index.js",

View File

@ -3,23 +3,31 @@
.el-dropdown {
vertical-align: top;
& .el-button-group {
margin-bottom: 0;
}
& + .el-dropdown {
margin-left: 15px;
}
}
.el-dropdown-link {
cursor: pointer;
color: #20a0ff;
}
.el-icon-caret-bottom {
vertical-align: middle;
font-size: 12px;
}
}
.demo-dropdown .block {
display: inline-block;
padding: 30px 0;
text-align: center;
border-right: solid 1px #EFF2F6;
flex: 1;
&:last-child {
border-right: none;
.block-col-2 {
margin: -24px;
.el-col {
padding: 30px 0;
text-align: center;
border-right: 1px solid #eff2f6;
&:last-child {
border-right: 0;
}
}
}
@ -34,17 +42,9 @@
<script>
export default {
methods: {
handleMainClick() {
alert('click main button');
handleClick() {
alert('button click');
}
},
mounted() {
this.$nextTick(() => {
let demos = document.querySelectorAll('.source');
let lastDemo = demos[demos.length - 1];
lastDemo.style.padding = '0';
lastDemo.style.display = 'flex';
});
}
}
</script>
@ -59,12 +59,17 @@
:::demo 通过`text`属性来设置按钮文字。默认条件下,他由一个主要按钮和一个下拉按钮组成,`el-dropdown`中的主要按钮同样可以设置点击事件,只要使用`mainclick`事件即可。默认情况下,下拉按钮只要`hover`即可,无需点击也会显示下拉菜单。
```html
<el-dropdown text="下拉菜单" type="text" :icon-separate="false" @mainclick="handleMainClick()">
<el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item>双皮奶</el-dropdown-item>
<el-dropdown-item>蚵仔煎</el-dropdown-item>
<el-dropdown>
<span class="el-dropdown-link">
下拉菜单<i class="el-icon-caret-bottom el-icon-right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item>双皮奶</el-dropdown-item>
<el-dropdown-item>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
```
:::
@ -76,19 +81,29 @@
:::demo 设置`icon-separate`属性来呈现不带独立按钮的下拉菜单,设置为`false`即可。在选项三和选项四中插入了一条分割线,只需要在选项四中设置`class`为`divider`。
```html
<el-dropdown text="更多菜单" type="primary" :icon-separate="false">
<el-dropdown-item>选项一</el-dropdown-item>
<el-dropdown-item>选项二</el-dropdown-item>
<el-dropdown-item>选项三</el-dropdown-item>
<el-dropdown-item class="divider">选项四</el-dropdown-item>
<el-dropdown>
<el-button type="primary">
更多菜单<i class="el-icon-caret-bottom el-icon-right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item>双皮奶</el-dropdown-item>
<el-dropdown-item>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-dropdown split-button type="primary" @click="handleClick">
更多菜单
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item>双皮奶</el-dropdown-item>
<el-dropdown-item>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-dropdown text="主要按钮" type="primary" @mainclick="handleMainClick()">
<el-dropdown-item>选项一</el-dropdown-item>
<el-dropdown-item>选项二</el-dropdown-item>
<el-dropdown-item>选项三</el-dropdown-item>
<el-dropdown-item>选项四</el-dropdown-item>
</el-dropdown>
```
:::
@ -98,33 +113,51 @@
:::demo 在`trigger`属性设置为`click`即可。
```html
<div class="block">
<span class="demonstration">hover 激活</span>
<el-dropdown text="下拉菜单" type="text" :icon-separate="false" trigger="hover">
<el-dropdown-item>选项一</el-dropdown-item>
<el-dropdown-item>选项二</el-dropdown-item>
<el-dropdown-item>选项三</el-dropdown-item>
<el-dropdown-item>选项四</el-dropdown-item>
</el-dropdown>
</div>
<div class="block">
<span class="demonstration">click 激活</span>
<el-dropdown text="下拉菜单" type="text" :icon-separate="false" trigger="click">
<el-dropdown-item>选项一</el-dropdown-item>
<el-dropdown-item>选项二</el-dropdown-item>
<el-dropdown-item>选项三</el-dropdown-item>
<el-dropdown-item class="divider">选项四</el-dropdown-item>
</el-dropdown>
</div>
<el-row class="block-col-2">
<el-col :span="12">
<span class="demonstration">hover 激活</span>
<el-dropdown>
<span class="el-dropdown-link">
下拉菜单<i class="el-icon-caret-bottom el-icon-right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item>双皮奶</el-dropdown-item>
<el-dropdown-item>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
<el-col :span="12">
<span class="demonstration">click 激活</span>
<el-dropdown trigger="click">
<span class="el-dropdown-link">
下拉菜单<i class="el-icon-caret-bottom el-icon-right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item>双皮奶</el-dropdown-item>
<el-dropdown-item>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
</el-row>
```
:::
### Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|------------- |---------------- |---------------- |---------------------- |-------- |
| text | 菜单按钮文本 | string | — | — |
| type | 菜单按钮类型,同 Button 组件 | string | — | — |
| trigger | 触发下拉菜单的方式 | string | hover,click | hover |
| icon-separate | 独立的下拉菜单按钮 | boolean | — | true |
| size | 菜单按钮尺寸,同 Button 组件 | string | large, small, mini | — |
| split-button | 带下拉框的按钮 | boolean | — | false |
| menu-align | 菜单水平对齐方向 | string | start, end | end |
| trigger | 触发下拉的行为 | string | hover, click | hover |
### Events
| 事件名称 | 说明 | 回调参数 |
|---------- |-------- |---------- |
| click | `split-button` 为 true 时,点击左侧按钮的回调 | — |

View File

@ -0,0 +1,7 @@
const ElDropdownMenu = require('../dropdown/src/dropdown-menu');
ElDropdownMenu.install = function(Vue) {
Vue.component(ElDropdownMenu.name, ElDropdownMenu);
};
module.exports = ElDropdownMenu;

View File

@ -1,5 +1,5 @@
<template>
<ul class="el-dropdown__menu" transition="md-fade-bottom">
<ul class="el-dropdown__menu">
<slot></slot>
</ul>
</template>
@ -7,6 +7,11 @@
import Popper from 'main/utils/popper';
export default {
name: 'ElDropdownMenu',
props: {
visible: Boolean
},
data() {
return {
popper: null
@ -17,13 +22,6 @@
return this.$parent.menuAlign;
}
},
methods: {
updatePopper() {
if (this.popper) {
this.popper.update();
}
}
},
mounted() {
document.body.appendChild(this.$el);

View File

@ -1,78 +1,24 @@
<template>
<div class="el-dropdown"
:class="{'el-dropdown--text': type === 'text'}"
v-clickoutside="hide"
>
<!-- 分割的下拉按钮 -->
<el-button-group v-if="iconSeparate">
<el-button :size="size" :type="type" @click.native="$emit('mainclick')">{{text}}</el-button>
<el-button
:size="size"
:type="type"
class="el-dropdown__icon-button"
@mouseenter.native="handleMouseEnter"
@mouseleave.native="handleMouseLeave"
@click.native="handleClick">
<i class="el-dropdown__icon el-icon-caret-bottom"></i>
</el-button>
</el-button-group>
<!-- 不分割的下拉按钮 -->
<el-button :size="size" :type="type" @mouseenter.native="handleMouseEnter" @mouseleave.native="handleMouseLeave" @click.native="handleClick" v-else>
{{text}}<i class="el-dropdown__icon el-icon-caret-bottom"></i>
</el-button>
<!-- 下拉菜单 -->
<transition name="md-fade-bottom">
<el-dropdown-menu
v-if="visible"
@mouseenter.native="handleMouseEnter"
@mouseleave.native="handleMouseLeave">
<slot></slot>
</el-dropdown-menu>
</transition>
</div>
</template>
<script>
/**
* dropdown
* @module packages/dropdown
* @desc 下拉菜单组件
* @param {string} label - 名称
*/
import ElButton from 'packages/button/index.js';
import ElButtonGroup from 'packages/button-group/index.js';
import ElDropdownMenu from './dropdown-menu.vue';
import Clickoutside from 'main/utils/clickoutside';
export default {
name: 'ElDropdown',
components: {
ElButton,
ElButtonGroup,
ElDropdownMenu
},
directives: { Clickoutside },
props: {
text: String,
type: String,
iconSeparate: {
type: Boolean,
default: true
},
trigger: {
type: String,
default: 'hover'
},
size: {
type: String,
default: ''
},
menuAlign: {
type: String,
default: 'end'
}
},
type: {
type: String
},
splitButton: Boolean
},
data() {
@ -82,6 +28,10 @@
};
},
mounted() {
this.initEvent();
},
methods: {
show() {
clearTimeout(this.timeout);
@ -95,21 +45,61 @@
this.visible = false;
}, 150);
},
handleMouseEnter() {
if (this.trigger === 'hover') {
this.show();
}
},
handleMouseLeave() {
if (this.trigger === 'hover') {
this.hide();
}
},
handleClick() {
if (this.trigger === 'click') {
this.visible = !this.visible;
this.visible = !this.visible;
},
initEvent() {
let { trigger, show, hide, handleClick, splitButton } = this;
let triggerElm = splitButton
? this.$refs.trigger.$el
: this.$slots.default[0].elm;
if (trigger === 'hover') {
triggerElm.addEventListener('mouseenter', show);
triggerElm.addEventListener('mouseleave', hide);
let dropdown = this.$slots.dropdown[0];
let insertHook = dropdown.data.hook.insert;
dropdown.data.hook.insert = (vnode) => {
insertHook(vnode);
this.$nextTick(_ => {
vnode.elm.addEventListener('mouseenter', show);
vnode.elm.addEventListener('mouseleave', hide);
});
};
} else if (trigger === 'click') {
triggerElm.addEventListener('click', handleClick);
}
}
},
render(h) {
let { hide, splitButton, visible, type } = this;
let dropdownElm = visible ? this.$slots.dropdown : null;
var handleClick = _ => {
this.$emit('click');
};
let triggerElm = !splitButton
? this.$slots.default
: (<el-button-group>
<el-button type={type} nativeOn-click={handleClick}>
{this.$slots.default}
</el-button>
<el-button ref="trigger" type={type} class="el-dropdown__icon-button">
<i class="el-dropdown__icon el-icon-caret-bottom"></i>
</el-button>
</el-button-group>);
return (
<div class="el-dropdown" v-clickoutside={hide}>
{triggerElm}
<transition name="md-fade-bottom">
{dropdownElm}
</transition>
</div>
);
}
};
</script>

View File

@ -35,16 +35,7 @@
border: 0;
}
& .el-icon-right {
margin-left: 5px;
}
& .el-icon-left {
margin-right: 5px;
}
& [class*="el-icon-"] {
/*line-height: 0.9;*/
& + span {
margin-left: 5px;
}

View File

@ -53,8 +53,9 @@
}
}
@e icon {
padding-left: 5px;
transform: scale(.8, .8);
font-size: 12px;
vertical-align: middle;
margin: 0 3px;
}
@m text {
.el-button-text {

View File

@ -69,6 +69,13 @@
animation: rotating 1s linear infinite;
}
.el-icon-right {
margin-left: 5px;
}
.el-icon-left {
margin-right: 5px;
}
@keyframes rotating {
0% {
transform: rotateZ(0deg);

View File

@ -3,6 +3,7 @@ import Pagination from '../packages/pagination/index.js';
import Dialog from '../packages/dialog/index.js';
import Autocomplete from '../packages/autocomplete/index.js';
import Dropdown from '../packages/dropdown/index.js';
import DropdownMenu from '../packages/dropdown-menu/index.js';
import DropdownItem from '../packages/dropdown-item/index.js';
import Menu from '../packages/menu/index.js';
import Submenu from '../packages/submenu/index.js';
@ -62,6 +63,7 @@ const install = function(Vue) {
Vue.component(Dialog.name, Dialog);
Vue.component(Autocomplete.name, Autocomplete);
Vue.component(Dropdown.name, Dropdown);
Vue.component(DropdownMenu.name, DropdownMenu);
Vue.component(DropdownItem.name, DropdownItem);
Vue.component(Menu.name, Menu);
Vue.component(Submenu.name, Submenu);
@ -133,6 +135,7 @@ module.exports = {
Dialog,
Autocomplete,
Dropdown,
DropdownMenu,
DropdownItem,
Menu,
Submenu,