When I was learning to use Vue recently, I found that some of the styles defined in

conclusion

The scoped property is the main reason the defined style does not work. When scoped is used, styles created for children of the current component, including some third-party component libraries (I used element-UI), will not take effect.

Why does the style given to the child component not take effect after using the scoped property?

When the

<template>
    <div class="example">hi</div>
</template>

<style scoped>
.example {
    color:red;
}
</style>
Copy the code

Convert to the following:

<style>
.example[data-v-f3f3eg9] {
  color: red;
}
</style>

<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>
Copy the code

We can see that both HTML and CSS have data attributes, so even if other components have a.example class, without the corresponding data attribute, the style will not take effect, so the style of the current class will not pollute the style of other elements.

Because of this, when we call a child component, the inner element of the child component cannot get the CSS style set externally, as shown in the following example:

End result:

The source code:

<! -- Parent component (HelloWorld.vue) -->
<template>
  <div class="hello">
    <h1>Hello,World!</h1>
    
    <hi-world />
  </div>
</template>

<script>
import HiWorld from "./HiWorld.vue";

export default {
  name: 'HelloWorld'.components:{
    HiWorld
  }
}
</script>

<style scoped>
.hello h1{
  color:red;
}
</style>

<! -- Subcomponent (hiworld.vue) -->
<template>
  <div>
    <h1>Hi,World!</h1>
  </div>
</template>

<script>
export default{}</script>

<style>

</style>
Copy the code

The converted code looks like this:

<div class="hello" data-v-469af010="">
    <h1 data-v-469af010="">Hello,World!</h1>
    
    <div data-v-469af010="">
        <h1>Hi,World!</h1>
    </div>
</div>
Copy the code

You can see that the elements in the parent helloWorld.vue have data attributes, but the internal elements in the child hiworld.vue do not. So the style defined in the parent element does not affect the elements in the child component.

The solution

Vue2

The writing of Vue2 also works in Vue3, but this writing has been deprecated in Vue3.

1. When using preprocessors such as Sass:::v-deep

::v-deep .child-class {
    background-color: # 000;
}
Copy the code

2. Without preprocessor:>>>

>>> .child-class {
    background-color: # 000;
}
Copy the code

Vue3

In Vue3, prefix::v-It is now deprecated, and we can use only one, whether we use a preprocessor like Sass or not:deepSelectors, although parenthesized selectors are now recommended.

:deep(.child-class) {
    background-color: # 000;
}
Copy the code

In addition to

The root node of the child component

When using scoped, the style of the parent component does not leak into the child component. However, the root node of a child component is still affected by the parent component’s Scoped CSS and the child component’s scoped CSS. This is by design so that the parent component can change the style of the root node of the child component for layout reasons. Here’s an example:

End result:

The source code:

<! -- parent helloworld.vue, compare the above code and only modify the style part -->
<template>
  <div class="hello">
    <h1>Hello,World!</h1>
    
    <hi-world />
  </div>
</template>

<script>
import HiWorld from "./HiWorld.vue";

export default {
  name: 'HelloWorld'.components:{
    HiWorld
  }
}
</script>

<style scoped>
.hello h1{
  color:red;
}

.hello div {
  width: 20%;
  border: 5px solid;
  margin: auto;
}
</style>


<! -- hiworld.vue -->
<template>
  <div>
    <h1>Hi,World!</h1>
  </div>
</template>

<script>
export default{}</script>

<style>

</style>  
Copy the code

We can see that the root

element of the child component is affected by the parent component scoped CSS. This can also be seen in the compiled code:
<div class="hello" data-v-469af010="">
    <h1 data-v-469af010="">Hello,World!</h1>
    
    <div data-v-469af010="">
        <h1>Hi,World!</h1>
    </div>
</div>
Copy the code

Scoped CSS does not eliminate the need for class and ID selectors

Because of the way browsers render CSS selectors, p {color: red} is much slower in scoped CSS (combined with attribute selectors). In contrast, if you use a class or ID selector, such as.example {color:red}, then you plan to eliminate the performance hit.

Slotted selector

By default, the scoped style does not affect the contents of
because they are owned by the parent component (the component that passes the content in). Use: SloTTED pseudo class to explicitly hit the content of slot. Here’s a simple example:

End result:

The source code:

<! -- Parent helloWorld.vue -->
<template>
  <div class="hello">
    <h1>Hello,World!</h1>
    
    <! -- use <slot/> and pass in the content -->
    <hi-world>
      <h1>Hi,World!</h1>
    </hi-world>
  </div>
</template>

<script>
import HiWorld from "./HiWorld.vue";

export default {
  name: 'HelloWorld'.components:{
    HiWorld
  }
}
</script>

<style scoped>

</style>

<! Hiworld.vue -->
<template>
  <div>
    <slot/>
  </div>
</template>

<script>
export default{}</script>

<style scoped>
:slotted(h1) {
  color: red;
}
</style>  
Copy the code

The resources

  1. Vue-loader.vuejs.org/guide/scope…
  2. medium.com/@debbyji/de…
  3. V3.vuejs.org/api/sfc-sty…
  4. Stackoverflow.com/questions/4…