Vue CSS Modules
CSS Modules:局部作用域 & 模块化
为每一个局部类赋予全局唯一的类名,这样组件样式间就不会相互影响了。如:
/* button.css */.button { font-size: 16px;}.mini { font-size: 12px;}复制代码
它会被转换为类似这样:
/* button.css */.button__button--d8fj3 { font-size: 16px;}.button__mini--f90jc { font-size: 12px;}复制代码
当导入一个 CSS 模块文件时,它会将局部类名到全局类名的映射对象提供给我们。就像这样:
import styles from './button.css'// styles = { // button: 'button__button--d8fj3',// mini: 'button__mini--f90jc'// }element.innerHTML = ''复制代码
vue-css-modules
:简化类名映射
下面是一个使用了 CSS Modules 的按钮组件:
复制代码
的确,CSS Modules 对于 Vue 组件是一个不错的选择。但也存在以下几点不足:
- 你必须在
data
中传入styles
- 你必须使用
styles.localClassName
导入全局类名 - 如果有其他全局类名,你必须将它们放在一起
- 如果要和组件的属性值绑定,就算局部类名和属性名一样,也要显式指定
对于上面的按钮组件,使用 vue-css-modules
后:
复制代码
现在:
- 你不必在
data
中传入styles
,但得在mixins
中传入styles
? - 你可以跟
styles.localClassName
说拜拜了 - 将局部类名放在
styleName
属性,全局类名放在class
属性,规整了许多 - 局部类名绑定组件同名属性,只需在其前面加上
:
修饰符
修饰符
@button
复制代码
这等同于:
复制代码
这让你能在外部重置组件的样式:
.form [data-component-button] { font-size: 20px;}复制代码
$type
复制代码
这等同于:
复制代码
:mini
复制代码
这等同于:
复制代码
disabled=isDisabled
复制代码
这等同于:
复制代码
使用方法
在 Vue 模板中使用
引入模板外部的 CSS 模块
复制代码
使用模板内部的 CSS 模块
复制代码
在 Vue JSX 中使用
import CSSModules from 'vue-css-modules'import styles from './button.css'export default { mixins: [CSSModules(styles)], props: { mini: Boolean }, render() { return ( ) }}复制代码
在 Vue 渲染函数中使用
import CSSModules from 'vue-css-modules'import styles from './button.css'export default { mixins: [CSSModules(styles)], props: { mini: Boolean }, render(h) { return h('button', { styleName: '@button :mini' }, '点我') }}复制代码
实现原理
vue-css-modules
注册了 钩子,在钩子中劫持了组件的渲染函数。对于传给渲染函数的参数,将会解析其 data
或 data.attrs
中的 styleName
属性生成全局类名字符串,并将它附着在 data.staticClass
值的后面。
Github: