當使用 3rd Party 的 Package 時,若只有特定 Page 想要改變其內部 CSS Style,其他 Page 則維持不變,該如何才不會影響到其他 Page 呢 ?
Version
CSS 3
Hello World
Hello World
為紅色,可發現其 style 為 color: #f00
。
HelloWorld.vue
<template>
<h1 class="title">Hello World</h1>
</template>
<style>
.title {
color: #f00
}
</style>
模擬別人 package 內的 component。
第 5 行
<style>
.title {
color: #f00
}
</style>
別人 component 並沒有使用 scoped style,而是使用 global style。
理論上使用 scoped style 更佳
App.vue
<template>
<HelloWorld/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
components: {
HelloWorld
}
}
</script>
直接使用 HelloWorld
component,因此 Hello World
為 紅色
。
Global Style
<template>
<HelloWorld/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
components: {
HelloWorld
}
}
</script>
<style>
.title {
color: #00f;
}
</style>
15 行
<style>
.title {
color: #00f;
}
</style>
若想將 HelloWorld
改成 藍色
,最簡單方式是直接以 .title
改成 color: #00f
。
這種方法雖然可行,但因為是 global style,會導致其他 page 的
HelloWorld
component 也一併改成藍色
,是 side effect 很大的方式
Namespace Style
<template>
<div class="app">
<HelloWorld/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
components: {
HelloWorld
}
}
</script>
<style>
.app .title {
color: #00f;
}
</style>
第 2 行
<div class="app">
<HelloWorld/>
</div>
在 <HelloWorld/>
外多包一層 <div>
,加上一個 dummy class 以 component 名稱命名,藉此建立 namespace。
17 行
<style>
.app .title {
color: #00f;
}
</style>
依然使用 global style,但因為有 .app
namespace 保護,只會改到本 page 的 <HelloWorld/>
,不會有 side effect 影響到其他 page。
Scoped Style
<template>
<HelloWorld/>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
components: {
HelloWorld
}
}
</script>
<style scoped>
.title {
color: #00f;
}
</style>
15 行
<style scoped>
.title {
color: #00f;
}
</style>
使用 scoped style,可直接對 .title
將 color
改成 #00f
。
當使用 scoped style 時,Vue 會自動對 component 加上亂數 attribute,其 selector 也會改成 attribute selector,因此不會影響到其他 page。
Conclusion
- 三種方式都是在 component 使用端去修改 style,並不是直接從 component 內去修改 style,如同無法更改 package 內的 compnent 一樣
- 三種方式雖然都可行,但 global style 是最差的,side effect 嚴重,因為可能影響到其他 page 的 style
- Scoped style 最優,沒有 side effect,但實務上可能有些 selector 會抓不到
- Namespace style 最萬用,side effect 在可控範圍,一定可抓到 selector,也不會影響到其他 page