vue scoped,子组件的根节点依然受其父组件的CSS 的影响
我们都知道,vue scoped 的作用是避免 css 全局作用域的影响
以下截图来自vue-loader 官网页面对scoped css 原理的介绍
官网文档上也说明了子组件根元素会受到父组件同名css样式影响,截图如下
文档中提到,子组件根节点样式会受到父组件样式影响,这样设计是为了让父组件可以从布局的角度出发,调整其子组件根元素的样式。
但是,现在,我不希望子组件根元素样式受到父组件影响,怎么做呢?
我们先来看一下,具体是怎么相互影响的呢?
父组件
<template> <div class="root"> <span>父组件</span> <child-component></child-component> </div> </template> <script> import Child from "./child"; export default { components: { "child-component": Child } }; </script> <style scoped> .root { color: green; padding: 40px; } </style>
父组件中给根元素添加字体绿色和 padding 间距
子组件
<template> <div class="root"> <span>子组件</span> </div> </template> <script> export default {}; </script> <style scoped> .root { background-color: red; } </style>
子组件只添加了背景色红色
结果
结果显示子组件被额外添加了 padding 样式(这非预想设计的样式)
分析
本来子组件中我们通过 .root 给了背景色样式为红色,但是在父组件中由于我们意外给了一个同名 .root 样式,导致我们给子组件额外添加了padding间距(注:字体色理论上由于继承关系也会显示为绿色,我们暂不考虑这个)。
原因,因为父组件的生成的唯一标识 'data-v-a83bd3b0' ,也会给子组件根元素加上这个标识,巧合的是,子组件根元素具有 .root 的选择器,刚好使得 .root[data-v-a83bd3b0] 生效。
即使得该样式生效了
通过以上分析,我们知道,以上问题(样式干扰)由两个条件产生:
①,父组件唯一标识符属性 data-v-id 也会被添加到 子组件根元素上
②,子组件根元素上具有和父组件同名class
解决问题方案(解决原理是将上述任意一个条件使得它不成立,那么问题就不会产生啦)
方案一,避免父组件使用和子组件根元素同名 class(往往很难避免,还需要页面调试查看子组件根元素className)
方案二,给子组件根元素添加一层 div,不添加 class样式(这样的话,父组件生成的data-v-id 便会在该div上,从而使得)推荐
如图使用方案二,这样就避免啦问题
vue插槽内的样式冲突问题
vue插槽打包之后,插槽中的所有内容,均会被打上组件唯一标识id,若在插槽中存在和提供插槽组件存在同名class样式,也会产生冲突问题。如下图所示
目前解决方案,如图中所示,换一个不同名字的class名字