vue-component - Vue 3 如果 onbeforeprint 和 onafterprint 在 onMounted 中设置,我是否需要在 onBeforeUnmount 中重置它们(以及如何重置)?

标签 vue-component vuejs3 onbeforeprint

在 VUE 3 组件中,我这样设置了 onBeforePrint 和 onAfterPrint:

onMounted(() => {
  window.onbeforeprint = () => {
    clearPlaceholders();
  };
  window.onafterprint = () => {
    setPlaceholders();
  };
});

当页面卸载时,我是否需要取消设置这些设置?如果需要,取消设置这些设置的最佳实践是什么?

最佳答案

onMounted 中的外部元素上添加监听器1(主体、窗口、文档、祖先等...)应删除 onBeforeUnmount 中的钩子(Hook) Hook 2

import { onMounted, onBeforeUnmount } from 'vue'
//...

  onMounted(() => {
    window.addEventListener('beforeprint', clearPlaceholders)
    window.addEventListener('afterprint', setPlaceholders)
  })

  onBeforeUnmount(() => {
    window.removeEventListener('beforeprint', clearPlaceholders)
    window.removeEventListener('afterprint', setPlaceholders)
  })

//...

重要提示:要删除先前绑定(bind)的监听器,必须将相同的事件名称和处理程序传递给 removeEventListener 当这些传递到addEventListener时.
换句话说,运行相同处理程序的单独箭头函数是单独的处理程序,因为:

const a = () => clearPlaceholders()
const b = () => clearPlaceholders()
console.log(a === b) // false

// So this wouldn't work:
target.addEventListener(eventName, a)
target.removeEventListener(eventName, b)  // ❌ fails

// the listener is removed by:
target.removeEventListener(eventName, a)  // ✅ succeeds

阅读matching event listeners for removal了解详情。


1 - 组件模板中包含的元素不需要清理,因为当 DOM 元素被删除时,它们会被垃圾回收。

2 - 无法在 onUnmounted 中删除监听器如果它(监听器)是在组件内部定义的,则 Hook ,因为当时 onUnmounted钩子(Hook)被触发组件内容已被删除(公平地说,onAfterUnmounted对于理解此钩子(Hook)何时被触发更有用)。


减少样板文件(可选)

如果您发现自己必须在外部目标上添加/删除大量事件,则可以使用可组合项来减少样板:

import { useEventListener } from './useEventListener'

  //...
  useEventListener(window, 'beforeprint', clearPlaceholders)
  useEventListener(window, 'afterprint', setPlaceholders)
  useEventListener(window, 'scroll', onScrollHandler, { passive: true })
  useEventListener(document.body, 'click', onBodyClickHandler, {
    capture: true
  })

可组合项 - useEventListener.js - 看起来像这样:

import { onMounted, onBeforeMount } from 'vue'

export const useEventListener = (target, ...args) => {
  onMounted(() => {
    target.addEventListener(...args)
  })
  onBeforeUnmount(() => {
    target.removeEventListener(...args)
  })
}

请注意,此可组合项只能在 setup() 中使用(或<script setup>)。

关于vue-component - Vue 3 如果 onbeforeprint 和 onafterprint 在 onMounted 中设置,我是否需要在 onBeforeUnmount 中重置它们(以及如何重置)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75815977/

相关文章:

javascript - 是否可以在按下按钮时附加组件?

javascript - Vue.Js(2) : Property or method "hideModel" is not defined on the instance but referenced during render

vue.js - 在现有网页中使用没有 npm 的组件

javascript - Vue2 - 将普通 ONKEYPRESS 函数转换为方法

javascript - Vuejs 3 webpack : Problem with vue-template-compiler

vue.js - Module parse failed : Unexpected token (3:27) in Vue 3 project如何解决

vuejs3 - 如何在vuejs中制作动态表单

javascript - 打印 Firefox/Chrome 后关闭选项卡(内容为 application/pdf)

javascript - 从 javascript 中的 onbeforeprint 中排除特定元素

javascript - 在 beforeprint 事件上使用 JQuery