vueの中でstyleのscoped属性を使うことを注意します。


vueコンポーネントでは、スタイルを私有化(モジュール化)するために、全体的に汚染されないように、styleラベルにscoped属性を追加して、それを表すことができるのは現在のモジュールだけで、これは非常に良い措置ですが、なぜ慎重に使うべきですか?私たちが公共のコンポーネント(三方倉庫またはプロジェクトのカスタマイズされたコンポーネント)のスタイルを変更する必要があるとき、scopedは多くの困難を引き起こし、余分な複雑さを追加する必要があるからです。
scopedは私有化様式の原理を実現します。
なぜ複雑さが増すと言いますか?まずモジュールの原理から話します。呼びやすくするために、このようなコンポーネントをモジュールプライベートコンポーネントといい、他のscopedを入れていないものをモジュール一般コンポーネントといいます。
DOM構造を確認すると、vueはDOM構造およびcssスタイルにユニークな重複しないマークを付けて、唯一のスタイルの私有化モジュール化の目的を達成することができます。具体的なレンダリング結果はどのようなものか、一例で説明します。
共通コンポーネント
公共のコンポーネントのブロックブロックをブロック化するために、scoped属性を追加します。

//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>
ブラウザレンダリングブロック
buttonコンポーネントはブラウザでレンダリングしたhtml部分とcss部分はそれぞれ:

