書かれなかったみたいなので、代わりに先日投稿したものを紹介します。
Vue.js
を使っているときに、scoped
内で別のコンポーネントにスタイルを当てるときにはまったので備忘録として残しておきます。
概要
scoped
を使っている際に親のコンポーネントで子のコンポーネントのスタイルを変更しようとしても、別のスコープとなるため変更できません。
グローバルに書いていくという手もありますが、するとSFC
の利点が得られませんし、すぐに管理できなくなります
外部で定義された汎用コンポーネントとかを使う場合によく遭遇します。
例
簡単な例で確認していきます。
※ pug
とsass
を使っています
子コンポーネント
デフォルトで赤色のテキストを表示するだけのコンポーネントです。
<template lang="pug">
.child-container
.child-layout
p.title ChildComponet
</template>
<script>
export default {
name: "child",
}
</script>
<style lang="sass" scoped>
.title
color: red
</style>
親コンポーネント
子コンポーネントを持ち、子のテキストを緑色にしようしています。
<template lang="pug">
.parent-container
p.title ParentComponent
child.child
</template>
<script>
import Child from "./Child"
export default {
components: { Child }
}
</script>
<style lang="sass" scoped>
.title
color: blue
.child .title
color: green
</style>
実行結果
上記のコードを実行すると子のテキストは赤色のままです
出力されるHTMLにはコンポーネントのスコープを表すdata-v-XXX
というアトリビュートが設定されています。
(今回だと親はdata-v-a1-c2f88c
、子はdta-v-10e5fd3c
)
対してスタイルでは期待通りのスコープにはなっていません。
解決策
よく読んだら公式のスコープ付き CSSのページに書いてありました。
scoped スタイルで入れ子のセレクタが必要なら、CSS に対して >>> オペレータを、そして scss に対しては /deep/ を使用する必要があります
「入れ子」という表現が今回の例にマッチすることだと気づかず、何回もスルーしてましたorz
親コンポーネントに/deep/
を反映してみます。
親コンポーネント
子のコンポーネント以下になるところで/deep/
を追加します。
<template lang="pug">
.parent-container
p.title ParentComponent
child.child
</template>
<script>
import Child from "./Child"
export default {
components: { Child }
}
</script>
<style lang="sass" scoped>
.title
color: blue
.child /deep/ .title
color: green
</style>
実行結果
期待通りに緑色となりました
スタイルはこんな感じで、.child
にスコープの値が設定されています。
※HTMLに変化はないです。
注意点
/deep/
をつけた後の結果を見ると分かりますが、/deep/
以下はコンポーネント内部でグローバルになるので複数のコンポーネントを持つ場合は注意してください。