vue scoped,子组件的根节点依然受其父组件的CSS 的影响

vue scoped,子组件的根节点依然受其父组件的CSS 的影响

vue-loader文档

我们都知道,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名字

 

 

@萍2樱释ღ( ´・ᴗ・` )

posted @ 2020-10-02 17:20  不忘初心dbsdxq  阅读(5551)  评论(2编辑  收藏  举报
TOP 文章底部