Implementation principle of scoped privatization style in vue

In vue, the original intention of scoped design is to make the style private so that it will not affect the style anywhere else.

Let's start with the principle of implementing module components. By looking at the DOM structure, it is found that vue ensures uniqueness by adding unique and non duplicate marks on the DOM structure and css style, so as to achieve the purpose of style privatization and modularization. The specific rendering results are illustrated by examples. For the convenience of addressing, let's assume that "scoped component" is called "style private component"; The "unscoped" is called "general component".

(1) a common component, v-button, is added with scoped attribute for style modularization.

    // v-button.vue
    <template>
        <div class="button-warp">
            <button class="button">text</button>
        </div>
    </template>
    ...
    <style scoped>
        .button-warp {
            display:inline-block;
        }
        .button {
            padding: 5px 10px;
            font-size: 12px;
            border-radus: 2px;
        }
    </style>


The html and css parts rendered by the v-button component in the browser are:

    <div data-v-2311c06a class="button-warp">
        <button data-v-2311c06a class="button">text</button>
    </div>
    .button-warp[data-v-2311c06a] {
        display:inline-block;
    }
    .button[data-v-2311c06a] {
        padding: 5px 10px;
        font-size: 12px;
        border-radus: 2px;
    }


It can be seen from the above words that for components with scoped attribute, two processes are done to achieve modularization of component style:
Add a non repeating data attribute (such as data-v-2311c06a) to the DOM node of HTML to represent its uniqueness;
Add a data attribute selector of the current component (such as [data-v-2311c06a]) at the end of each css selector (the compiled css statement) to privatize the style.
As we all know, css style has a priority. scoped's operation has achieved the purpose of modularization of component style, resulting in an increase in the weight of each style. Therefore, theoretically, we need to modify this style and override this style with higher weight. This is one dimension that increases complexity.

(2) "general component" refers to "style private component" v-button?

    //content.vue
    <template>
        <div class="content">
            <p class="title"></p>
            <!-- v-button Suppose it is the component defined above -->
            <v-button></v-button>
        </div>
    </template>
    ...
    <style>
        .content {
            width: 1200px;
            margin: 0 auto;
        }
        .content .button {
            border-raduis: 5px;
        }
    </style>


At this point, content If the scoped attribute is not added to Vue's style, the rendered html and css are:

    <div class="content">
        <p class="title"></p>
        <!-- v-button Suppose it is the component defined above -->
        <div data-v-2311c06a class="button-warp">
            <button data-v-2311c06a class="button">text</button>
        </div>
    </div>
    /* button.vue Rendered css */
    .button-warp[data-v-2311c06a] {
        display:inline-block;
    }
    .button[data-v-2311c06a] {
        padding: 5px 10px;
        font-size: 12px;
        border-radus: 2px;
    }
    /* content.vue Rendered css */
    .content {
        width: 1200px;
        margin: 0 auto;
    }
    .content .button {
        border-raduis: 5px;
    }


It can be seen that although the border raduis attribute of the button is modified in the content component, due to the weight relationship, The effective style is still the internal style of the component (in this case, the external style is overwritten). Therefore, if we want to modify the style, we must increase the weight of the style we want to modify (increase the selector level, ID selector, parallel selector, important, etc.).

(3) "style private component" refers to "style private component" v-button?

If in content Vue style with scoped attribute? According to the rules (the same is true) from the beginning of the analysis, first add the data attribute to all DOM nodes, and then add the data attribute selector at the end of the css selector. Then the rendered html and css are respectively:

    <div data-v-57bc25a0 class="content">
        <p data-v-57bc25a0 class="title"></p>
        <!-- v-button Suppose it is the component defined above -->
        <div data-v-57bc25a0 data-v-2311c06a class="button-warp">
            <button data-v-2311c06a class="button">text</button>
        </div>
    </div>
    /* button.vue Rendered css */
    .button-warp[data-v-2311c06a] {
        display:inline-block;
    }
    .button[data-v-2311c06a] {
        padding: 5px 10px;
        font-size: 12px;
        border-radus: 2px;
    }
    /* content.vue Rendered css */
    .content[data-v-57bc25a0] {
        width: 1200px;
        margin: 0 auto;
    }
    .content .button[data-v-57bc25a0] {
        border-raduis: 5px;
    }


For the above two cases (2) and (3), it is obvious that the rendered results are very different.
In case (3), although we added the code to modify the style of the button component in the content, look carefully. Since the ". Content. Button" sentence adds the scoped tag of the content component at the end, the last sentence actually does not work on the DOM node we want, so (3) In this case, any style we write inside the content will still not affect the button.vue component.
In summary, there are three rendering rules for scoped:
Add a non repeating data attribute (such as data-v-2311c06a) to the DOM node of HTML to represent its uniqueness;
Add a data attribute selector of the current component (such as [data-v-2311c06a]) at the end of each css selector (the compiled css statement) to privatize the style;
If there are other components inside the component, only the outermost label of other components will be added with the data attribute of the current component.

Reference article: Use the scoped attribute of style with caution in vue .

Keywords: Vue.js html css

Added by sareejoh on Wed, 22 Dec 2021 21:05:17 +0200