mirror of https://github.com/ElemeFE/element
				
				
				
			Dropdown Reconstruction
							parent
							
								
									10306ab821
								
							
						
					
					
						commit
						cf3e15eab9
					
				|  | @ -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", | ||||
|  |  | |||
|  | @ -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 时,点击左侧按钮的回调 | — | | ||||
|  |  | |||
|  | @ -0,0 +1,7 @@ | |||
| const ElDropdownMenu = require('../dropdown/src/dropdown-menu'); | ||||
| 
 | ||||
| ElDropdownMenu.install = function(Vue) { | ||||
|   Vue.component(ElDropdownMenu.name, ElDropdownMenu); | ||||
| }; | ||||
| 
 | ||||
| module.exports = ElDropdownMenu; | ||||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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; | ||||
|       } | ||||
|  |  | |||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 baiyaaaaa
						baiyaaaaa