Vue CSS Modules
CSS Modules: Local scope & modularity
CSS Modules gives each local class a globally unique class name so that component styles don’t affect each other. Such as:
/* button.css */
.button {
font-size: 16px;
}
.mini {
font-size: 12px;
}
Copy the code
It will be converted to something like this:
/* button.css */
.button__button--d8fj3 {
font-size: 16px;
}
.button__mini--f90jc {
font-size: 12px;
}
Copy the code
When importing a CSS module file, it gives us a mapping object from local class names to global class names. Something like this:
import styles from './button.css'
// styles = {
// button: 'button__button--d8fj3',
// mini: 'button__mini--f90jc'
// }
element.innerHTML = '<button class="' + styles.button + ' ' + styles.mini + '" / >'
Copy the code
vue-css-modules
: Simplified class name mapping
Here is a button component that uses CSS Modules:
<template>
<button :class="{ 'global-button-class-name': true, [styles.button]: true, [styles.mini]: mini }">Am I</button>
</template>
<script>
import styles from './button.css'
export default {
props: { mini: Boolean },
data: (a)= > ({ styles })
}
</script>
Copy the code
Indeed, CSS Modules are a good choice for Vue components. However, there are also the following shortcomings:
- You must be in
data
The incomingstyles
- You have to use
styles.localClassName
Import the global class name - If there are other global class names, you must put them together
- If you want to bind to a component’s property value, specify it explicitly, even if the local class name is the same as the property name
For the button component above, use vue-CSS-modules:
<template>
<button
class="global-button-class-name"
styleName="button :mini">Am I</button>
</template>
<script>
import CSSModules from 'vue-css-modules'
import styles from './button.css'
export default {
mixins: [CSSModules(styles)],
props: { mini: Boolean}}</script>
Copy the code
Now:
- You don’t have to be in
data
The incomingstyles
, but have to be inmixins
The incomingstyles
🌝 - You can tell
styles.localClassName
Say goodbye - Place the local class name in
styleName
Property, the global class name is placed inclass
Properties, a lot of neat - The local class name binds to the component’s property of the same name and is simply preceded by it
:
The modifier
The modifier
@button
<button styleName="@button">button</button>
Copy the code
This is equivalent to:
<button styleName="button" data-component-button="true">button</button>
Copy the code
This allows you to restyle components externally:
.form [data-component-button] {
font-size: 20px;
}
Copy the code
$type
<button styleName="$type">button</button>
Copy the code
This is equivalent to:
<button :styleName="type">button</button>
Copy the code
:mini
<button styleName=":mini">button</button>
Copy the code
This is equivalent to:
<button :styleName="mini ? 'mini' : ''">button</button>
Copy the code
disabled=isDisabled
<button styleName="disabled=isDisabled">button</button>
Copy the code
This is equivalent to:
<button :styleName="isDisabled ? 'disabled' : ''">button</button>
Copy the code
Method of use
Used in Vue templates
Import CSS modules outside the template
<template>
<button
class="global-button-class-name"
styleName="button :mini">Am I</button>
</template>
<script>
import CSSModules from 'vue-css-modules'
import styles from './button.css'
export default {
mixins: [CSSModules(styles)],
props: { mini: Boolean}}</script>
Copy the code
Use the CSS module inside the template
<template>
<button
class="global-button-class-name"
styleName="button :mini">Am I</button>
</template>
<script>
import CSSModules from 'vue-css-modules'
export default {
mixins: [CSSModules()],
props: { mini: Boolean}}</script>
<style module>
.button {
font-size: 16px;
}
.mini {
font-size: 12px;
}
</style>
Copy the code
Used in Vue JSX
import CSSModules from 'vue-css-modules'
import styles from './button.css'
export default {
mixins: [CSSModules(styles)],
props: { mini: Boolean },
render() {
return (
<button styleName="@button :mini">Am I</button>)}}Copy the code
Used in Vue rendering functions
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'
}, 'am I')}}Copy the code
Realize the principle of
Vue-css-modules registers the beforeCreate hook in which it hijacks the component’s rendering function. For parameters passed to the render function, the styleName property in its data or data.attrs is parsed to generate a global class name string that is attached to the value of data.staticClass.
Making: vue – CSS – modules