為了有效的維護(hù)和開發(fā)項(xiàng)目央渣,代碼的重復(fù)利用就顯得尤為重要恕酸。在Sass中奉呛,除了@import和@extend可以使你的代碼更加具有重復(fù)利用性霹崎,@mixin指令也同樣能提高你代碼的重復(fù)使用率并簡(jiǎn)化你的代碼珊搀。
@extend指令通過繼承從而簡(jiǎn)化了代碼,但是它也有缺陷之處尾菇,首先是不夠靈活境析,其次它還會(huì)將你不需要的其他地方具有相同類名的樣式都繼承過來。
@mixin指令是另一種簡(jiǎn)化代碼的方法派诬。Mixins可以包含任意內(nèi)容且可以傳遞參數(shù)劳淆,因此比'@extend'更加靈活和強(qiáng)大。
定義Mixins
通過@mixin加名稱的方式就可以定義一個(gè)Mixins模塊默赂,在模塊內(nèi)你可以添加任何你想重復(fù)使用的樣式沛鸵。
由于歷史原因,連字符和下劃線被認(rèn)為是相同的缆八,也就是說@mixin button-large { }和@mixin button_large { }是一樣的曲掰。
Mixins能夠包含任何在 CSS 和 Sass 中有效的內(nèi)容。
使用@mixin指令
你可以通過@include來調(diào)用具有相同名稱的mixin模塊奈辰。
比如通過@include調(diào)用我之前創(chuàng)建名為button的mixin模塊栏妖,那么解析后的CSS就如下所示:
正如你所預(yù)期的那樣,@include被名為button的混合模塊內(nèi)的樣式所取代冯挎。同時(shí)我在.button-green中添加的background-color樣式依然保留著底哥。
在mixin模塊的定義中還可以包含其他的mixin咙鞍。比如:
所以你可以通過以包含多種簡(jiǎn)單mixin模塊的方式創(chuàng)建較為復(fù)雜的mixin模塊。
當(dāng)Mixins模塊包含選擇器和規(guī)則集趾徽,也就是mixins包含的內(nèi)容本身就是有效的CSS樣式時(shí)续滋,他們就可以在其他規(guī)則集外被調(diào)用。比如本文之前創(chuàng)建的名為link的mixin模塊:
之后我們可以直接調(diào)用這個(gè)模塊孵奶,即使不在一個(gè)選擇器內(nèi)疲酌。
這段代碼將會(huì)被解析為:
之所以能這樣調(diào)用是因?yàn)檫@個(gè)mixin模塊內(nèi)既包含了選擇器也包含了樣式,如果沒有選擇器了袁,那么編譯后將不會(huì)有內(nèi)容顯示朗恳。比如我們?cè)谶x擇器外直接調(diào)用button這個(gè)mixin模塊,那么將不會(huì)有東西被編譯载绿。
不會(huì)被編譯是因?yàn)槟愕臉邮經(jīng)]有被應(yīng)用到任何元素上粥诫。
參數(shù)的使用
Mixins可以接收和使用參數(shù),這使得它比@extend更加強(qiáng)大和靈活崭庸。我更新了之前的button模塊怀浆,增加了名為background的參數(shù)并將其傳遞給模塊。
注意到參數(shù)被設(shè)置為一個(gè)變量并成為backround屬性的值怕享。如果我們想創(chuàng)建一個(gè)綠色的按鈕执赡,那么就可以使用以下代碼:
當(dāng)Sass被編譯時(shí),值green就被傳遞給@mixin并成為變量$backround的值函筋。編譯后的代碼如下:
你還可以在@mixin和@include中傳遞多個(gè)參數(shù)沙合,參數(shù)間用逗號(hào)隔開。比如:
給參數(shù)設(shè)置默認(rèn)值
你可能會(huì)好奇如果在定義mixin時(shí)定義了參數(shù)跌帐,但是在@include調(diào)用時(shí)沒有傳遞參數(shù)會(huì)發(fā)生什么首懈。這種情況下你會(huì)收到一個(gè)編譯錯(cuò)誤的提示。同時(shí)我相信這種情況一定不是你想看到的谨敛。你可以通過在mixin中定義參數(shù)的時(shí)候給它設(shè)置一個(gè)默認(rèn)值猜拾,從而來避免這種錯(cuò)誤。
現(xiàn)在如果你在調(diào)用的時(shí)候忘記傳遞參數(shù)值
你的代碼將會(huì)使用你設(shè)置的參數(shù)默認(rèn)值來解析佣盒,在這個(gè)例子中也就是green這個(gè)值。
當(dāng)然顽聂,你也可以通過提供一個(gè)參數(shù)值來覆蓋這個(gè)默認(rèn)值肥惭。
這時(shí)將會(huì)使用你提供的值來編譯代碼
關(guān)鍵字參數(shù)
為了幫助你的代碼更加容易理解,你可以在傳遞值給mixin時(shí)將參數(shù)名稱和參數(shù)值一并傳遞過去紊搪。
關(guān)鍵字參數(shù)會(huì)額外增加一些代碼蜜葱,但是這會(huì)使得你的@include更加容易理解。比如耀石,上面那段代碼就比下面這段代碼更加容易理解牵囤,因?yàn)樯厦娴拇a明確指出了green和#fff分別是什么。
雖然選擇器的名稱給了我們一些線索,可以大概推斷出第一個(gè)參數(shù)代表什么揭鳞,但是對(duì)于第二個(gè)參數(shù)卻沒有任何提示作用炕贵,而且一年后你很可能不會(huì)再記得這個(gè)參數(shù)的含義。
一起傳遞關(guān)鍵字名稱和值也被稱為命名參數(shù)野崇,你也可以以任意順序傳遞命名參數(shù)称开。下面兩種傳遞方式解析后會(huì)得到相同的結(jié)果。
因?yàn)槊麉?shù)是變量名乓梨,由于歷史原因鳖轰,下劃線和破折號(hào)可以互換使用。
數(shù)量可變的參數(shù)
Mixins可以接收未知數(shù)量的參數(shù)扶镀。比如你可以給同一個(gè)元素增加多種box-shadows蕴侣。這里,我增加了暗灰和淺灰兩種陰影臭觉。
在另一個(gè)元素上你可能只想使用一種陰影或者在其他元素上你又想使用三種或者四種陰影昆雀。這個(gè)時(shí)候你就可以創(chuàng)建一個(gè)接收數(shù)量可變的參數(shù)的mixin模塊,并且在使用@include指令的時(shí)候決定傳遞參數(shù)的數(shù)量胧谈。
通過在變量名后增加三個(gè)點(diǎn)(...)來使mixin模塊接收數(shù)量可變的參數(shù)忆肾。需要注意的是這些是三個(gè)周期的字符,而不是單一的省略號(hào)菱肖。當(dāng)你使用@include傳遞參數(shù)的時(shí)候客冈,使用逗號(hào)將參數(shù)分開。
之前的代碼將被編譯為:
Sass將所有參數(shù)打包為一個(gè)列表稳强,但是在此我沒有列出這個(gè)列表场仲,相關(guān)內(nèi)容之后我會(huì)再做補(bǔ)充。
你同樣可以給mixin傳遞可變的參數(shù)
這里我將變量'$shadows'設(shè)置為有兩種陰影的list退疫,并在@include中將其作為參數(shù)傳遞渠缕。同樣,你也可以將參數(shù)設(shè)置為一個(gè)map褒繁,并且作為參數(shù)傳遞亦鳞。你也可以同時(shí)傳遞list和map,只要list作為第一個(gè)傳遞棒坏。
總結(jié)
Mixins是一個(gè)在提高代碼重復(fù)使用率方面非常有用的指令燕差。而且能夠使用和傳遞參數(shù)這一點(diǎn)使得它非常的強(qiáng)大。
你可以在創(chuàng)建mixins時(shí)設(shè)置默認(rèn)值來防止編譯錯(cuò)誤坝冕,同時(shí)也可以在調(diào)用時(shí)覆蓋默認(rèn)值徒探。甚至你還可以更加靈活地傳遞數(shù)量可變的參數(shù)。