如果我们在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 组件将处理与下拉菜单相关的所有事件。 那么你能帮我实现这个目标吗?

原文由 Rakesh Soni 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 366
2 个回答

我知道这是一个相当古老的问题,但我认为最好的方法是在没有任何外部插件的情况下做到这一点,即向已安装的生命周期挂钩添加一个点击侦听器(并在 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>

原文由 kgolinski 发布,翻译遵循 CC BY-SA 4.0 许可协议

在 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 但当然您不需要。

原文由 ssten 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题