使用webpack+vue+less開發,使用less-loader,配置全局less變量 原 薦

Less 是一門 CSS 預處理語言,它擴展了 CSS 語言,增加了變量、Mixin、函數等特性,在閱讀這篇文章的時候,筆者假設你已經有了一定的less編碼經驗。以下將不會講解less的用法。

我們在構建一個頁面的時候,會定義一些基本參數,例如主色調,文字顏色,標題顏色,副標題顏色,字體大小等等。 通過統一的參數,可以保證頁面整體風格的一致性。

在使用Vue模板進行開發的時候,我們把每個頁面組件化,組件內的樣式就寫在組件自身的<style>標籤內。 這時候我們需要引用一個變量,通常的方式是專門定義一個公共的variables.less 然後在每個需要使用這些變量的組件內,使用 @import 'xxxpath/variables.less';,主動引用的方式,來引入這些變量。

當組件少的時候還好說,當組件過多的時候,每次都引入就比較煩了。 最近在使用Vux-components這個組件庫的時候,該作者提供了一個 vux-loader 來配合組件庫的時候,可以按需打包使用的組件,以及支持全局less變量。

支持全局less變量,這個功能讓我在工作中減少了很多重複的勞動力。 最近在構建一個pc端項目的時候,我就想自己研究一下如何使用全局的less變量。

less-loader

首先看看less-loader支不支持這樣的功能,看了一遍文檔後,發現並不支持。可是在看文檔的過程中,有以下一段描述:

You can pass any Less specific options to the less-loader via loader options.
大意是,“你可以將less特有的配置通過 loader 的 options 參數傳入 less-loader”

隨後我就去翻查了 less 文檔中的選項部分 Less - command-line-usage-options , 發現有以下選項符合我們的需求

Global Variable

lessc --global-var="my-background=red"

This option defines a variable that can be referenced by the file. Effectively the declaration is put at the top of your base Less file, meaning it can be used but it also can be overridden if this variable is defined in the file.

Modify Variable

lessc --modify-var="my-background=red"

As opposed to the global variable option, this puts the declaration at the end of your base file, meaning it will override anything defined in your Less file.

global-var 會將所傳入的參數寫入所有的less文件的頂部,我們可以在自己的less文件中重寫這些參數的值
modify-var 和global-var 相反,會將所傳入的參數寫入所有less文件的底部,我們自己定義的變量會被覆蓋

瞭解到了這些,我就在項目裏做了一下簡單的測試,less-loader 的文檔中說,less 原生的選項都需要轉換成駝峯式,然後傳入 loader的options中。

loader: "less-loader", 
options: {
    globalVars: {
       'primary-color': 'blue'
    }
}

通過這樣的配置,我發現,果然,我在全局都可以不需要導入變量文件,直接使用 @primary-color 這個參數在我的less文件中。

原生的選項和less-loader支持的選項,大部分只需要簡單的轉換爲駝峯式即可,小部分略有不同,例如例子中寫的 global-val 在loader的選項中是 globalVars 多了一個 's',所有的支持並且對應的選項名,可以在參考 lessc 源碼。

配置全局參數

知道了如何傳入全局變量,那麼接下來就是解決如何方便的傳入全局變量了。這裏參考了 vux-loader 的實現,我將所有需要使用到的全局變量,存入一個 theme.less 中,大致內容如下。

@primary-color: #20A0FF;
@waring-color: #F7BA2A;
@success-color: #13CE66;
@danger-color: #FF4949;
@gray-color: #D3DCE6;
@mark-color: #E5E9F2;
@first-color: #1F2D3D;
@sencond-color: #324057;
@thrid-color: #475669;
@font-size: 14px;
@font-color: @first-color;
@global-padding: 15px;

然後,解析這個文件,將這些參數轉換爲 {key:value}的格式,最後傳入 less-loader中就可以了。 因爲偷懶,所以直接將 vux-loader 中的 get-less-variables.js 拷過來使用了。

const fs = require('fs');
module.exports = function getLessVariables(file) {
    var themeContent = fs.readFileSync(file, 'utf-8')
    var variables = {}
    themeContent.split('\n').forEach(function(item) {
        if (item.indexOf('//') > -1 || item.indexOf('/*') > -1) {
            return
        }
        var _pair = item.split(':')
        if (_pair.length < 2) return;
        var key = _pair[0].replace('\r', '').replace('@', '')
        if (!key) return;
        var value = _pair[1].replace(';', '').replace('\r', '').replace(/^\s+|\s+$/g, '')
        variables[key] = value
    })
    return variables
}

因爲項目是用 vue-cli 搭建的,預處理器的樣式都在 build/utils.js中, 將讀取出來的文件,傳入這個方法,就可以在所有的組件中使用全局定義的那些變量了。

less: generateLoaders('less', {
  globalVars: getLessVariables(config.themePath)
}),

到這裏,大部分功能以及完成了,但是有點不足的就是,如果要修改存放全局變量的less文件,必須重新啓動項目才能實現效果了,不能實現熱更行。 但是vux-loader實現了修改全局變量less後,可以自動重新編譯的功能。

這點等我有空再來研究如何實現的。

希望這篇文章對大家有幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章