vue3 中设置 teleport 组件后设置样式不起作用?
在 vue3 的实际开发中,我们经常会用到 teleport 内置组件来将要展示的模态框传送到 body 等外层元素上挂载并展示,主要解决的一种常见场景为:当前模态框需要更高的层级,但是模态框本身外层元素的 z-index 层级比较低,会导致模态框被其他元素覆盖。
实际使用如下
<button @click="open = true">Open Modal</button> <Teleport to="body"> <div v-if="open" class="modal"> <p>Hello from the modal!</p> <button @click="open = false">Close</button> </div> </Teleport>
但当我们给模态框上的 class 写 css 样式的时候,发现模特框样式根本无法生效,但是模态框下的子元素比如 title 样式可以生效
<template> <button @click="open = true">Open Modal</button> <Teleport to="body"> <div v-if="open" class="modal"> <p class="title">Hello from the modal!</p> <button @click="open = false">Close</button> </div> </Teleport> </template> <style lang="less" scoped> .modal{ color: green; .title{ color: red; } } </style>
原因为,使用了<style scoped>,那么样式将只对当前组件中的元素生效。但是,Teleport组件的子组件实际上是在DOM的其他位置渲染的。为了让样式生效,需要将样式设置为全局样式(不使用scoped)
可以单独写一个全局的非 scoped 样式来解决。
<template> <button @click="open = true">Open Modal</button> <Teleport to="body"> <div v-if="open" class="modal"> <p class="title">Hello from the modal!</p> <button @click="open = false">Close</button> </div> </Teleport> </template> <style lang="less"> .modal{ color: green; .title{ color: red; } } </style>
但是,如果尝试使用:deep()
这个深度选择器解决,发现会导致整个模态框样式包括子元素都无法生效。。。。