fix(dropdown): fix dropdown code based on popper's change

This commit is contained in:
JeremyWuuuuu 2020-09-14 23:42:33 +08:00 committed by hangzou
parent 9389c16685
commit 9902c33dbf
4 changed files with 112 additions and 96 deletions

View File

@ -44,13 +44,13 @@ describe('Dropdown', () => {
) )
const content = wrapper.findComponent({ ref: 'b' }).vm.$refs.popper as any const content = wrapper.findComponent({ ref: 'b' }).vm.$refs.popper as any
const triggerElm = wrapper.find('.el-dropdown-link') const triggerElm = wrapper.find('.el-dropdown-link')
expect(content.value).toBe(false) expect(content.visible).toBe(false)
await triggerElm.trigger(MOUSE_ENTER_EVENT) await triggerElm.trigger(MOUSE_ENTER_EVENT)
await sleep(TIMEOUT) await sleep(TIMEOUT)
expect(content.value).toBe(true) expect(content.visible).toBe(true)
await triggerElm.trigger(MOUSE_LEAVE_EVENT) await triggerElm.trigger(MOUSE_LEAVE_EVENT)
await sleep(TIMEOUT) await sleep(TIMEOUT)
expect(content.value).toBe(false) expect(content.visible).toBe(false)
}) })
test('menu click', async () => { test('menu click', async () => {
@ -117,13 +117,13 @@ describe('Dropdown', () => {
) )
const content = wrapper.findComponent({ ref: 'b' }).vm.$refs.popper as any const content = wrapper.findComponent({ ref: 'b' }).vm.$refs.popper as any
const triggerElm = wrapper.find('.el-dropdown-link') const triggerElm = wrapper.find('.el-dropdown-link')
expect(content.value).toBe(false) expect(content.visible).toBe(false)
await triggerElm.trigger(MOUSE_ENTER_EVENT) await triggerElm.trigger(MOUSE_ENTER_EVENT)
await sleep(TIMEOUT) await sleep(TIMEOUT)
expect(content.value).toBe(false) expect(content.visible).toBe(false)
await triggerElm.trigger(CLICK) await triggerElm.trigger(CLICK)
await sleep(TIMEOUT) await sleep(TIMEOUT)
expect(content.value).toBe(true) expect(content.visible).toBe(true)
}) })
test('split button', async () => { test('split button', async () => {
@ -157,12 +157,12 @@ describe('Dropdown', () => {
const content = wrapper.findComponent({ ref: 'b' }).vm.$refs.popper as any const content = wrapper.findComponent({ ref: 'b' }).vm.$refs.popper as any
const triggerElm = wrapper.find('.el-dropdown__caret-button') const triggerElm = wrapper.find('.el-dropdown__caret-button')
const button = wrapper.find('.el-button') const button = wrapper.find('.el-button')
expect(content.value).toBe(false) expect(content.visible).toBe(false)
await button.trigger('click') await button.trigger('click')
expect((wrapper.vm as any).name).toBe('click') expect((wrapper.vm as any).name).toBe('click')
await triggerElm.trigger(MOUSE_ENTER_EVENT) await triggerElm.trigger(MOUSE_ENTER_EVENT)
await sleep(TIMEOUT) await sleep(TIMEOUT)
expect(content.value).toBe(true) expect(content.visible).toBe(true)
}) })
test('hide on click', async () => { test('hide on click', async () => {
@ -192,7 +192,7 @@ describe('Dropdown', () => {
await sleep(TIMEOUT) await sleep(TIMEOUT)
await wrapper.findComponent({ ref: 'c' }).trigger('click') await wrapper.findComponent({ ref: 'c' }).trigger('click')
await sleep(TIMEOUT) await sleep(TIMEOUT)
expect(content.value).toBe(true) expect(content.visible).toBe(true)
}) })
test('triggerElm keydown', async () => { test('triggerElm keydown', async () => {
@ -224,7 +224,7 @@ describe('Dropdown', () => {
keyCode: eventKeys.enter, keyCode: eventKeys.enter,
}) })
await sleep(TIMEOUT) await sleep(TIMEOUT)
expect(content.value).toBe(false) expect(content.visible).toBe(false)
await triggerElm.trigger(MOUSE_ENTER_EVENT) await triggerElm.trigger(MOUSE_ENTER_EVENT)
await sleep(TIMEOUT) await sleep(TIMEOUT)
@ -232,7 +232,7 @@ describe('Dropdown', () => {
keyCode: eventKeys.tab, keyCode: eventKeys.tab,
}) })
await sleep(TIMEOUT) await sleep(TIMEOUT)
expect(content.value).toBe(false) expect(content.visible).toBe(false)
}) })
test('dropdown menu keydown', async () => { test('dropdown menu keydown', async () => {

View File

@ -1,6 +1,5 @@
<template> <template>
<ul <ul
v-clickOutside:[_trigger]="_hide"
:class="[size && `el-dropdown-menu--${size}`]" :class="[size && `el-dropdown-menu--${size}`]"
class="el-dropdown-menu" class="el-dropdown-menu"
@mouseenter.stop="show" @mouseenter.stop="show"
@ -11,14 +10,10 @@
</template> </template>
<script lang='ts'> <script lang='ts'>
import { defineComponent, getCurrentInstance, onMounted, ref } from 'vue' import { defineComponent, getCurrentInstance, onMounted, ref } from 'vue'
import ClickOutside from '@element-plus/directives/click-outside'
import { useDropdown, initDropdownDomEvent } from './useDropdown' import { useDropdown, initDropdownDomEvent } from './useDropdown'
export default defineComponent({ export default defineComponent({
name: 'ElDropdownMenu', name: 'ElDropdownMenu',
directives: {
ClickOutside,
},
setup() { setup() {
const { _elDropdownSize, elDropdown } = useDropdown() const { _elDropdownSize, elDropdown } = useDropdown()
const size = _elDropdownSize.value const size = _elDropdownSize.value

View File

@ -11,7 +11,6 @@ import {
VNode, VNode,
} from 'vue' } from 'vue'
import { on, addClass, removeClass } from '@element-plus/utils/dom' import { on, addClass, removeClass } from '@element-plus/utils/dom'
import ClickOutside from '@element-plus/directives/click-outside'
import ElButton from '@element-plus/button/src/button.vue' import ElButton from '@element-plus/button/src/button.vue'
import ElButtonGroup from '@element-plus/button/src/button-group.vue' import ElButtonGroup from '@element-plus/button/src/button-group.vue'
import ELPopper from '@element-plus/popper/src/index.vue' import ELPopper from '@element-plus/popper/src/index.vue'
@ -19,9 +18,6 @@ import { useDropdown } from './useDropdown'
export default defineComponent({ export default defineComponent({
name: 'ElDropdown', name: 'ElDropdown',
directives: {
ClickOutside,
},
components: { components: {
ElButton, ElButton,
ElButtonGroup, ElButtonGroup,
@ -225,14 +221,16 @@ export default defineComponent({
class: 'el-dropdown', class: 'el-dropdown',
}, [triggerVnode.value]) }, [triggerVnode.value])
const onVisibleUpdate = (val: boolean) => visible.value = val
return () => h(ELPopper, { return () => h(ELPopper, {
ref: 'popper', ref: 'popper',
placement: props.placement, placement: props.placement,
effect: props.effect, effect: props.effect,
value: visible.value, visible: visible.value,
manualMode: true, 'onUpdate:visible': onVisibleUpdate,
popperClass: 'el-dropdown-popper', popperClass: 'el-dropdown-popper',
trigger: props.trigger, trigger: [props.trigger],
}, { }, {
default: () => slots.dropdown?.(), default: () => slots.dropdown?.(),
trigger: () => dropdownVnode, trigger: () => dropdownVnode,

View File

@ -11,13 +11,15 @@ Hover on the dropdown menu to unfold it for more actions.
<span class="el-dropdown-link"> <span class="el-dropdown-link">
Dropdown List<i class="el-icon-arrow-down el-icon--right"></i> Dropdown List<i class="el-icon-arrow-down el-icon--right"></i>
</span> </span>
<el-dropdown-menu slot="dropdown"> <template #dropdown>
<el-dropdown-item>Action 1</el-dropdown-item> <el-dropdown-menu>
<el-dropdown-item>Action 2</el-dropdown-item> <el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item> <el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item disabled>Action 4</el-dropdown-item> <el-dropdown-item>Action 3</el-dropdown-item>
<el-dropdown-item divided>Action 5</el-dropdown-item> <el-dropdown-item disabled>Action 4</el-dropdown-item>
</el-dropdown-menu> <el-dropdown-item divided>Action 5</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> </el-dropdown>
<style> <style>
@ -44,23 +46,27 @@ Use the button to trigger the dropdown list.
<el-button type="primary"> <el-button type="primary">
Dropdown List<i class="el-icon-arrow-down el-icon--right"></i> Dropdown List<i class="el-icon-arrow-down el-icon--right"></i>
</el-button> </el-button>
<el-dropdown-menu slot="dropdown"> <template #dropdown>
<el-dropdown-item>Action 1</el-dropdown-item> <el-dropdown-menu>
<el-dropdown-item>Action 2</el-dropdown-item> <el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item> <el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 4</el-dropdown-item> <el-dropdown-item>Action 3</el-dropdown-item>
<el-dropdown-item>Action 5</el-dropdown-item> <el-dropdown-item>Action 4</el-dropdown-item>
</el-dropdown-menu> <el-dropdown-item>Action 5</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> </el-dropdown>
<el-dropdown split-button type="primary" @click="handleClick"> <el-dropdown split-button type="primary" @click="handleClick">
Dropdown List Dropdown List
<el-dropdown-menu slot="dropdown"> <template #dropdown>
<el-dropdown-item>Action 1</el-dropdown-item> <el-dropdown-menu>
<el-dropdown-item>Action 2</el-dropdown-item> <el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item> <el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 4</el-dropdown-item> <el-dropdown-item>Action 3</el-dropdown-item>
<el-dropdown-item>Action 5</el-dropdown-item> <el-dropdown-item>Action 4</el-dropdown-item>
</el-dropdown-menu> <el-dropdown-item>Action 5</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> </el-dropdown>
<style> <style>
@ -101,13 +107,15 @@ Click the triggering element or hover on it.
<span class="el-dropdown-link"> <span class="el-dropdown-link">
Dropdown List<i class="el-icon-arrow-down el-icon--right"></i> Dropdown List<i class="el-icon-arrow-down el-icon--right"></i>
</span> </span>
<el-dropdown-menu slot="dropdown"> <template #dropdown>
<el-dropdown-item icon="el-icon-plus">Action 1</el-dropdown-item> <el-dropdown-menu>
<el-dropdown-item icon="el-icon-circle-plus">Action 2</el-dropdown-item> <el-dropdown-item icon="el-icon-plus">Action 1</el-dropdown-item>
<el-dropdown-item icon="el-icon-circle-plus-outline">Action 3</el-dropdown-item> <el-dropdown-item icon="el-icon-circle-plus">Action 2</el-dropdown-item>
<el-dropdown-item icon="el-icon-check">Action 4</el-dropdown-item> <el-dropdown-item icon="el-icon-circle-plus-outline">Action 3</el-dropdown-item>
<el-dropdown-item icon="el-icon-circle-check">Action 5</el-dropdown-item> <el-dropdown-item icon="el-icon-check">Action 4</el-dropdown-item>
</el-dropdown-menu> <el-dropdown-item icon="el-icon-circle-check">Action 5</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> </el-dropdown>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -116,13 +124,15 @@ Click the triggering element or hover on it.
<span class="el-dropdown-link"> <span class="el-dropdown-link">
Dropdown List<i class="el-icon-arrow-down el-icon--right"></i> Dropdown List<i class="el-icon-arrow-down el-icon--right"></i>
</span> </span>
<el-dropdown-menu slot="dropdown"> <template #dropdown>
<el-dropdown-item icon="el-icon-plus">Action 1</el-dropdown-item> <el-dropdown-menu>
<el-dropdown-item icon="el-icon-circle-plus">Action 2</el-dropdown-item> <el-dropdown-item icon="el-icon-plus">Action 1</el-dropdown-item>
<el-dropdown-item icon="el-icon-circle-plus-outline">Action 3</el-dropdown-item> <el-dropdown-item icon="el-icon-circle-plus">Action 2</el-dropdown-item>
<el-dropdown-item icon="el-icon-check">Action 4</el-dropdown-item> <el-dropdown-item icon="el-icon-circle-plus-outline">Action 3</el-dropdown-item>
<el-dropdown-item icon="el-icon-circle-check">Action 5</el-dropdown-item> <el-dropdown-item icon="el-icon-check">Action 4</el-dropdown-item>
</el-dropdown-menu> <el-dropdown-item icon="el-icon-circle-check">Action 5</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> </el-dropdown>
</el-col> </el-col>
</el-row> </el-row>
@ -155,13 +165,15 @@ Use `hide-on-click` to define if menu closes on clicking.
<span class="el-dropdown-link"> <span class="el-dropdown-link">
Dropdown List<i class="el-icon-arrow-down el-icon--right"></i> Dropdown List<i class="el-icon-arrow-down el-icon--right"></i>
</span> </span>
<el-dropdown-menu slot="dropdown"> <template #dropdown>
<el-dropdown-item>Action 1</el-dropdown-item> <el-dropdown-menu>
<el-dropdown-item>Action 2</el-dropdown-item> <el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item> <el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item disabled>Action 4</el-dropdown-item> <el-dropdown-item>Action 3</el-dropdown-item>
<el-dropdown-item divided>Action 5</el-dropdown-item> <el-dropdown-item disabled>Action 4</el-dropdown-item>
</el-dropdown-menu> <el-dropdown-item divided>Action 5</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> </el-dropdown>
<style> <style>
@ -186,13 +198,15 @@ Clicking each dropdown item fires an event whose parameter is assigned by each i
<span class="el-dropdown-link"> <span class="el-dropdown-link">
Dropdown List<i class="el-icon-arrow-down el-icon--right"></i> Dropdown List<i class="el-icon-arrow-down el-icon--right"></i>
</span> </span>
<el-dropdown-menu slot="dropdown"> <template #dropdown>
<el-dropdown-item command="a">Action 1</el-dropdown-item> <el-dropdown-menu>
<el-dropdown-item command="b">Action 2</el-dropdown-item> <el-dropdown-item command="a">Action 1</el-dropdown-item>
<el-dropdown-item command="c">Action 3</el-dropdown-item> <el-dropdown-item command="b">Action 2</el-dropdown-item>
<el-dropdown-item command="d" disabled>Action 4</el-dropdown-item> <el-dropdown-item command="c">Action 3</el-dropdown-item>
<el-dropdown-item command="e" divided>Action 5</el-dropdown-item> <el-dropdown-item command="d" disabled>Action 4</el-dropdown-item>
</el-dropdown-menu> <el-dropdown-item command="e" divided>Action 5</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> </el-dropdown>
<style> <style>
@ -226,42 +240,51 @@ Besides default size, Dropdown component provides three additional sizes for you
```html ```html
<el-dropdown split-button type="primary"> <el-dropdown split-button type="primary">
Default Default
<el-dropdown-menu slot="dropdown"> <template #dropdown>
<el-dropdown-item>Action 1</el-dropdown-item> <el-dropdown-menu>
<el-dropdown-item>Action 2</el-dropdown-item> <el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item> <el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 4</el-dropdown-item> <el-dropdown-item>Action 3</el-dropdown-item>
</el-dropdown-menu> <el-dropdown-item>Action 4</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> </el-dropdown>
<el-dropdown size="medium" split-button type="primary"> <el-dropdown size="medium" split-button type="primary">
Medium Medium
<el-dropdown-menu slot="dropdown"> <template #dropdown>
<el-dropdown-item>Action 1</el-dropdown-item> <el-dropdown-menu>
<el-dropdown-item>Action 2</el-dropdown-item> <el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item> <el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 4</el-dropdown-item> <el-dropdown-item>Action 3</el-dropdown-item>
</el-dropdown-menu> <el-dropdown-item>Action 4</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> </el-dropdown>
<el-dropdown size="small" split-button type="primary"> <el-dropdown size="small" split-button type="primary">
Small Small
<el-dropdown-menu slot="dropdown"> <template #dropdown>
<el-dropdown-item>Action 1</el-dropdown-item> <el-dropdown-menu>
<el-dropdown-item>Action 2</el-dropdown-item> <el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item> <el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 4</el-dropdown-item> <el-dropdown-item>Action 3</el-dropdown-item>
</el-dropdown-menu> <el-dropdown-item>Action 4</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> </el-dropdown>
<el-dropdown size="mini" split-button type="primary"> <el-dropdown size="mini" split-button type="primary">
Mini Mini
<el-dropdown-menu slot="dropdown"> <template #dropdown>
<el-dropdown-item>Action 1</el-dropdown-item> <el-dropdown-menu>
<el-dropdown-item>Action 2</el-dropdown-item> <el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item> <el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 4</el-dropdown-item> <el-dropdown-item>Action 3</el-dropdown-item>
</el-dropdown-menu> <el-dropdown-item>Action 4</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> </el-dropdown>
``` ```
::: :::