核心要點
map-get()
函數仍然可以提供所需的值。 本文標題可能會讓一些人感到意外。如果您是Sass老手,您可能還記得使用列表的列表來模擬嵌套數據數組的日子(在Ruby-Sass-3.3之前)。 (Ruby) Sass 3.3添加了一種名為映射的新數據類型。列表的列表可以以嵌套格式保存複雜數據,但沒有鍵值配對。映射添加了鍵值對,並讓我們創建數據數組。
隨著映射的出現,我們許多Sass用戶開始將所有內容都放入映射中(並且有充分的理由!)。所有斷點寬度、顏色值、網格佈局、類型比例和其他響應式排版細節都可以放入映射中!
現在Sass有了鍵值對映射,還有使用列表的列表的好理由嗎?一個理論上的原因是向後兼容性:如果您的Sass可能由安裝了較舊版本的開發人員維護,列表將幫助他們。然而,在實踐中,Sass版本通常由package.json
或其他項目配置控制,並且Ruby gem只需一個命令即可更新(gem update sass
)。
您可能選擇使用嵌套列表而不是映射的一個更實際的原因是輸入較少。讓我們比較一下映射和嵌套列表,看看它們在各自語法和循環遍歷方式上的比較。
語法比較
在我們的示例中,讓我們創建一個控制響應式排版的 數據結構。它將存儲四個斷點(好吧,一個是最小的默認視圖)。對於每個斷點,我們將存儲最小寬度、最大寬度、基本字體大小和基本行高。
以下是我們將數據存儲在映射中的方法。一個大型映射將包含四個鍵(斷點標籤),其值是我們需要存儲和使用的變量的映射。以這種可讀的格式,我們有超過450個字符和26行。
<code>$breakpoint-map: ( small: ( min-width: null, max-width: 479px, base-font: 16px, vertical-rhythm: 1.3 ), medium: ( min-width: 480px, max-width: 959px, base-font: 18px, vertical-rhythm: 1.414 ), large: ( min-width: 960px, max-width: 1099px, base-font: 18px, vertical-rhythm: 1.5 ), xlarge: ( min-width: 1100px, max-width: null, base-font: 21px, vertical-rhythm: 1.618 ) );</code>
存儲相同數據的嵌套列表要短得多。但是,我們不再將鍵附加到數據,因此我們必須依賴於循環遍歷它或使用nth()
函數調用它。也就是說,它比映射短得多:少於180個字符,只有6行。
<code>$breakpoint-list: ( (small, null, 479px, 16px, 1.3), (medium, 480px, 959px, 18px, 1.414), (large, 960px, 1099px, 18px, 1.5), (xlarge, 1100px, null, 21px, 1.618) );</code>
循環比較
在編寫數據結構時,編寫列表大約只需要編寫映射時間的三分之一。但是,如果我們需要循環遍歷這些值,那又如何比較呢?
我們可以使用以下代碼循環遍歷此映射中的頂級項目:
<code>@each $label, $map in $breakpoint-map {}</code>
此行開頭的兩個變量($label
和$map
)在循環迭代映射中的數據時動態分配。每個頂級數據塊有兩個組成部分:鍵和值。我們將鍵分配給$label
,並將值(這是一個嵌套映射)分配給$map
。在這個循環中,我們可以使用變量$label
和$map
,它們將自動表示當前條目的鍵和值。
該循環將迭代四次,每次迭代一個嵌套映射。但是,要從嵌套映射中獲取有用的數據,我們需要使用map-get()
函數。此函數採用兩個參數——映射的名稱和所需鍵的名稱——並返回與該鍵關聯的值。它是Sass中PHP的$array['key']
和$object->key
或JavaScript的object.key
語法的等效項。
要使用@each
迭代所有子映射並將它們的值使用map-get()
分配給有用的變量,我們最終得到一個6行、220個字符的循環。
<code>@each $label, $map in $breakpoint-map { $min-width: map-get($map, min-width); $max-width: map-get($map, max-width); $base-font: map-get($map, base-font); $vertical-rhythm: map-get($map, vertical-rhythm); }</code>
嵌套列表確實使循環效率更高。對於映射,我們必須將映射分配給動態循環變量,然後使用map-get()
將所有值分配給變量,但是對於列表,我們可以快速地將所有值分配給變量。
由於頂級列表中的每個項目都按相同順序具有相同的五個值,因此我們可以立即將每個值分配給動態變量以在循環中使用。使用這些變量,我們不需要使用map-get()
將子值分配給可用的變量。我們需要的嵌套列表循環只有兩行,少於100個字符。
<code>@each $label, $min-width, $max-width, $base-font, $vertical-rhythm in $breakpoint-list { }</code>
嵌套列表警告
嵌套列表是主要的開發人員性能優勢:總的來說,您輸入的內容可能不到使用映射時的一半。但是,添加映射到Sass是有原因的:它們提供列表不具備的功能:鍵值映射。
如果您要依賴嵌套列表,您必須絕對確定您知道每個列表將包含多少個項目以及它們的順序。讓我們看看如果我們在列表中遺漏了一個項目,上面的示例會發生什麼:
<code>$breakpoint-map: ( small: ( min-width: null, max-width: 479px, base-font: 16px, vertical-rhythm: 1.3 ), medium: ( min-width: 480px, max-width: 959px, base-font: 18px, vertical-rhythm: 1.414 ), large: ( min-width: 960px, max-width: 1099px, base-font: 18px, vertical-rhythm: 1.5 ), xlarge: ( min-width: 1100px, max-width: null, base-font: 21px, vertical-rhythm: 1.618 ) );</code>
如果我們嘗試運行該代碼,最後一個列表將中斷。它將正確地將“xlarge”分配給$label
並將“1100px”分配給$min-width
,但隨後它將“21px”分配給$max-width
並將“1.618”分配給$base-font
,使$vertical-rhythm
為空。結果,我們在最後一個斷點中得到一個無效的字體大小聲明和一個缺少的行高屬性。此外,Sass不會為此報告錯誤,因此我們不知道事情是否成功。如果我們嘗試將最大寬度用於媒體查詢,我們將最終得到字體大小值(只有21px)——我認為這將是一個非常無用的最大寬度!
如果我們改用映射,即使缺少一個值,map-get()
函數也會給我們提供我們需要的東西。這就是我們的權衡:我們在列表中獲得的簡單性和速度,我們在映射中失去了特異性和防錯性。
使用嵌套列表的另一個相關問題是查詢特定列表。由於映射具有鍵,因此您可以使用map-get()
快速訪問任何子映射:
<code>$breakpoint-list: ( (small, null, 479px, 16px, 1.3), (medium, 480px, 959px, 18px, 1.414), (large, 960px, 1099px, 18px, 1.5), (xlarge, 1100px, null, 21px, 1.618) );</code>
要從嵌套列表中獲取中等列表的數據,我們需要一個更複雜的函數:
<code>@each $label, $map in $breakpoint-map {}</code>
該函數循環遍歷$breakpoint-list
中的所有列表,檢查我們想要標籤的第一個值,如果找到匹配項則返回列表。如果在沒有找到匹配項的情況下到達@each
循環的末尾,它將返回null。它基本上是列表的map-get()
的快速自製解釋,它使用第一個值作為偽鍵。
Sass有很多有用的函數可以處理映射:嵌套列表不存在相同的函數。例如,您可以使用map-merge()
向映射添加其他鍵值對。使用具有共享鍵的map-merge()
將更新共享鍵的值。您可以使用join()
或append()
添加一個新列表,但是模擬map-merge()
的更新功能將需要另一個自定義Sass函數。
另一個有用的映射函數是map-has-key()
。此函數對於驗證依賴於map-get()
的任何自定義函數非常有用。但是,列表沒有可比的函數。
您可以使用SassyLists模擬列表的映射函數。 (在Sass添加映射支持之前,此庫提供了這些函數。)
結論
由於映射使用鍵值對,因此它們比列表更強大。附加的Sass映射函數提供了查找數據和驗證映射值的實用方法。
嵌套Sass列表編寫和維護起來可能更快,但它們可能不如映射那樣適合錯誤檢查或詳細查詢。大多數情況下,我認為映射是更好的選擇,儘管冗長性有所增加。對於較小的代碼塊和單次使用循環,我偶爾會使用嵌套列表,但映射更適合項目範圍的設置和數據存儲。
您是否在您的任何工作中比較了映射和嵌套列表,或者重構了代碼以優先使用一個而不是另一個?在評論中分享您的經驗!
您可以在此Sassmeister gist中看到本教程中使用的代碼。
Sass映射與嵌套列表的常見問題解答 (FAQ)
Sass映射和嵌套列表都是Sass預處理器中的強大工具,但它們有明顯的區別。 Sass映射類似於其他編程語言中的關聯數組,其中每個值都與一個唯一的鍵相關聯。這使得檢索、更新和操作數據變得容易。另一方面,嵌套列表是一系列值,類似於JavaScript中的數組。當您需要存儲和迭代一系列值時,它們最適合使用,但它們缺乏映射提供的直接訪問特定值的功能。
要使用Sass映射,您首先需要使用一對括號定義一個映射,每個鍵值對用冒號分隔。例如,$map: (key1: value1, key2: value2)
。然後,您可以使用map-get
函數訪問映射中的值,如下所示:map-get($map, key1)
。
是的,您可以像嵌套列表一樣嵌套Sass映射。當您想要將相關數據組合在一起時,這尤其有用。要訪問嵌套映射中的值,您需要使用兩次map-get
函數:map-get(map-get($map, key1), key2)
。
您可以使用@each
指令迭代Sass映射。 @each
指令採用兩個變量:鍵和值。這是一個示例:@each $key, $value in $map { … }
。
Sass映射比嵌套列表具有幾個優點。它們允許直接訪問特定值,使您的代碼更高效且更易於閱讀。它們還提供用於操作映射的內置函數,例如添加、刪除和更新鍵值對。
是的,您可以使用map-from-list
函數將嵌套列表轉換為Sass映射。此函數採用一對列表並返回一個映射,其中每一對都是映射中的鍵值對。
要在Sass中使用嵌套列表,您首先需要使用一對括號定義一個列表,每個值用空格或逗號分隔。例如,$list: (value1, value2, value3)
。然後,您可以使用nth
函數訪問列表中的值,如下所示:nth($list, 1)
。
是的,您可以同時使用Sass映射和嵌套列表。例如,您可以使用映射來存儲一系列列表,反之亦然。這對於組織複雜的數據結構很有用。
雖然Sass映射和嵌套列表是強大的工具,但它們確實有一些限制。例如,Sass映射不能有重複的鍵,並且映射中鍵的順序不能保證。同樣,如果嵌套列表變得太大或太複雜,則可能難以管理。
使用Sass映射或嵌套列表的選擇取決於您的具體需求。如果您需要直接訪問特定值並能夠操作數據,則Sass映射可能是最佳選擇。如果您只需要存儲和迭代一系列值,則嵌套列表就足夠了。
以上是SASS地圖與嵌套列表的詳細內容。更多資訊請關注PHP中文網其他相關文章!