VUE项目中CSS管理

vue 的 scoped

在 vue 项目中,当 *.vue 文件中 <style> 标签有 scoped 属性时,它的 CSS 只作用于当前组件中的元素,很好的实现了样式私有化的目的。

使用 scoped 之后,父组件的样式将不会渗透到子组件中。不过一个子组件的根节点会同时受其父组件有作用域的 CSS 和子组件有作用域的 CSS 的影响,如果希望父组件样式影响子组件,可以使用 >>>操作符:

1
2
3
<style scoped>
.a >>> .b { /* ... */ }
</style>

sass 变量和 mixin

一般情况 scss 中的变量和 mixin 的作用域仅限于当前文件,每次在 vue 文件中引用公共变量或者 mixin 的时候,都需要先将mixin.scss import 进来。当我们有很多个 vue 组件的时候,这是一件非常非常麻烦的事情。

这个时候我们就需要用到sass-resources-loader了,它会在 webpack 打包过程中帮助我们将全局 scss 文件 import 到每个 Vue 组件中,举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module: {
rules: {
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
css: 'vue-style-loader!css-loader',
scss: [
'vue-style-loader',
'css-loader',
'sass-loader',
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, './src/modules/scss/mixin.scss')
}
}
]
}
}
}
}

如果我们需要在其它 scss 文件中使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module: {
rules: [{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
{
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, './src/modules/scss/mixin.scss')
}
}
]
}]
}

需要注意的是, sass-resources-loader会将common.scss注入每个 vue 组件中。为避免重复打包,不要在common.scss写具体的 CSS 方法。

webpack 打包优化

如果希望将项目中 css 抽离出来单独打包缓存,需要用到 webpack 的插件extract-text-webpack-plugin,下面是官方 vue-loader 文档中的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// webpack.config.js
var ExtractTextPlugin = require("extract-text-webpack-plugin")

module.exports = {
// other options...
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
css: ExtractTextPlugin.extract({
use: 'css-loader',
fallback: 'vue-style-loader' // <- 这是vue-loader的依赖,所以如果使用npm3,则不需要显式安装
})
}
}
}
]
},
plugins: [
new ExtractTextPlugin("style.css")
]
}

这样就可以将 vue 组件里面的 css 单独打包出来。

如果是移动端的项目,可以选择使用html-webpack-inline-source-plugin把 CSS 内联到 html 里面以减少请求。

坚持原创技术分享,您的支持将鼓励我继续创作!