众所周知,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中渲染出来 是不是很开心~