63 lines
1.4 KiB
Vue
63 lines
1.4 KiB
Vue
<template>
|
|
<button type="button" @click="show = true">
|
|
<slot />
|
|
<portal v-if="show" to="dropdown">
|
|
<div>
|
|
<div style="position: fixed; top: 0; right: 0; left: 0; bottom: 0; z-index: 99998; background: black; opacity: .2" @click="show = false" />
|
|
<div ref="dropdown" style="position: absolute; z-index: 99999;" @click.stop="show = autoClose ? false : true">
|
|
<slot name="dropdown" />
|
|
</div>
|
|
</div>
|
|
</portal>
|
|
</button>
|
|
</template>
|
|
|
|
<script>
|
|
import Popper from 'popper.js'
|
|
|
|
export default {
|
|
props: {
|
|
placement: {
|
|
type: String,
|
|
default: 'bottom-end',
|
|
},
|
|
boundary: {
|
|
type: String,
|
|
default: 'scrollParent',
|
|
},
|
|
autoClose: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
show: false,
|
|
}
|
|
},
|
|
watch: {
|
|
show(show) {
|
|
if (show) {
|
|
this.$nextTick(() => {
|
|
this.popper = new Popper(this.$el, this.$refs.dropdown, {
|
|
placement: this.placement,
|
|
modifiers: {
|
|
preventOverflow: { boundariesElement: this.boundary },
|
|
},
|
|
})
|
|
})
|
|
} else if (this.popper) {
|
|
setTimeout(() => this.popper.destroy(), 100)
|
|
}
|
|
},
|
|
},
|
|
mounted() {
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.keyCode === 27) {
|
|
this.show = false
|
|
}
|
|
})
|
|
},
|
|
}
|
|
</script>
|