點燈坊

失くすものさえない今が強くなるチャンスよ

如何更改套件內的 CSS ?

Sam Xiao's Avatar 2021-03-29

當使用 3rd Party 的 Package 時,若只有特定 Page 想要改變其內部 CSS Style,其他 Page 則維持不變,該如何才不會影響到其他 Page 呢 ?

Version

CSS 3

Hello World

pkg000

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 很大的方式

pkg001

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。

pkg002

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,可直接對 .titlecolor 改成 #00f

pkg003

當使用 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