在 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/