代码之家  ›  专栏  ›  技术社区  ›  agm1984

如果父组件中的元素被v-if删除,则在beforestroy生命周期方法中删除事件侦听器不起作用

  •  0
  • agm1984  · 技术社区  · 5 年前

    基本上,我使用的datepicker库不会发出焦点或模糊事件,因此需要手动添加它们,但由于上游的原因,删除事件侦听器时遇到问题 v-if .

    我是这样做的:

    <datepicker :id="datePickerId">
    

    ...

    computed: {
        datePickerId() { return `date-picker-${this.name}`; },
    },
    
    mounted() {
        document.getElementById(this.datePickerId).addEventListener('focus', this.handleFocus);
        document.getElementById(this.datePickerId).addEventListener('blur', this.handleBlur);
    },
    
    beforeDestroy() {
        document.getElementById(this.datePickerId).removeEventListener('focus', this.handleFocus);
        document.getElementById(this.datePickerId).removeEventListener('blur', this.handleBlur);
    },
    

    在我的组件通过 v型中频 ,例如:

    <my-datepicker v-if="isDisplayed">
    

    我已经研究过了,问题似乎是由于 v型中频 但是VUE实例仍然存在,所以 beforeDestroy 生命周期方法在元素已消失后调用。

    除了省略清理步骤和依赖现代浏览器垃圾收集之外,还有什么方法可以防止内存泄漏?

    我非常有兴趣了解更多关于如何更好地控制这段时间发生的事情 v型中频 变得迟钝。关于这个“不合时宜的时刻”的文章/问题/票子不多,所以如果有人有任何相关的输入,请随时添加。

    有没有其他方法可以利用第三方库的输入焦点/模糊事件?

    [Vue warn]:beforeDestroy钩子出错:“TypeError:无法读取null的属性'removeEventListener'”

    0 回复  |  直到 5 年前
        1
  •  0
  •   agm1984    5 年前

    在Vue团队的Chris Fritz的快速指导下,我能够解决这个问题。他说看看活动授权,所以我找到了一个解决方案 focusin focusout .

    我以前读过,现代浏览器在删除DOM元素时会自动垃圾收集事件侦听器。内存泄漏只不过是IE7的一个问题,克里斯说VUE本身甚至不支持IE7,所以存在一个替代的解决方案,在这里你可以简单地不删除事件侦听器。这个 beforeDestroy 生命周期可能被删除。

    但是,我更喜欢使用事件委派的解决方案:

    下面是解决此问题的标记:

    <div @focusin="handleFocus" @focusout="handleBlur">
        <datepicker
            @input="handleChange"
            :name="name"
        ></datepicker>
    </div>
    

    ...

    methods: {
        handleFocus() { console.log('focus in'); this.$emit('focus'); },
        handleBlur() { console.log('focus out'); this.$emit('blur'); },
    },
    

    您可以在MDN文档中进一步阅读:

    https://developer.mozilla.org/en-US/docs/Web/API/Element/focusin_event

    https://developer.mozilla.org/en-US/docs/Web/API/Element/focusout_event

    另外,有问题的datepicker库被调用 vuejs-datepicker ,而且这比吞咽更棒 focus blur 事件。