在Web前端開發的過程中,比起JavaScript,css通常是比較容易忽略的一塊內容。css易於理解,但是應用和維護並不簡單。如果項目規劃中沒有考慮好css管理的問題,隨著項目代碼量的增加和工程體量的增大,後期樣式上的維護會越來越困難。所以今天探討一下如何在vue項目管理好css。
css 選擇器的命名空間是全局的,並沒有局部的概念。同一個頁面下的所有css類名,都是在同一個「作用域」下的,因此我們常常要考慮如何避免命名衝突問題。
在vue項目中,我們一般在 *.vue 單個文件組件內的 <style> 中寫css。當 vue文件中 <style> 標籤有 scoped 屬性時,它的 CSS 只作用於當前組件中的元素,很好的實現了樣式私有化的目的。
<style scoped>
.example {
color: red;
}
</style>
<template>
<div class="example">hi</div>
</template>
vue通過在DOM結構以及css樣式上加唯一不重複的標記,達到樣式私有化模塊化的目的,最終轉換成:
<style>
.example[data-v-f3f3eg9] {
color: red;
}
</style>
<template>
<div class="example" data-v-f3f3eg9>hi</div>
</template>
使用scoped之後,父組件的樣式將不會滲透到子組件中。不過一個子組件的根節點會同時受其父組件有作用域的 CSS 和子組件有作用域的 CSS 的影響,如果希望父組件樣式影響子組件,可以使用 >>>操作符:
<style scoped>
.a >>> .b { /* ... */ }
</style>
公共css文件可以在每個頁面引入一次就可以了,但是變量和mixin不一樣。在使用sass的過程中,經常會遇到這樣的問題:通常情況下我們會建立一個common.scss文件管理一些公共的樣式,由於sass的變量和mixin的作用域僅限於當前文件,每次在vue文件中引用公共變量或者mixin的時候,都需要先將common.scss import進來。當我們有很多個vue組件的時候,這是一件非常非常麻煩的事情。這個時候我們就需要用到sass-resources-loader了,它會在webpack打包過程中幫助我們將全局scss文件import到每個Vue組件中,舉個例子:
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文件中使用:
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')
}
}
]
}]
}
這樣就可以在其它文件裡面裡調用common.scss裡面的變量和mixin了。需要注意的是, sass-resources-loader會將common.scss注入每個vue組件中。為避免重複打包,不要在common.scss寫具體的CSS方法。
如果希望將項目中css抽離出來單獨打包緩存,需要用到webpack的插件extract-text-webpack-plugin,下面是官方vue-loader文檔中的例子:
// 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裡面以減少請求。
在開發之前,需要結合項目特點和團隊背景,制定合適的技術方案,以保證項目的可維護性。這篇文章在 vue 項目中 css 管理方面,提供一點參考,希望對發家有所啟發。