自定义指令继续进行组件渲染

时间:2017-07-19 12:58:27

标签: javascript vue.js vuejs2 vue-component

我正在使用此帖子中的自定义click-outside指令:

Detect click outside element

这是我的元素:

<div class="datepicker panel panel-default" v-click-outside="close">

自定义指令:

module.exports = {
    bind(el, binding, vnode) {
        el.event = (event) => {
            // Check that click was outside the el and his children.
            if (!(el === event.target || el.contains(event.target))) {
                console.log('Clicked outside');

                // Call the method provided as the attribute value.
                vnode.context[binding.expression](event);
            }
        };

        document.body.addEventListener('click', el.event);
    },

    unbind(el) {
        document.body.removeEventListener('click', el.event);
    }
};

它有效,据我所知,绑定发生在元素的渲染上。因为我只希望在我的日期选择器出现时注册click事件,所以我用v-if包装它。

问题在于,当我使用按钮切换日期选择器上v-if的显示时,指令中的close方法会立即触发。

似乎bind内的事件在元素被显示之前发生,因此它立即关闭,根本不显示任何内容。

这看起来很奇怪,按钮负责显示datepicker,我希望在datepicker渲染时发生绑定。不是在同一时间或之前。

现在它似乎甚至在元素完全渲染之前就已经发生了。这会导致我的显示按钮导致v-click-outside事件。

造成这种情况的原因是什么?

修改

制作一个Jsfiddle来演示这个问题(打开控制台):

https://jsfiddle.net/stephanv/qqjnngdz/2/

1 个答案:

答案 0 :(得分:1)

听起来绝对符合逻辑。这是发生的事情:

  1. 点击“显示日期选择器”,实际上是按钮
  2. 调用
  3. show方法,因为在按钮上有@click="show"
  4. visible属性更改为true。

  5. 由于点击事件

  6. ,评估该指令
  7. if-else到位,声明el(带指令的div)与event.target(按钮)不同
  8. 由于if-else就在

  9. 之前调用了绑定表达式(hide
  10. hide函数被调用,visible属性设置为false,因此组件被隐藏!

  11. 与示例相比,您在此处缺少的是另一个目标(案例中的按钮)中打开日期选择器。这意味着默认情况下, ARE 在元素外部单击以显示它。

    您有两个选项 - 一个是检查日期选择器的当前状态 - 添加另一个属性(justOpened),在true内将其设置为show,当您检查是否它是否在外部点击,如果属性为true,则将其设置为false返回。这样你就可以“跳过”这样的一件事。

    如果您只是这样做,则不需要所有这些:

    <button type="button" @click.stop="show">Show datepicker</button>
    

    .stop修饰符实际上会在本机点击事件上调用stopImmediatePropagation(),因此当您单击此按钮时,您的指令将不会被调用。它就像一个魅力,但要注意,如果你打开日期选择器,然后再次单击相同的按钮,日期选择器将不会被隐藏(因为它不会知道你已经点击了外面)!

    希望有所帮助:)