從18年8月開始,我開始了個人野生前端職業生涯。不論是自學期間仍是工做以後,網上的文章對個人學習幫助良多。因此我想開始分享一些我沒在網上看到過的知識。css
一般咱們展現圖片是用html的<img>
標籤或者css的background-image
屬性。html
因爲安卓手機會對點擊的<img>
進行放大顯示,因此本人喜歡用background-image
多一點。前端
安卓<img>
點擊默認放大的解決方法:css能夠用pointer-events:none
;js可用e.preventDefault()
vue
固然這兩種載體還有其餘區別,能夠自行去搜索,下面就只用background-image
來做爲圖片的載體。webpack
不知道有沒有人和我同樣,工做中寫的頁面大多數是經過圖片堆砌起來的,不管是經過一些開發輔助工具(pxcook等),都要查看每張圖片的寬高,因此自從我看到了Less中有獲取圖片寬高的函數後,我就和Less擦出了火花。git
.logo {
width: image-width("logo.png");
height: image-height("logo.png");
}
編譯成
.logo {
width: 10px;
height: 20px;
}
複製代碼
先說下這個函數的缺點,用多了以後會使項目的編譯速度變慢(包括熱更新),若是你的電腦自己就慢的話不推薦用。github
移動端中的適配直接使用px單位是不行的,因此咱們要進一步的改寫web
@designWidth: 750;
html {
//由於移動端已經兼容了vw和calc,因此再也不須要用js來配置rem
font-size: calc(10000vw / @designWidth)
}
.image-size(@url) {
width: unit(image-width(@url) / 100, rem);
height: unit(image-height(@url) / 100, rem);
}
複製代碼
首先咱們的圖片都要放在路徑是src/assets/img/
的文件下,而不是和組件放在一塊兒vue-cli
.contain {
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.image-size(@url) {
width: unit(image-width(@url) / 100, rem);
height: unit(image-height(@url)/ 100, rem);
}
.bg-contain (@url) {
// 路徑是從項目的根目錄開始的
.image-size('./src/assets/img/@{url}');
// 這裏使用webpack來解析圖片模塊
background-image: url('~@/assets/img/@{url}');
// 使用繼承減小生成的css代碼量
&:extend(.contain);
}
使用以下
.logo {
.bg-contain('logo.png');
}
.homeLogo {
.bg-contain('home/logo.png');
}
複製代碼
在進一步改寫以前咱們先來了解下Less的List Functions。數組
@paths: 'home', 'index';
value: extract(@paths, 1);
編譯成
value: 'home';
複製代碼
很明顯這就是以1爲開始下標的數組,而且能夠經過extract()
函數取值。
有三處能夠減小咱們的代碼量
@paths: '/img';
.bg-contain (@name, @arg1: 'png', @arg2: 1) {
// 暫時沒想到更漂亮的方法來兼容參數的差別化
// 有想到的話請務必告訴我
@suffix1: if(isstring(@arg1), @arg1, '');
@suffix2: if(isstring(@arg2), @arg2, '');
@pathIndex1: if(isnumber(@arg1), @arg1, 0);
@pathIndex2: if(isnumber(@arg2), @arg2, 0);
@suffix: @suffix1 + @suffix2;
@pathIndex: @pathIndex1 + @pathInde2;
@path: extract(@paths, @pathIndex);
.image-size('./src/assets/@{path}/@{name}.@{suffix}');
background-image: url('~@/assets/@{path}/@{name}.@{suffix}');
&:extend(.contain);
}
使用以下
// home.vue
@paths: '/img/home';
.logo {
.bg-contain('logo');
}
.gif {
.bg-contain('logo', 'gif');
}
.test {
.bg-contain('logo', 'gif', 1);
}
// index.vue
@paths: '/img/index', '/img/common';
.logo {
.bg-contain('logo');
}
.commonLogo {
.bg-contain('logo', 2);
}
複製代碼
我用的循環可不是loop when這種那麼噁心的東西,而是用Less v3.7.0 版本的新特性each()來進行遍歷。
首先讓咱們來看一下怎麼用each()來減小代碼量
@imgs: logo, avatar;
each(@imgs, {
.bg-@{value} {
.bg-contain(@value);
}
)
複製代碼
不知道大家有沒有和我同樣看到這段後感受很爽,不過這裏要注意一下。
當咱們要用遍歷出來的@value
來做爲選擇器時,咱們的數組裏放的元素是不能帶引號的,不過咱們能夠通用Less的e()
函數來去引號。
由於在Less中帶引號的是Value
類型,而不帶引號的是Node
類型,只有Node
類型能夠用來做爲選擇器使用。感興趣的話能夠看下Less的源碼。
上面的代碼仍是要在css裏寫圖片名字而後在html裏寫上相應的class,感受寫的有點不舒服。不知道大家有沒有想到怎麼連css都不寫就能用圖片呢。
我先說下個人思路:
是否是很簡單?
固然這種方式是有缺點的,就是不能動態地更新自動引入的圖片,因此若是用這種方法來自動引入圖片的話,你須要在yarn serve
前就把要用到的圖片給放在圖片目錄下。
下面我就用 Vue + Node + Less 來作自動引入圖片。
這裏我用 vue-cli 3.0 來生成項目,而後在項目根目錄下配置 vue.config.js 文件。
你固然可使用上面的前置字符串來限制class的做用域,使用以下:
<div class="bg-logo"/>
複製代碼
我這裏還有一種我喜歡的方式來限制class的做用域,不過確定不是人人都喜歡的方式,首先看看怎麼使用:
// html版
<bg logo/>
// pug版
bg(logo)
複製代碼
極簡主義,有沒有!!!
首先咱們知道<bg />
這個標籤是不存在的,對於這種標籤瀏覽器是會把它當作inline-block
,因此咱們要把<bg />
的 display
屬性定義爲block
。(這裏我沒有看HTML的規範,因此若是說的不許確的話請你們指出)。
bg {
display: block;
}
複製代碼
而後若是直接在 vue 裏的<template>
中使用這種不存在的HTML標籤的話,vue 會從當前組件配置的components屬性中找有沒有這個組件,沒有的話會報錯,雖然報錯不會影響輸出結果,可是看着報錯內心就不舒服了,因此咱們能夠改一下vue源碼的 isHTMLTag
變量,在makeMap
中加一個bg
字符串。
第一次寫這種分享文章,可能有的地方寫的很差,請多多包涵。
其實Less還有不少很棒的特性,好比 @plugin
Maps
range()
等。
最後,知道我爲何後半段都用圖片嗎?就是想大家參觀一下個人 ✨0 star✨github。