この記事では主に Vue の style のスコープ属性を紹介しますが、これは非常に優れていると編集者が考えているので、参考にしてください。エディターをフォローして見てみましょう
vue コンポーネントでは、スタイルをプライベート化 (モジュール化) し、グローバル世界を汚染しないようにするために、スタイル タグにscoped 属性を追加して、現在のスタイルにのみ属することを示すことができます。これは非常に良い方法ですが、注意して使用する必要があるのはなぜですか?パブリック コンポーネント (サードパーティ ライブラリまたはプロジェクトでカスタマイズされたコンポーネント) のスタイルを変更する必要がある場合、スコープを指定するとさらに困難が発生し、さらに複雑さが必要になることが多いためです。
プライベート化されたスタイルのスコープ付き実装の原則
なぜ複雑さが増すと思いますか?それでは、モジュール実装の原則から始めましょう。命名の便宜上、この種のコンポーネントをモジュールプライベートコンポーネントと呼び、その他のスコープ外のコンポーネントをモジュール一般コンポーネントと呼ぶことにします。
DOM 構造を調べると、vue が DOM 構造と CSS スタイルに重複しない一意のタグを追加して、一意性を確保し、スタイルのプライベート化とモジュール化の目的を達成していることがわかりました。具体的なレンダリング結果を例を挙げて説明します。
パブリックコンポーネントボタンコンポーネント
パブリックコンポーネントボタンは、スタイルをモジュール化するためにそれにスコープ属性を追加します
//button.vue <template> <p class="button-warp"> <button class="button">text</button> </p> </template> ... <style scoped> .button-warp{ display:inline-block; } .button{ padding: 5px 10px; font-size: 12px; border-radus: 2px; } </style>
ブラウザはボタンコンポーネントをレンダリングします
によってレンダリングされるHTML部分のボタンコンポーネントブラウザと CSS 部分は次のとおりです:
<p data-v-2311c06a class="button-warp"> <button data-v-2311c06a class="button">text</button> </p>
.button-warp[data-v-2311c06a]{ display:inline-block; } .button[data-v-2311c06a]{ padding: 5px 10px; font-size: 12px; border-radus: 2px; }
上記の言葉からわかるように、コンポーネント スタイルのモジュール化を実現するために、スコープ付き属性が追加されたコンポーネントに対して 2 つのプロセスが実行されます:
重複しないデータを追加するHTML DOM ノード属性 (data-v-2311c06a など) にその一意性を示す
各 CSS セレクター (コンパイルおよび生成された CSS ステートメント) の最後に、現在のコンポーネントのデータ属性セレクター (例: as [ data-v-2311c06a]) を使用してスタイルをプライベート化します
CSS スタイルが優先されることは誰もが知っていますが、スコープ付きのこの操作によりコンポーネント スタイルをモジュール化するという目的は達成されますが、次のような結果が生じます。増加: 理論上、このスタイルを変更したい場合は、このスタイルをカバーするためにより高いウェイトが必要になります。これは、複雑さを増す要素の 1 つです。
他のコンポーネントはボタンコンポーネントを参照します
上記は単一コンポーネントのレンダリングの結果を分析していますが、コンポーネントが相互に呼び出した後の結果はどうなるでしょうか?具体的には 2 つの状況に分けられます: モジュール一般コンポーネントがモジュール プライベート コンポーネントを参照する (モジュール プライベート コンポーネントがモジュール一般コンポーネントを参照するのと本質的に同じ)。
例: button コンポーネントが content.vue コンポーネントで使用されている場合、content.vue コンポーネントがスコープ属性を追加するかどうかでレンダリング結果にどのような違いがありますか?
//content.vue <template> <p class="content"> <p class="title"></p> <!-- v-button假设是上面定义的组件 --> <v-button></v-button> </p> </template> ... <style> .content{ width: 1200px; margin: 0 auto; } .content .button{ border-raduis: 5px; } </style>
モジュールの一般コンポーネント (スコープされていない) は、モジュールのプライベート コンポーネントを参照します
スコープされた属性がスタイルに追加されていない場合、レンダリングされる HTML と CSS は次のようになります:
<p class="content"> <p class="title"></p> <!-- v-button假设是上面定义的组件 --> <p data-v-2311c06a class="button-warp"> <button data-v-2311c06a class="button">text</button> </p> </p>
/*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; }
コンテンツ コンポーネントでは、ボタンの border-raduis 属性が変更されていますが、重みの関係により、コンポーネント内のスタイルが引き続き有効になります (この時点では、外部スタイルはオーバーライドされます)。したがって、スタイルを変更するという目的を達成したい場合は、変更したいスタイルの重みを増やす必要があります (セレクター レベル、ID セレクター、並列セレクター、重要などを追加します)
モジュール プライベート コンポーネント (スコープ付きのコンポーネントを追加) ) 参照モジュールのプライベートコンポーネント
scoped 属性を追加するとどうなるでしょうか?最初に分析したルールによると (これも当てはまります):
最初にすべての DOM ノードにデータ属性を追加します
次に CSS セレクターの最後にデータ属性セレクターを追加します
その後、レンダリングされた HTML と CSS は次のようになりますそれぞれ:
<p data-v-57bc25a0 class="content"> <p data-v-57bc25a0 class="title"></p> <!-- v-button假设是上面定义的组件 --> <p data-v-57bc25a0 data-v-2311c06a class="button-warp"> <button data-v-2311c06a class="button">text</button> </p> </p>
/*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; }
上記 2 つの状況では、レンダリング結果が大きく異なることがはっきりとわかります。
コンテンツ内にボタンコンポーネントのスタイルを変更したいコードを追加しましたが、よく見ると、 .content .button 文の最後にコンテンツコンポーネントのスコープ付きタグが追加されているため、最後の文は実際にはDOM ノードにはまったく影響しないため、この場合、コンテンツ内に記述したスタイルは button.vue コンポーネントに影響を与えないため、これは恥ずかしいことです。 。 。 。
もちろん、この問題も解決できます。つまり、グローバル スタイルを直接追加して変更することもできますが、これは必然的にすべての場所のコンポーネントに影響を与えるため、スコープ付き属性のないスタイルを追加するには別の方法が必要です。 content.vue コンポーネント。これは、プライベート スタイル用とパブリック スタイル用の 2 つのスタイルを追加することを意味します。これは間違いなくちょっとひどいもので、どちらの解決策も重量という 1 つの問題を回避できません。 ! !
rreeeこれは規制に準拠していますか?このように書くことができないことを私は見ていなかったようで、それが効果を発揮しました。 。 。しかし、これでは思考が複雑になり、少し面倒になります。
スコープ付きのレンダリング ルールを要約する
スコープ付き
の 3 つのレンダリング ルールを要約する HTML DOM ノードに非反復データ属性 (形式: data-v-2311c06a) を追加して、その一意性を表現します
各 CSS セレクター (コンパイルおよび生成された CSS ステートメント) の最後に現在のコンポーネントのデータ属性セレクター ([data-v-2311c06a] など) を追加して、スタイルをプライベート化します
コンポーネントが内部の場合他のコンポーネントが含まれている場合、現在のコンポーネントのデータ属性のみが他のコンポーネントの最も外側のタグに追加されます
解決策
参照先のサードパーティライブラリの場合、相手がスコープ付きを使用している場合、追加することはできません本当にスタイルを変更する必要がある場合は、スコープ外のコンポーネントでスタイルを変更するか、グローバル スタイルを直接変更するのが最善です。
保守するコンポーネントについては、コンポーネントのスタイルがあらゆる状況に対応できるかどうかを明確に考える必要があります。本当に追加する必要がある場合、このコンポーネントを使用する開発者の作業は間違いなく増加します。
もちろん、この問題に対するより良い解決策がある場合は、教えてください。
興味深い事実
スコープを使用する場合は、スコープのこの機能に注意する必要があります。私はバグだと思ったので、 という問題を提起しました。非常に横暴な返答
スコープ付きデザイン 本来の目的は、デザイン上の理由から、現在のコンポーネントのスタイルが他のコンポーネントのスタイルを変更しないようにすることです。ということで、もちろんこの問題は終了しました
以上が皆さんのためにまとめたもので、今後皆さんのお役に立てれば幸いです。
関連記事:
Nodejsの暗号モジュールのセキュリティ知識について(詳細なチュートリアル)
Angularでドロップダウンボックスのファジークエリ関数を実装する方法
以上がVue で style のスコープ属性を使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。