Vue - In-depth understanding of scoped attributes in vue

1 Introduction

We know that in order to prevent css style pollution, vue provides scopedattributes to limit the css scope;
when <style>the tag has a scoped attribute, its CSS only acts on the elements in the current component.

2. scoped principle

1. scopedThe attribute is actually to add a non-repeated custom attribute to each dom node element (such as: data-v-6810cbe5);
2, and then add it to the end of the style when compiling 属性选择器to privatize the style ( Such as .btn[data-v-6810cbe5]);
as follows:

Code before translation:

btn component (using the button component of the Vant component library):

<template>
  <div class="copy1">
    <van-button type="default">默认按钮</van-button>
  </div>
</template>

<style scoped lang="scss">
.van-button {
    
    
    background-color: red;
  }
</style>

The results of browser editing are as follows:

insert image description here
It can be seen that van-button is added after the class name [data-v-03f66e5f]; custom attributes are automatically added to its nodes data-v-03f66e5f;
therefore: even if the same class name is used in two unrelated components, their styles will not affect each other ;

3. Different situations where parent-child components use scoped

scoped的Although this operation achieves the purpose of component style modularization, it may not be possible to modify the style of the child component regardless of the weight of the parent component style;

The following describes the role of scoped in four situations:

4. The first type: the parent component does not add scoped, and the child component does not add scoped

insert image description here

This is the most primitive case where you can see that the background color of the button is blue. At this time, the parent component is declared background-color: blue;, the child component is declared background-color: red, and the weight is the same, but the style
of the parent component will override the style of the child component; after viewing Elements, you will find that the insertion position of the style file of the parent component is behind the style file of the child component (above) It can be seen that one is line 9 and the other is line 90). For styles with the same weight, the latter will overwrite the front, so the style of the parent component will take effect.

5. The second type: the parent component does not add scoped, and the child component adds scoped

Subcomponent: btn.vue

<template>
  <div class="copy1">
    <van-button type="default">默认按钮</van-button>
  </div>
</template>

<style lang="scss" scoped>
.van-button {
    
    
    background-color: red;
  }
</style>

insert image description here

We can see that the child component .van-button{background-color: red}; is compiled into .van-button[data-v-03f66e5f]{background-color: red};
the weight of the button style in the child component =类选择器(.button)+属性选择器([data-v-03f66e5f]), and the weight of the button style in the parent component = the class selector (.button), so the weight of the child component style is increased, and the override can be produced Acts on the parent component's style, causing the button's background color to be red.

6. The third type: scoped is added to the parent component, but scoped is not added to the child component

parent component:

<template>
  <div>
    <!-- 使用子组件 -->
    <div class="scoped1">
      <btn></btn>
    </div>
  </div>
</template>

<script>
//引入
import Btn from './copy1/index.vue';
export default {
    
    
  name: 'copy',
  components: {
    
    
    Btn,
  },  
};
</script>

<style lang="scss" scoped>
.scoped1 {
    
    
  .van-button {
    
    
    background-color: blue;
  }
}
<style>

Subcomponent: btn.vue

<template>
  <div class="copy1">
    <van-button type="default">默认按钮</van-button>
  </div>
</template>

<style lang="scss">
.van-button {
    
    
    background-color: red;
  }
</style>

insert image description here

We can see that the background color of the button is red. After the scoped is added to the parent component style, all elements are added with data-v attributes, including the root node of the child component, but the inner element of the child component is the same, so the role of the parent component 不会受影响is .van-button[data-v-ae1b895c] {background-color:blue;}not to the .van-button of the child component.

This is also the reason why directly modifying the style of element-ui or vant-ui subcomponents does not take effect. Even if you want to write it, you need to use the depth effect selector or the style is not written in the scoped attribute.

注意

If you only modify the style of the root node of the child component, it can still be written in the scoped CSS of the parent component, because the root node of a child component will have two data-v attributes at the same time, one is the original of the parent component, and the other is the child Above the root node of the component; (see the left part of the figure above); so it will also affect the root node element of the subcomponent;

7. The fourth type: the parent component adds scoped, and the child component also adds scoped

The renderings are as follows:

insert image description here
We can see that the root node of the child component not only has the data-v attribute of the child component, but also the data-v attribute of the parent component. The .van-button element is still not affected by the parent component, and only has the data-v attribute of its own component, so the button color is still red.
This is the same as the third case above; directly override the style of the sub-component;

8. Solution

So what if I just want the style of the parent component to override the style of the child component?

1. The first type uses two styles, one for private styles (plus scoped), and one for public styles.

<style lang="scss" scoped>
.van-button {
    
    
	....
}
// 公共样式
<style lang="scss" >
.van-button {
    
    
  background-color: blue;
}

2. Depth action selector

Parent elements use /deep/ or >>> for penetration

<style lang="scss" scoped>
/deep/ .scoped1 {
    
    
  .van-button {
    
    
    background-color: blue;
  }
  
  编译如下:
  [data-v-ae1b895c] .scoped1 .van-button {
    
    
    background-color: blue;
  }
}
<style>

Some preprocessors like Sass don't parse >>> correctly. In this case you can use the /deep/ or ::v-deep operators instead - both are aliases for >>> and will work just as well.

It is recommended to use /deep/ for simplicity and convenience;

9. Summary

1. The weight of each style in scoped CSS is increased. In theory, we can modify a certain style, but we need a higher weight to cover this style; 2. Regardless of the weight of the parent component style, it may not be possible to modify the child
component styles, except for the root node of the child component.

END;

The article reference comes from Nuggets 喂。小欢: https://juejin.cn/post/6844903965746790408

Guess you like

Origin blog.csdn.net/qq_43886365/article/details/129496484