这个常见的问题,我发现现在网上的很多方法,不是极其繁琐就是有问题。
比如下面这个:
<template>
<div class="nian">
<div class="selectBox" @click.stop="isshow=!isshow">
<div>选择年份:</div>
<div>
<div>2022年</div>
<img src="../assets/images/down.png" alt="">
</div>
</div>
<div v-show="isshow" class="list" ref="drop">
<div>2021年</div>
<div>2022年</div>
</div>
</div>
</template>
<script>
export default {
name: 'xiala',
components: {},
data: () => ({
isshow:false
}),
computed: {},
watch: {},
mounted() {
document.addEventListener('click', this.clickOut)
},
methods: {
// 当点击菜单以外的区域隐藏菜单
clickOut(e) {
let drop = this.$refs.drop
if (drop && !drop.contains(e.target) && this.isshow) {
this.isshow = false
}
},
},
created() {},
destroyed() {},
}
</script>
乍一看逻辑没什么问题,但是我使用的时候发现,当点击展示下拉框,isshow赋值为true的时候,因为出现了点击行为,clickOut也会调用,isshow又被重新赋值为false了,这样下拉框就不会展示了。所以我们还需要获取点击出现下拉框的元素,把他也同时排除在外。
像这样:
<template>
<div class="nian">
<div ref="term" class="selectBox" @click.stop="isshow=!isshow">
<div>选择年份:</div>
<div>
<div>2022年</div>
<img src="../assets/images/down.png" alt="">
</div>
</div>
<div v-show="isshow" class="list" ref="drop">
<div>2021年</div>
<div>2022年</div>
</div>
</div>
</template>
<script>
export default {
name: 'xiala',
components: {},
data: () => ({
isshow:false
}),
computed: {},
watch: {},
mounted() {
document.addEventListener('click', this.clickOut)
},
methods: {
// 当点击菜单以外的区域隐藏菜单
clickOut(e) {
let drop = this.$refs.drop
let term = this.$refs.term
if (drop && !drop.contains(e.target) && term && !term.contains(e.target) && this.isshow) {
this.isshow = false
}
},
},
created() {},
destroyed() {},
}
</script>