眾所周知,vue中有兩種css渲染模式,一是直接在style中直接加上scoped,另一種是配置CSSModules.
- scoped是為了防止各個元件間的class汙染,從而渲染成隔離模式如:
<template>
<div>
<div class="box">box</div>
</div>
</template>
<script>
export default {}
</script>
<style scoped>
.box{
color: #ccc;
}
</style>複製程式碼
html渲染成
<div data-v-fae5bece class="box">box</div>複製程式碼
css渲染成
.box[data-v-fae5bece] {
color: #ccc;
}複製程式碼
現在有一個子元件Comp.vue
<template>
<div class="inner">inner-box</div>
</template>
<style scoped>
.inner {
color: #f00;
}
</style>複製程式碼
父元件對其不加任何修飾,那顯而易見Comp渲染出來的color是 紅色(#f00),現在我希望通過父元件修改Comp中的顏色,通常做法是在父元件的style中加上
<style scoped>
.box {
color: #ccc;
}
.box .inner{
color: #ccc;
}
</style>
//或者官方推薦的深度作用選擇器效果一樣.box >>> .inner{ color: #ccc;}複製程式碼
當然顯示出來Comp的顏色已經變成了灰色(#ccc),但是有一點很重要,在HTML中渲染出來的效果是這樣:
<div data-v-9b5d8882 data-v-fae5bece class="inner">
inner-box
</div>
複製程式碼
.box[data-v-fae5bece] .inner {
color: #ccc;
}複製程式碼
div中的權重越來越多,inner樣式也失去了封裝的效果,子元件中所有的inner樣式都會被渲染成父元件的樣式,如果有更多的父元件對其修改樣式呢?
2.CSSModules出場了(以下皆為vue2.X)
參看官方vue-loader配置說明:vue-loader.vuejs.org/zh/guide/cs…
配置方式:
- build/utils.js中找到css-loader,在其options中加上,注:加上後要重啟dev生效
直接在vue中的style加上module,class以$style.box的形式訪問,甚至可以通過javascript訪問this.$style.box
<div>
<div :class="$style.box"> <p>box</p>
</div>
</div>
</template>
<style module>
.box {
color: #ccc;
}
</style>複製程式碼
也支援以下形式
<p :class="{ [$style.red]: isRed }">
Am I red?
</p>
<p :class="[$style.red, $style.bold]">
Red and bold
</p>複製程式碼
如果class是下劃線的形式則需要以下形式訪問
:class="$style['box-a']"複製程式碼
直接看渲染效果
<div class="ms3sHUJ9cRha8f_qHKpJE_0"><p>box</p></div>
複製程式碼
.ms3sHUJ9cRha8f_qHKpJE_0{
color: #ccc;
}複製程式碼
媽媽再也不用擔心我的樣式汙染啦!
如果現在assets檔案中有一個common.css,然後在template中直接使用common的.red class,然後發現樣式不生效,f12一看原來common中的樣式也被模組化了
.red_1R_DKSL1 {
color: #f00;
}
複製程式碼
(注意:commom中的element選擇器並不會被模組化,可以放心使用)
那麼怎麼引用common中的style呢?
引用的方式有很多種看自己喜歡挑選
<script>
export default {
data: function(){
return {
style: require('@/assets/sass/common.scss')
}
}
}
</script>複製程式碼
使用方式大致和module一樣
:class="style.box"
:class="style['aa-bb']"複製程式碼
也可以:
<script>
import style from '@/assets/sass/common.scss'
export default {
data: function(){
return {}
},
created: function(){
this.style = style
}
}
</script>
複製程式碼
也可以:
<script>
import style from '@/assets/sass/common.scss'
export default {
data: function(){
return {}
},
computed: {
style : function(){
return style
},
},
}
</script>
複製程式碼
任君挑選...
當然如果你不想這麼麻煩,也可以換一種配置
在build/vue-loader.conf.js檔案中
然後app.vue中全域性引用
<style lang="scss" src="@/assets/sass/common.scss"></style>複製程式碼
<template>
<div>
<div :class="$style.box">
<p class="red">box</p>
</div>
</div>
</template>複製程式碼
直接引用common中的red樣式
html中渲染出來 是不是很開心~