繁体   English   中英

如果我们在 vuejs 的菜单外单击,如何隐藏下拉菜单

[英]how to hide dropdown menu if we click outside the menu in vuejs

我在 vuejs 中使用dropdown菜单组件来制作普通的下拉菜单。 我的dropdown组件代码是:

<template>
    <span class="dropdown" :class="{shown: state}">
        <a href="#" @click.prevent="toggleDropdown" class="dropdown-toggle">toggle menu</a>
            <div class="dropdown-menu" v-show="state">
                <ul class="list-unstyled">
                    <slot></slot>
                </ul>
            </div>
        </transition>
    </span>
</template>

<script>
export default {
    name: 'dropdown',
    data () {
        return {
            state: false
        }
    },
    methods: {
        toggleDropdown (e) {
            this.state = !this.state;
        }
    }
}
</script>

现在我通过在模板中使用以下代码在我的VUE应用程序中的不同位置导入dropdown组件

<dropdown>
    <li>
         Action
    </li>
</dropdown>

现在工作正常,但我希望同时只有一个下拉菜单处于活动状态。

我做了很少的研究,发现我可以使用像https://github.com/davidnotplay/vue-my-dropdown这样的插件,但我不想使用它。 同样,我还研究了上述示例的工作原理,但我想以这样一种方式实现此下拉功能,即我的dropdown组件将处理与下拉相关的所有事件。 那么你能帮我实现这个目标吗?

看看vue-clickaway。( 链接

有时您需要检测元素外部的点击(以关闭模式窗口或隐藏下拉选择)。 没有本地事件,并且Vue.js也不涵盖您。 这就是存在vue-clickaway的原因。 在进一步阅读之前,请查看演示。

我知道这是一个很老的问题,但是我认为没有任何外部插件的最佳方法是在安装的生命周期挂钩中添加一个Click侦听器(并在beforeDestroy挂钩上将其删除)并过滤组件上的点击,以便仅在以下情况下隐藏在外面点击。

<template>
    <span class="dropdown" :class="{shown: state}">
      <a href="#" @click.prevent="toggleDropdown" class="dropdown-toggle">toggle menu</a>
            <div class="dropdown-menu" v-show="state">
                <ul class="list-unstyled">
                    <slot></slot>
                </ul>
            </div>
        <transition/>
    </span>
</template>

<script>
export default {
  name: 'dropdown',
  data () {
    return {
      state: false
    }
  },
  methods: {
    toggleDropdown (e) {
      this.state = !this.state
    },
    close (e) {
      if (!this.$el.contains(e.target)) {
        this.state = false
      }
    }
  },
  mounted () {
    document.addEventListener('click', this.close)
  },
  beforeDestroy () {
    document.removeEventListener('click',this.close)
  }
}
</script>

在 Vue 3 中,以下应该有效

请注意,下拉触发器和下拉内容上的@click.stop阻止文档事件执行关闭功能。

<template>
  <div class="dropdown" :class="{'is-active': dropdown.active.value}">
    <div class="dropdown-trigger">
      <button class="button" @click.stop="dropdown.active.value = !dropdown.active.value">
        Toggle
      </button>
    </div>
    <div class="dropdown-menu" role="filter">
      <div class="dropdown-content" @click.stop>
        <!-- dropdown items -->
      </div>
    </div>
  </div>
</template>

<script>

import { defineComponent, ref, onMounted, onBeforeUnmount } from "vue";

export default defineComponent({
  name: "Dropdown",
  setup(){
    const dropdown = {
      active: ref(false),
      close: () => {
        dropdown.active.value = false
      }
    }

    onBeforeUnmount(() => {
      document.removeEventListener('click', dropdown.close)
    })

    onMounted(() => {
      document.addEventListener('click', dropdown.close)
    })

    return {
      dropdown
    }
  }
})

</script>

此示例使用bulma但当然您不需要。

您可以利用blur事件,例如,如果添加方法:

close() {
    setTimeout(() => {
        this.state = false;
    }, 200);
}

并为您的链接设置blur事件:

<a href="#" @click.prevent="toggleDropdown" @blur="close">toggle menu</a>

然后,每当您的切换链接失去焦点时,下拉列表都将被隐藏。 setTimeout是必需的,因为Java单击事件在模糊后发生,这将导致下拉链接不可单击。 要变通解决此问题,延迟菜单隐藏一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM