尝试使用v-on:blur来使上下文菜单消失,但它不起作用。

6
我正在使用vue.js编写一个简单的上下文菜单。当我在特定元素上右键单击时,它会打开菜单(使用@contextmenu.prevent)。这个功能有效。
但是,当我在菜单外面点击时,我希望菜单消失。但这不起作用...我使用v-on:blur尝试了解决这个问题,也试过@blur。但都没有成功。以下是我的HTML代码:
<!-- my context menu -->
<ul class="context-menu"
    ref="contextMenuTrack"
    v-if="openedMenu === 'contextMenuTrack'"
    v-bind:style="{top: top, left: left}"
    v-on:blur="closeMenu()">
    <li v-on:click="removeTrack(project.structure.tracks.indexOf(targetOfMenu));closeMenu()">delete track</li>
</ul>
<div>

    [ ...... stuff here ......]

    <!-- Where the menu is called-->
    <li class="track"
         v-for="track in project.structure.tracks">
        <div class="track-name-row">
            <li @contextmenu.prevent="openContextMenuTrack(track,$event)"
                v-on:click="expandTrack(project.structure.tracks.indexOf(track))"
                class="track-color-viewer"></li>

                [ .... other li tags .....]
        </div>
    </li>

    [ ...... stuff here ......]

</div>

这里是用于我的Vue组件菜单的数据:

data() {
    return {
        //the kind of menu which is opened
        openedMenu: undefined,
        //the coordinate of the menu
        top: "0px",
        left: "0px",
        //the element which is targeted by the menu
        targetOfMenu: undefined
    };
},

以下是我在Vue.js组件中用于菜单的方法:

 methods: {

    setMenu(top, left) {
        this.top = top - 170 + "px";
        this.left = left + "px";
    },

    // opening menu : calling set menu whith x and y
    openContextMenuTrack(track, event) {
        this.openedMenu = "contextMenuTrack";
        this.targetOfMenu = track;

        this.$nextTick((() => {
            this.$refs.contextMenuTrack.focus();
            this.setMenu(event.y, event.x);
        }).bind(this));
    },

    closeMenu() {
        this.openedMenu = undefined;
        this.targetOfMenu = undefined;
    }
}
3个回答

9

blur事件仅适用于表单控件(<input>等)。

您的问题通常可以通过创建自定义指令来解决,该指令在点击菜单外部时运行方法。

类似于下面的代码:

https://www.npmjs.com/package/v-click-outside

<ul class="context-menu"
    ref="contextMenuTrack"
    v-if="openedMenu === 'contextMenuTrack'"
    v-bind:style="{top: top, left: left}"

    v-click-outside="closeMenu()">

    <li v-on:click="removeTrack(project.structure.tracks.indexOf(targetOfMenu));closeMenu()">delete track</li>
</ul>

希望这能有所帮助。 编辑: 使用更好的包(vue-clickaway)的示例:

https://jsfiddle.net/Linusborg/hqkgp4hm/


非常感谢。我将检查v-click-outside,如果它有效,我会验证您的答案 :) - Bénédicte Lagouge
它的表现并不是很好。事实上,当我点击元素之外的区域时,菜单就会关闭。但是当我点击菜单选项时,菜单会关闭而不执行与该选项相关联的操作。有什么建议吗? - Bénédicte Lagouge
我在上面的回答中添加了一个更好的包示例。 - Linus Borg

2
这可能有所帮助,如果你在寻找不推荐的方法 ;) 在$refs上得到相同结果会有些棘手。
let x = document.querySelector('.targetClass).addEventListener('click', (e) => 
{
  if(e.target.className == 'targetClass') {
    this.close()
  }
 })

0

我刚在一个项目中做了这个:

  created: function() {
    let self = this;
    window.addEventListener("click", function(e) {
      if (self.$el.querySelector('.targetClass') && !self.$el.querySelector('.targetClass').contains(e.target)) {
        this.close()
      }
    });
  },
  destroyed: function(){
    let self = this;
    window.removeEventListener("click", function(e) {
      if (self.$el.querySelector('.targetClass') && !self.$el.querySelector('.targetClass').contains(e.target)) {
        this.close()
      }
    });
  },

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接