vue.js

Vuejsでコンポネント内のCSSを親コンポネントから変更したい場合はdeep selectorを使おう

はじめに

Vuejsなどのコンポネント志向のフレームワークを使っていると、コンポネントの中のスタイルをある特定の用途のときのみ変更したいことが発生すると思います。
とは言え下記の用に scoped パラメータを設定していると、外側からコンポネントのスタイルを上書きすることは困難です。

# 子コンポーネント
<style scoped>
.hoge {
  color: red;
}
...

</style>

そこで下記の用に設定する人がいますが、 !important も使ってるしグローバル汚染するため明らかにアンチパターンです。

# 親コンポネント
<style>
.hoge {
  color: black !important;
}
</style>

Deep Selector

vue-loader:2.12 から上記のパターンの場合を考慮し、DeepSelectorというものが導入されました。

使い方

使い方は単純で、 親コンポネントのCSSセレクターと子コンポーネントのCSSセレクターを >>> でつなぐだけです。

# 親コンポネント
<style scoped>
.parent >>> .hoge {
  color: black; /* .parentの親属性に所属する .hoge属性に関してのみblackが適応 */
}
</style>

scssの場合は >>> の変わりに /deep/ となります。inp

応用した使い方

例えば element-ui のような外部テーマを使用する場合、コンポネに使用されるCSSクラスの接頭語は決まっています。 (element-uiの場合は .el- )
そうした場合SCSS記法を使えば下記のように指定できるようになります。

.parent /deep/ .el- {
  &select {
    width: 100%;
  }
  &input {
    width: 80%;
  }
}

そうすることで、特定のコンポネの子コンポーネントのみスタイルを当てるというのが、ソースコード上でひとまとまりに管理できるようになります。