<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;
}
上の文字からわかるように、scoped属性を付加したコンポーネントは、コンポーネントのスタイルをモジュール化するために、二つの処理を行った。
  • はHTMLのDOMノードにダタ属性を重複しないように付けて彼の一意性を表します。
  • は、各cssセレクタの末尾に、現在のコンポーネントのdata属性セレクタを加えてプライベート化スタイル
  • をプライベート化する。
    cssスタイルに優先度があるという説はよく知られていますが、scopedのこの動作はモジュール化の目的に達していますが、各スタイルの重みが増してきます。理論的にはこのスタイルを修正するためには、より高い重みが必要です。これは複雑さを増す一つの次元です。
    他のコンポーネントはbuttonコンポーネントを参照します。
    単一のコンポーネントをレンダリングした結果を上で分析しましたが、コンポーネントを相互に呼び出したら、どのような結果が出ますか?具体的には、2つの場合に分けて、モジュールの一般的なコンポーネントは、モジュールのプライベートコンポーネント(本質的およびモジュールのプライベートコンポーネント参照モジュールの一般的なコンポーネントと同じ)を参照する。モジュールのプライベートコンポーネントは、モジュールのプライベートコンポーネントを参照します。
    例えば、コンポーネントcontent.vueにbuttonコンポーネントを使っていますが、content.vueコンポーネントはscoped属性を追加してレンダリングした結果、どのような違いがありますか?
    
    //content.vue
    <template>
      <div class="content">
        <p class="title"></p>
        <!-- v-button           -->
        <v-button></v-button>
      </div>
    </template>
    ...
    <style>
      .content{
        width: 1200px;
        margin: 0 auto;
      }
      .content .button{
        border-raduis: 5px;
      }
    </style>
    
    モジュールの一般的なコンポーネント(scopedを追加していません)は、モジュールのプライベートコンポーネントを参照します。
    もしstyleにscoped属性がないならば、レンダリングします)とcssはそれぞれです。
    
    <div class="content">
      <p class="title"></p>
      <!-- v-button           -->
      <div data-v-2311c06a class="button-warp">
        <button data-v-2311c06a class="button">text</button>
      </div>
    </div>
    
    
    /*button.vue     css*/
    .button-warp[data-v-2311c06a]{
      display:inline-block;
    }
    .button[data-v-2311c06a]{
      padding: 5px 10px;
      font-size: 12px;
      border-radus: 2px;
    }
    /*content.vue     css*/
    .content{
      width: 1200px;
      margin: 0 auto;
    }
    .content .button{
      border-raduis: 5px;
    }
    
    contentコンポーネントでは、buttonのborder-raduis属性が修正されたが、重みの関係により、依然としてコンポーネント内部のパターンが発効していることがわかる。したがって、スタイルを変更する目的を達成するには、スタイルを変更する重みを加重しなければなりません(セレクタ階層、IDセレクタ、並列セレクタ、impotantなどを追加します)。
    モジュールのプライベートコンポーネント(scopedを追加)参照モジュールのプライベートコンポーネント
    scoped属性を追加したら?分析を開始したルールに基づいて(事実も同じです):
    まず、すべてのDOMノードにdata属性を追加します。
    cssセレクタの末尾にdata属性セレクタを追加します。
    じゃレンダリングします。これとcssはそれぞれです。
    
    <div data-v-57bc25a0 class="content">
      <p data-v-57bc25a0 class="title"></p>
      <!-- v-button           -->
      <div data-v-57bc25a0 data-v-2311c06a class="button-warp">
        <button data-v-2311c06a class="button">text</button>
      </div>
    </div>
    
    /*button.vue     css*/
    .button-warp[data-v-2311c06a]{
      display:inline-block;
    }
    .button[data-v-2311c06a]{
      padding: 5px 10px;
      font-size: 12px;
      border-radus: 2px;
    }
    /*content.vue     css*/
    .content[data-v-57bc25a0]{
      width: 1200px;
      margin: 0 auto;
    }
    .content .button[data-v-57bc25a0]{
      border-raduis: 5px;
    }
    
    上の二つの場合には、明らかにレンダリング後の結果が違っています。
    私たちはcontentにbuttonコンポーネントのスタイルを変更したいコードを追加しましたが、よく見てください。content.buttonという文の末尾にはcontentコンポーネントのscopedマークが付けられています。最後にこの文は私たちが欲しいDOMノードにはまったく作用しません。だから、このような状況はcontent内部に書いてあるどんなスタイルでもbutton.vueコンポーネントに影響しません。だから気まずいです。。。。
    もちろんこの問題も解決できます。全体のスタイルを直接入れて修正できます。しかし、これは必ず全体の部品に影響を与えます。したがって、もう一つの方法が必要です。content.vueコンポーネントにscoped属性を持たないスタイルラベルをもう一つ追加します。つまり、二つのスタイルを追加するということです。一つはプライベートスタイル、一つは共有スタイルに使います。これは間違いなく少しshitので、しかもこれらの2つの解決案はすべて1つの問題を回避できません:重み!
    
    //content.vue
    <template>
      <div class="content">
        <p class="title"></p>
        <!-- v-button           -->
        <v-button></v-button>
      </div>
    </template>
    ...
    <style scoped>
      .content{
        width: 1200px;
        margin: 0 auto;
      }
    </style>
    <style>
      .content .button{
        border-raduis: 5px;
      }
    </style>
    
    これは規範に合いますか?このように書いてはいけないというのは見たことがないようです。でも、これは確かに思考の複雑さを増しています。ちょっと悩んでいます。
    scopedのレンダリングルールをまとめます。
    scoped 3つのレンダリングルールをまとめます。
  • はHTMLのDOMノードにダタ属性を重複しないように付けて彼の一意性を表します。
  • は、各cssセレクタの末尾に、現在のコンポーネントのdata属性セレクタを加えてプライベート化スタイル
  • をプライベート化する。
  • コンポーネントの内部に他のコンポーネントが含まれている場合、他のコンポーネントの最外層タグに現在のコンポーネントのdata属性
  • だけを追加する。
    ソリューション
    引用する三方倉庫に対して、もし相手がscopedを使ったら、私達は何を変えることができません。もし彼のスタイルを修正する必要があるなら、一番scopedを入れない部品の中でスタイルを修正することができます。
    自分が守っているコンポーネントについては、コンポーネントのスタイルがすべてを満たすかどうかを必ず確認してください。この部品を使う開発学生の仕事が増えるのは間違いないです。
    もちろんこの問題に対して、皆さんがもっといい解決策があれば、皆さんTELL MEに来てください。
    おもしろい事
    <del>scopedを使って、scopedのこの特性を慎重にして、私はこれがBUGだと思って、issueを持ってきました。
    scopedは、現在のコンポーネントのスタイルを他のところのスタイルに変えられないように設計したからです。当たり前のようにこのissueはもう乾いてしまいました。
    以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。