对于悬浮窗一类的组件,组件里的内容往往需要渲染在父组件以外的地方,比如<body>
,此时组件内需要做如下操作:
- 在组件中为需要渲染到
<body>
上的DOM加上ref
,比如<div ref="container"></div>
,以索引到对应的DOM,可以是组件中最顶层的DOM。 - 调用
document.body.appendChild(this.$refs.container)
,将目标DOM移动到<body>
上,可以在mounted()
生命周期中调用,也可以在第一次打开悬浮窗时调用。在组件被销毁前,只能调用一次,否则极易导致页面崩溃!! - 如果目标DOM已经被移动到
<body>
上了,则需要在beforeDestroy()
生命周期中手动将目标DOM从<body>
中删除。否则将导致有无用DOM残留在页面上,造成内存泄漏!!
这样可以防止因弹出框不在<body>
上而导致出现悬浮窗被意外遮挡等问题。
注意
此类操作对于Vue.js
而言为非正常操作,极易导致页面出现问题,比如:
- 虚拟DOM和页面上的真实DOM不一致,导致页面逻辑错乱、页面崩溃甚至浏览器崩溃。
- 可能出现大量无用DOM没有及时删除并残留在
<body>
上,易导致页面卡顿、崩溃、甚至浏览器崩溃。
因此此类操作需要在项目中的公共组件中实现,且在项目中推广开前需要进行全面的测试;不到万不得已不要在和业务高度相关、复用率低的组件中实现,以防止代码逻辑陷入混乱。
范例
以下是一个简单的对话框组件的代码:
<template>
<div class='dialog-container'
ref='dialogContainer'
v-show='this.visible'