Dropdown Reconstruction

pull/255/head
baiyaaaaa 2016-10-05 11:03:44 +08:00
parent 10306ab821
commit cf3e15eab9
9 changed files with 181 additions and 150 deletions

View File

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

View File

@ -3,23 +3,31 @@
.el-dropdown { .el-dropdown {
vertical-align: top; vertical-align: top;
& .el-button-group {
margin-bottom: 0;
}
& + .el-dropdown { & + .el-dropdown {
margin-left: 15px; margin-left: 15px;
} }
} }
.el-dropdown-link {
cursor: pointer;
color: #20a0ff;
}
.el-icon-caret-bottom {
vertical-align: middle;
font-size: 12px;
}
} }
.demo-dropdown .block { .block-col-2 {
display: inline-block; margin: -24px;
padding: 30px 0;
text-align: center; .el-col {
border-right: solid 1px #EFF2F6; padding: 30px 0;
flex: 1; text-align: center;
&:last-child { border-right: 1px solid #eff2f6;
border-right: none;
&:last-child {
border-right: 0;
}
} }
} }
@ -34,17 +42,9 @@
<script> <script>
export default { export default {
methods: { methods: {
handleMainClick() { handleClick() {
alert('click main button'); 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> </script>
@ -59,12 +59,17 @@
:::demo 通过`text`属性来设置按钮文字。默认条件下,他由一个主要按钮和一个下拉按钮组成,`el-dropdown`中的主要按钮同样可以设置点击事件,只要使用`mainclick`事件即可。默认情况下,下拉按钮只要`hover`即可,无需点击也会显示下拉菜单。 :::demo 通过`text`属性来设置按钮文字。默认条件下,他由一个主要按钮和一个下拉按钮组成,`el-dropdown`中的主要按钮同样可以设置点击事件,只要使用`mainclick`事件即可。默认情况下,下拉按钮只要`hover`即可,无需点击也会显示下拉菜单。
```html ```html
<el-dropdown text="下拉菜单" type="text" :icon-separate="false" @mainclick="handleMainClick()"> <el-dropdown>
<el-dropdown-item>黄金糕</el-dropdown-item> <span class="el-dropdown-link">
<el-dropdown-item>狮子头</el-dropdown-item> 下拉菜单<i class="el-icon-caret-bottom el-icon-right"></i>
<el-dropdown-item>螺蛳粉</el-dropdown-item> </span>
<el-dropdown-item>双皮奶</el-dropdown-item> <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-item>蚵仔煎</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown> </el-dropdown>
``` ```
::: :::
@ -76,19 +81,29 @@
:::demo 设置`icon-separate`属性来呈现不带独立按钮的下拉菜单,设置为`false`即可。在选项三和选项四中插入了一条分割线,只需要在选项四中设置`class`为`divider`。 :::demo 设置`icon-separate`属性来呈现不带独立按钮的下拉菜单,设置为`false`即可。在选项三和选项四中插入了一条分割线,只需要在选项四中设置`class`为`divider`。
```html ```html
<el-dropdown text="更多菜单" type="primary" :icon-separate="false"> <el-dropdown>
<el-dropdown-item>选项一</el-dropdown-item> <el-button type="primary">
<el-dropdown-item>选项二</el-dropdown-item> 更多菜单<i class="el-icon-caret-bottom el-icon-right"></i>
<el-dropdown-item>选项三</el-dropdown-item> </el-button>
<el-dropdown-item class="divider">选项四</el-dropdown-item> <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>
<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`即可。 :::demo 在`trigger`属性设置为`click`即可。
```html ```html
<div class="block"> <el-row class="block-col-2">
<span class="demonstration">hover 激活</span> <el-col :span="12">
<el-dropdown text="下拉菜单" type="text" :icon-separate="false" trigger="hover"> <span class="demonstration">hover 激活</span>
<el-dropdown-item>选项一</el-dropdown-item> <el-dropdown>
<el-dropdown-item>选项二</el-dropdown-item> <span class="el-dropdown-link">
<el-dropdown-item>选项三</el-dropdown-item> 下拉菜单<i class="el-icon-caret-bottom el-icon-right"></i>
<el-dropdown-item>选项四</el-dropdown-item> </span>
</el-dropdown> <el-dropdown-menu slot="dropdown">
</div> <el-dropdown-item>黄金糕</el-dropdown-item>
<div class="block"> <el-dropdown-item>狮子头</el-dropdown-item>
<span class="demonstration">click 激活</span> <el-dropdown-item>螺蛳粉</el-dropdown-item>
<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>选项二</el-dropdown-item> </el-dropdown-menu>
<el-dropdown-item>选项三</el-dropdown-item> </el-dropdown>
<el-dropdown-item class="divider">选项四</el-dropdown-item> </el-col>
</el-dropdown> <el-col :span="12">
</div> <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 ### Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |
|------------- |---------------- |---------------- |---------------------- |-------- | |------------- |---------------- |---------------- |---------------------- |-------- |
| text | 菜单按钮文本 | string | — | — |
| type | 菜单按钮类型,同 Button 组件 | string | — | — | | type | 菜单按钮类型,同 Button 组件 | string | — | — |
| trigger | 触发下拉菜单的方式 | string | hover,click | hover | | split-button | 带下拉框的按钮 | boolean | — | false |
| icon-separate | 独立的下拉菜单按钮 | boolean | — | true |
| size | 菜单按钮尺寸,同 Button 组件 | string | large, small, mini | — |
| menu-align | 菜单水平对齐方向 | string | start, end | end | | 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> <template>
<ul class="el-dropdown__menu" transition="md-fade-bottom"> <ul class="el-dropdown__menu">
<slot></slot> <slot></slot>
</ul> </ul>
</template> </template>
@ -7,6 +7,11 @@
import Popper from 'main/utils/popper'; import Popper from 'main/utils/popper';
export default { export default {
name: 'ElDropdownMenu',
props: {
visible: Boolean
},
data() { data() {
return { return {
popper: null popper: null
@ -17,13 +22,6 @@
return this.$parent.menuAlign; return this.$parent.menuAlign;
} }
}, },
methods: {
updatePopper() {
if (this.popper) {
this.popper.update();
}
}
},
mounted() { mounted() {
document.body.appendChild(this.$el); 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> <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'; import Clickoutside from 'main/utils/clickoutside';
export default { export default {
name: 'ElDropdown', name: 'ElDropdown',
components: {
ElButton,
ElButtonGroup,
ElDropdownMenu
},
directives: { Clickoutside }, directives: { Clickoutside },
props: { props: {
text: String,
type: String,
iconSeparate: {
type: Boolean,
default: true
},
trigger: { trigger: {
type: String, type: String,
default: 'hover' default: 'hover'
}, },
size: {
type: String,
default: ''
},
menuAlign: { menuAlign: {
type: String, type: String,
default: 'end' default: 'end'
} },
type: {
type: String
},
splitButton: Boolean
}, },
data() { data() {
@ -82,6 +28,10 @@
}; };
}, },
mounted() {
this.initEvent();
},
methods: { methods: {
show() { show() {
clearTimeout(this.timeout); clearTimeout(this.timeout);
@ -95,21 +45,61 @@
this.visible = false; this.visible = false;
}, 150); }, 150);
}, },
handleMouseEnter() {
if (this.trigger === 'hover') {
this.show();
}
},
handleMouseLeave() {
if (this.trigger === 'hover') {
this.hide();
}
},
handleClick() { 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> </script>

View File

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

View File

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

View File

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

View File

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