vue3处理css样式 :deep() 没有作用
<style lang="scss" scoped>.el-dialog :deep(.el-dialog__body) {
height: 500px;
overflow: auto;
}
</style>
请问为什么样式穿透没有效果?
https://vuejs.org/api/sfc-css...
我不知道是我写的有问题还是vue3这块有问题,有点折磨
回答:
<style lang="scss" scoped>.el-dialog :deep(.el-dialog__body) {
height: 500px;
overflow: auto;
}
</style>
上面代码不生效的原因是 .el-dialog
并不是当前组件中的 class。它是 element plus 组件中的 class。编译当前 .vue 文件时它没有被当前 .vue 中 template 元素匹配到。
可以这么写 style:
:deep(.el-dialog__body) { background-color: red;
}
先看这个例子:
<script setup>import { ref } from "vue";
const dialogVisible = ref(false);
</script>
<template>
<div>
<el-button @click="dialogVisible = true"
>click to open the Dialog</el-button
>
<el-dialog
v-model="dialogVisible"
title="Tips"
width="30%"
:before-close="handleClose"
custom-class="my-dialog"
>
Lorem ipsum dolor sit amet.
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="dialogVisible = false"
>Confirm</el-button
>
</span>
</template>
</el-dialog>
</div>
</template>
<style scoped>
:deep(.el-dialog__body) {
background-color: red;
}
</style>
正如你所见,它生效了。此时组件样式被编译器处理成:
组件 template 被处理成这样:
需要注意的是,当前 template 中给出了单个组件根节点。上面示例中组件根节点是 div。
如果我们去掉根节点,其他条件保持不变,当前组件的 template 会是这样:
<template> <el-button @click="dialogVisible = true">click to open the Dialog</el-button>
<el-dialog
v-model="dialogVisible"
title="Tips"
width="30%"
:before-close="handleClose"
custom-class="my-dialog"
>
Lorem ipsum dolor sit amet.
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="dialogVisible = false"
>Confirm</el-button
>
</span>
</template>
</el-dialog>
</template>
此时 style 依然被处理成这样:
正如你所见,深度选择器是不会生效的:
由于我们给 style 添加了 scoped,当前组件编译后的样式自动添加了用于表示样式作用域的选择器,而这个“表示样式作用域的选择器”默认对应组件的唯一根节点,但是我们没有唯一根节点。
上面已经给出了一种解决方法了:
- 组件要包含一个根节点
- 还要再 style 中使用
:deep()
我们来思考更好的做法。显然上面的解决办法中虽然直接更改了 element 组件的的 class,但是仅在作用域内生效,并无不妥。
但是常规的做法是尽量不直接修改组件库组件的的 class。例如提问中的例子我们可以修改插入元素的根节点高度。
<template> <div>
<el-button @click="dialogVisible = true"
>click to open the Dialog</el-button
>
<el-dialog
v-model="dialogVisible"
title="Tips"
width="30%"
:before-close="handleClose"
custom-class="my-dialog"
>
<div class="my-dialog-content">
<p>Lorem ipsum dolor sit amet.</p>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="dialogVisible = false"
>Confirm</el-button
>
</span>
</template>
</el-dialog>
</div>
</template>
<style scoped>
.my-dialog-content {
height: 200px;
}
</style>
.my-dialog-content
即是作为插槽内容的根节点 class,修改此 class 以达到等同更改 .el-dialog__body
的效果。
如果不是仅仅修改单组组件中组件库的样式,对于 element plus,可以通过修改 theme 文件中样式变量以达到全局修改的效果。
或者直接在任意组件中通过 vue3 提供的 :global()
修改全局样式。以题中的例子为例:
<style scoped>:global(.el-dialog__body) {
background: red;
}
</style>
既然是全局样式,当然与组件是否有单个根节点无关了。
回答:
vue2中element-ui中的dialog是挂载在body上的,也就是说你需要设置全局样式去改,而不能设置scoped样式,不知道element-plus中是不是这样,你可以看看,而且deep不应该放在body前面,应该放在dialog类前面
以上是 vue3处理css样式 :deep() 没有作用 的全部内容, 来源链接: utcz.com/p/937099.html