Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 视频一区国产精戏刘婷,在线观看免费av网,日本一区二区三区四区

          整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          Qt中的快捷鍵匯總

          Qt Creator中提供了各種快捷鍵來加快開發(fā)進程。

          如果需要查看或自定義快捷鍵,選擇工具->選項->環(huán)境->鍵盤。快捷鍵按類別列出,可以在過濾器(Filter)處輸入命令名稱、標簽名稱或快捷鍵名稱,來快速定位想要查找的快捷鍵。

          以紅顏色顯示的快捷鍵與某些功能相關(guān)聯(lián)。Qt Creator可以在當前上下文中執(zhí)行該功能。如果幾個功能用同一個快捷鍵,那么就會產(chǎn)生沖突,Qt Creator不會執(zhí)行任何功能。

          鍵盤快捷鍵也可能與窗口管理器使用的快捷鍵沖突。這種情況下,Qt Creator的快捷鍵就不會起作用。通常,可以在窗口管理器中配置快捷鍵,但如果不行,則可以改變Qt Creator的快捷鍵。例如,在Ubuntu 11.10窗口管理器中使用了F10,因此默認的Qt Creator的鍵盤快捷鍵F10(單步調(diào)試)就不會在該系統(tǒng)上運行。

          自定義快捷鍵

          選擇工具->選項->環(huán)境->鍵盤。

          從列表中選擇一個命令。

          在快捷鍵設置的”Key sequence”處,有以下選擇:

          (1) 輸入與選定命令關(guān)聯(lián)的快捷鍵。

          (2) 選擇”Record”,按下要設置的快捷鍵,選擇”Stop Recording”來完成錄制。

          恢復默認的快捷鍵,選擇”Reset”。

          導入/導出快捷鍵

          Qt Creator允許使用不同的鍵盤快捷鍵映射方案:

          要導入鍵盤快捷鍵映射方案,單擊”Import…”,然后選擇要導入的快捷鍵映射方案.kms文件。

          要導出鍵盤快捷鍵映射方案,單擊”Export…”,然后選擇要導出.kms文件的位置。

          默認快捷鍵

          下表列出了默認的快捷鍵,它們是由動作進行分類。

          【領QT開發(fā)教程學習資料,點擊→「鏈接」←莬費領取,先碼住不迷路~】

          一般快捷鍵

          動作

          快捷鍵

          打開文件或項目(O)…

          Ctrl+O

          新建文件或項目(N)…

          Ctrl+N

          在外部編輯器中打開

          Alt+V, Alt+I

          全選(A)

          Ctrl+A

          刪除

          Del

          剪切(T)

          Ctrl+X

          復制(C)

          Ctrl+C

          粘貼

          Ctrl+V

          撤銷

          Ctrl+Y

          打印

          Ctrl+P

          保存

          Ctrl+S

          保存所有文件(L)…

          CTRL+Shift+S

          關(guān)閉窗口

          Ctrl+W

          關(guān)閉所有文件

          Ctrl+Shift+W

          關(guān)閉當前文件

          Ctrl+F4

          后退

          Alt+Left

          前進

          Alt+Right

          跳轉(zhuǎn)行(G)…

          Ctrl+L

          歷史中下個打開的文件

          Ctrl+Shift+Tab

          切換到其他分欄

          Ctrl+E, O

          歷史中先前打開的文件

          Ctrl+Tab

          激活定位器

          Ctrl+K

          切換到歡迎模式

          Ctrl+1

          切換到編輯模式

          Ctrl+2

          切換到設計模式

          Ctrl+3

          切換到調(diào)試模式

          Ctrl+4

          切換到項目模式

          Ctrl+5

          切換到分析模式

          Ctrl+6

          切換到幫助模式

          Ctrl+7

          切換問題窗口

          Alt+1 (Cmd+1 on OS X)

          切換搜索結(jié)果窗口

          Alt+2 (Cmd+2 on OS X)

          切換應用程序輸出窗口

          Alt+3 (Cmd+3 on OS X)

          切換編譯輸出窗口

          Alt+4 (Cmd+4 on OS X)

          切換其它輸出窗口

          Alt+編號 (Cmd+編號 on OS X) 編號為”輸出窗口”中的編號

          激活書簽窗口

          Alt+M

          激活文件系統(tǒng)窗口

          Alt+Y

          激活打開文檔窗口

          Alt+O

          最大化輸出窗口

          Alt+9

          輸出窗口-下一項

          F6

          輸出窗口-上一項

          Shift+F6

          激活項目窗口

          Alt+X

          全屏

          Ctrl+Shift+F11

          切換側(cè)邊欄

          Alt+0 (Cmd+0 on OS X)

          撤銷

          Ctrl+Z

          移動到編輯模式。在編輯模式下:第一次按下將焦點移動到編輯器中,第二次按下關(guān)閉輔助窗口

          Esc

          退出Qt Creator

          Ctrl+Q

          編輯快捷鍵

          動作

          快捷鍵

          自動縮進

          Ctrl+I

          折疊

          Ctrl+<

          展開

          Ctrl+>

          在此范圍內(nèi)觸發(fā)完成

          Ctrl+Space

          復制行

          Ctrl+Ins

          復制到行下

          Ctrl+Alt+Down

          復制到行上

          Ctrl+Alt+Up

          查看剪切板歷史

          Ctrl+Shift+V

          剪切行

          Shift+Del

          追加行

          Ctrl+J

          在當前行上方插入新行

          Ctrl+Shift+Enter

          在當前行下方插入新行

          Ctrl+Enter

          減小字體大小

          Ctrl+- (Ctrl+鼠標滾輪向下)

          增加字體大小

          Ctrl++ (Ctrl+鼠標滾輪向上)

          重置字體大小

          Ctrl+0

          切換Vim的編輯風格

          Alt+V, Alt+V

          分欄

          Ctrl+E, 2

          左右分欄

          Ctrl+E, 3

          刪除所有分割

          Ctrl+E, 1

          刪除當前分割

          Ctrl+E, 0

          全選

          Ctrl+A

          跳轉(zhuǎn)至塊結(jié)尾

          Ctrl+]

          跳轉(zhuǎn)至塊開始

          Ctrl+[

          跳轉(zhuǎn)至以}結(jié)尾的塊

          Ctrl+}

          跳轉(zhuǎn)至以{開始的塊

          Ctrl+{

          向下移動當前行

          Ctrl+Shift+Down

          向上移動當前行

          Ctrl+Shift+Up

          在此范圍激活重構(gòu)

          Alt+Enter

          重新包裝段

          Ctrl+E, R

          選擇當前塊,第二次按下選擇父塊

          Ctrl+U

          啟用文本換行

          Ctrl+E, Ctrl+W

          注釋選中的內(nèi)容

          Ctrl+/

          可視化的空白

          Ctrl+E, Ctrl+V

          調(diào)整大小

          Ctrl+J

          網(wǎng)格布局

          Ctrl+G

          水平布局

          Ctrl+H

          垂直布局

          Ctrl+L

          預覽

          Alt+Shift+R

          編輯信號和槽

          F4

          切換書簽

          CTRL+M

          下個書簽

          Ctrl+.

          上個書簽

          Ctrl+,

          取得代碼片段

          Alt+C, Alt+F

          粘貼代碼片段

          Alt+C, Alt+P

          查找所有引用

          Ctrl+Shift+U

          跟隨鼠標下的符號

          F2

          重命名光標所在符號

          Ctrl+Shift+R

          切換函數(shù)聲明/定義

          Shift+F2

          打開類型層次窗口

          Ctrl+Shift+T

          切換頭文件/源文件

          F4

          選中的文本變小寫

          Alt+U

          選中的文本變大寫

          Alt+Shift+U

          在JavaScript中執(zhí)行靜態(tài)檢查來查找共同問題

          Ctrl+Shift+C

          查找和替換

          Ctrl+F

          向下查找

          F3

          向上查找

          Shift+F3

          查找選中文本下一次出現(xiàn)

          Ctrl+F3

          查找選中文本上一次出現(xiàn)

          Ctrl+Shift+F3

          替換和查找下一個

          Ctrl+=

          打開高級搜索

          Ctrl+Shift+F

          錄制宏

          Alt+(

          停止錄制宏

          Alt+)

          播放最近的宏

          Alt+R

          顯示Qt Quick工具欄

          Ctrl+Alt+Space

          在FakeVim模式執(zhí)行用戶行為

          Alt+V, n, 其中n是用戶動作的數(shù)量, 從1到9

          圖像瀏覽器快捷鍵

          動作

          快捷鍵

          切換背景

          Ctrl+[

          顯示輪廓線

          Ctrl+]

          放大

          Ctrl++

          縮小

          Ctrl+-

          適應屏幕

          Ctrl+=

          原始大小

          Ctrl+0

          Qt Quick設計師快捷鍵

          動作

          快捷鍵

          打開定義所選組件的QML文件

          F2

          切換代碼編輯器/可視化編輯器

          F4

          切換左側(cè)側(cè)邊欄

          Ctrl+Alt+0

          切換右側(cè)側(cè)邊欄

          Ctrl+Alt+Shift+0

          調(diào)試快捷鍵

          動作

          快捷鍵

          開始/繼續(xù)調(diào)試

          F5

          停止調(diào)試

          Shift+F5

          單步跳過

          F10

          單步進入

          F11

          單步跳出

          Shift+F11

          切換斷點

          F9

          運行到選擇的函數(shù)

          Ctrl+F6

          執(zhí)行到行

          Ctrl+F10

          相反方向

          F12(暫無)

          項目快捷鍵

          動作

          快捷鍵

          構(gòu)建項目

          Ctrl+B

          構(gòu)建所有項目

          Ctrl+Shift+B

          新建項目…

          Ctrl+Shift+N

          載入項目…

          Ctrl+Shift+O

          選擇構(gòu)建套件(Kit)構(gòu)建和運行項目

          Ctrl+T

          運行

          Ctrl+R

          幫助快捷鍵

          動作

          快捷鍵

          上下文相關(guān)幫助

          F1

          在幫助模式下激活內(nèi)容

          Ctrl+T(暫無)

          添加書簽

          Ctrl+M

          在幫助模式下激活索引

          Ctrl+I(暫無)

          重置字體大小

          Ctrl+0(暫無)

          在幫助模式下激活查找

          Ctrl+S(暫無)


          當我們拿到一個 PC 端頁面的設計稿的時候,往往會發(fā)現(xiàn)頁面的布局并不是隨意的,而是遵循的一定的規(guī)律:行與行之間會以某種方式對齊。對于這樣的設計稿,我們可以使用柵格布局來實現(xiàn)。

          早在 Bootstrap 一統(tǒng)江湖的時代,柵格布局的概念就已深入人心,整個布局就是一個二維結(jié)構(gòu),包括列和行, Bootstrap 會把屏幕分成 12 列,還提供了一些非常方便的 CSS 名讓我們來指定每列占的寬度百分比,并且還通過媒體查詢做了不同屏幕尺寸的適應。

          element-ui 也實現(xiàn)了類似 Bootstrap 的柵格布局系統(tǒng),那么基于 Vue 技術(shù)棧,它是如何實現(xiàn)的呢?

          需求分析

          和 Bootstrap 12 分欄不同的是,element-ui 目標是提供的是更細粒度的 24 分欄,迅速簡便地創(chuàng)建布局,寫法大致如下:

          <el-row>
           <el-col>aaa</el-col>
           <el-col>bbb</el-col>
          </el-row>
          <el-row>
           ...
          </el-row>
          復制代碼
          

          這就是二維布局的雛形,我們會把每個列的內(nèi)容寫在 <el-col></el-col> 之間,除此之外,我們還需要支持控制每個 <el-col> 所占的寬度自由組合布局;支持分欄之間存在間隔;支持偏移指定的欄數(shù);支持分欄不同的對齊方式等。

          了解了 element-ui Layout 布局組件的需求后,我們來分析它的設計和實現(xiàn)。

          設計和實現(xiàn)

          組件的渲染

          回顧前面的例子,從寫法上看,我們需要設計 2 個組件,el-row 和 el-col 組件,分別代表行和列;從 Vue 的語法上看,這倆組件都要支持插槽(因為在自定義組件標簽內(nèi)部的內(nèi)容都分發(fā)到組件的 slot 中了);從 HTML 的渲染結(jié)果上看,我們希望模板會渲染成:

          <div class="el-row">
           <div class="el-col">aaa</div>
           <div class="el-col">bbb</div>
          </div>
          <div class="el-row">
           ...
          </div>
          復制代碼
          

          想達到上述需求,組件的模板可以非常簡單。

          el-row 組件模板代碼如下:

          <div class="el-row">
           <slot></slot>
          </div>
          復制代碼
          

          el-col 組件代碼如下:

          <div class="el-col">
           <slot></slot>
          </div>
          復制代碼
          

          這個時候,新需求來了,我希望 el-row 和 el-col 組件不僅能渲染成 div,還可以渲染成任意我想指定的標簽。 那么除了我們要支持一個 tag 的 prop 之外,僅用模板是難以實現(xiàn)了。

          我們知道 Vue 的模板最終會編譯成 render 函數(shù),Vue 的組件也支持直接手寫 render 函數(shù),那這個需求用 render 函數(shù)實現(xiàn)就非常簡單了。

          el-row 組件:

          render(h) {
           return h(this.tag, {
           class: [
           'el-row',
           ]
           }, this.$slots.default);
          }
          復制代碼
          

          el-col 組件:

          render(h) {
           return h(this.tag, {
           class: [
           'el-col',
           ]
           }, this.$slots.default);
          }
          復制代碼
          

          其中,tag 是定義在 props 中的,h 是 Vue 內(nèi)部實現(xiàn)的 $createElement 函數(shù),如果對 render 函數(shù)語法還不太懂的同學,建議去看 Vue 的官網(wǎng)文檔 render 函數(shù)部分。

          了解了組件是如何渲染之后,我們來給 Layout 組件擴展一些 feature 。

          分欄布局

          Layout 布局的主要目標是支持 24 分欄,即一行能被切成 24 份,那么對于每一個 el-col ,我們想要知道它的占比,只需要指定它在 24 份中分配的份數(shù)即可。

          于是我們給剛才的示例加上一些配置:

          <el-row>
           <el-col :span="8">aaa</el-col>
           <el-col :span="16">bbb</el-col>
          </el-row>
          <el-row>
           ...
          </el-row>
          復制代碼
          

          來看第一行,第一列 aaa 占 8 份,第二列 bbb 占 16 份。總共寬度是 24 份,經(jīng)過簡單的數(shù)學公式計算,aaa 占總寬度的 1/3,而 bbb 占總寬度的 2/3,進而推導出每一列指定 span 份就是占總寬度的 span/24。

          默認情況下 div 的寬度是 100% 獨占一行的,為了讓多個 el-col 在一行顯示,我們只需要讓每個 el-col 的寬占一定的百分比,即實現(xiàn)了分欄效果。設置不同的寬度百分比只需要設置不同的 CSS 即可實現(xiàn),比如當某列占 12 份的時候,那么它對應的 CSS 如下:

          .el-col-12 {
           width: 50%
          }
          復制代碼
          

          為了滿足 24 種情況,element-ui 使用了 sass 的控制指令,配合基本的計算公式:

          .el-col-0 {
           display: none;
          }
          @for $i from 0 through 24 {
           .el-col-#{$i} {
           width: (1 / 24 * $i * 100) * 1%;
           }
          }
          復制代碼
          

          所以當我們給 el-col 組件傳入了 span 屬性的時候,只需要給對應的節(jié)點渲染生成對應的 CSS 即可,于是我們可以擴展 render 函數(shù):

          render(h) {
           let classList = [];
           classList.push(`el-col-${this.span}`);
           
           return h(this.tag, {
           class: [
           'el-col',
           classList
           ]
           }, this.$slots.default);
          }
          復制代碼
          

          這樣只要指定 span 屬性的列就會添加 el-col-${span} 的樣式,實現(xiàn)了分欄布局的需求。

          分欄間隔

          對于柵格布局來說,列與列之間有一定間隔空隙是常見的需求,這個需求的作用域是行,所以我們應該給 el-row 組件添加一個 gutter 的配置,如下:

          <el-row :gutter="20">
           <el-col :span="8">aaa</el-col>
           <el-col :span="16">bbb</el-col>
          </el-row>
          <el-row>
           ...
          </el-row>
          復制代碼
          

          有了配置,接下來如何實現(xiàn)間隔呢?實際上非常簡單,想象一下,2 個列之間有 20 像素的間隔,如果我們每列各往一邊收縮 10 像素,是不是看上去就有 20 像素了呢。

          先看一下 el-col 組件的實現(xiàn):

          computed: {
           gutter() {
           let parent = this.$parent;
           while (parent && parent.$options.componentName !== 'ElRow') {
           parent = parent.$parent;
           }
           return parent ? parent.gutter : 0;
           }
          },
          render(h) {
           let classList = [];
           classList.push(`el-col-${this.span}`);
           
           let style = {};
           
           if (this.gutter) {
           style.paddingLeft = this.gutter / 2 + 'px';
           style.paddingRight = style.paddingLeft;
           }
           
           return h(this.tag, {
           class: [
           'el-col',
           classList
           ]
           }, this.$slots.default);
          }
          復制代碼
          

          這里使用了計算屬性去計算 gutter,其實是比較有趣的,它通過 $parent 往外層查找 el-row,獲取到組件的實例,然后獲取它的 gutter 屬性,這樣就建立了依賴關(guān)系,一旦 el-row 組件的 gutter 發(fā)生變化,這個計算屬性再次被訪問的時候就會重新計算,獲取到新的 gutter。

          其實,想在子組件去獲取祖先節(jié)點的組件實例,我更推薦使用 provide/inject 的方式去把祖先節(jié)點的實例注入到子組件中,這樣子組件可以非常方便地拿到祖先節(jié)點的實例,比如我們在 el-row 組件編寫 provide:

          provide() {
           return {
           row: this
           };
          }
          復制代碼
          

          然后在 el-col 組件注入依賴:

          inject: ['row']
          復制代碼
          

          這樣在 el-col 組件中我們就可以通過 this.row 訪問到 el-row 組件實例了。

          使用 provide/inject 的好處在于不論組件層次有多深,子孫組件可以方便地訪問祖先組件注入的依賴。當你在編寫組件庫的時候,遇到嵌套組件并且子組件需要訪問父組件實例的時候,避免直接使用 this.$parent,盡量使用 provide/inject,因為一旦你的組件嵌套關(guān)系發(fā)生變化,this.$parent 可能就不符合預期了,而 provide/inject 卻不受影響(只要祖先和子孫的關(guān)系不變)。

          在 render 函數(shù)中,我們會根據(jù) gutter 計算,給當前列添加了 paddingLeft 和 paddingRight 的樣式,值是 gutter 的一半,這樣就實現(xiàn)了間隔 gutter 的效果。

          那么這里能否用 margin 呢,答案是不能,因為設置 margin 會占用外部的空間,導致每列的占用空間變大,會出現(xiàn)折行的情況。

          render 過程也是有優(yōu)化的空間,因為 style 是根據(jù) gutter 計算的,那么我們可以把 style 定義成計算屬性,這樣只要 gutter 不變,那么 style 就可以直接拿計算屬性的緩存,而不用重新計算,對于 classList 部分,我們同樣可以使用計算屬性。組件 render 過程的一個原則就是能用計算屬性就用計算屬性。

          再來看一下 el-row 組件的實現(xiàn):

          computed: {
           style() {
           const ret = {};
           if (this.gutter) {
           ret.marginLeft = `-${this.gutter / 2}px`;
           ret.marginRight = ret.marginLeft;
           }
           return ret;
           }
          },
          render(h) {
           return h(this.tag, {
           class: [
           'el-row',
           ],
           style: this.style
           }, this.$slots.default);
          }
          復制代碼
          

          由于我們是通過給每列添加左右 padding 的方式來實現(xiàn)列之間的間隔,那么對于第一列和最后一列,左邊和右邊也會多出來 gutter/2 大小的間隔,顯然是不符合預期的,所以我們可以通過設置左右負 margin 的方式填補左右的空白,這樣就完美實現(xiàn)了分欄間隔的效果。

          偏移指定的欄數(shù)

          如圖所示,我們也可以指定某列的偏移,由于作用域是列,我們應該給 el-col 組件添加一個 offset 的配置,如下:

          <el-row :gutter="20">
           <el-col :offset="8" :span="8">aaa</el-col>
           <el-col :span="8">bbb</el-col>
          </el-row>
          <el-row>
           ...
          </el-row>
          復制代碼
          

          直觀上我們應該用 margin 來實現(xiàn)偏移,并且 margin 也是支持百分比的,因此實現(xiàn)這個需求就變得簡單了。

          我們繼續(xù)擴展 el-col 組件:

          render(h) {
           let classList = [];
           classList.push(`el-col-${this.span}`);
           classList.push(`el-col-offset-${this.offset}`);
           
           let style = {};
           
           if (this.gutter) {
           style.paddingLeft = this.gutter / 2 + 'px';
           style.paddingRight = style.paddingLeft;
           }
           
           return h(this.tag, {
           class: [
           'el-col',
           classList
           ]
           }, this.$slots.default);
          }
          復制代碼
          

          其中 offset 是定義在 props 中的,我們根據(jù)傳入的 offset 生成對應的 CSS 添加到 DOM 中。element-ui 同樣使用了 sass 的控制指令,配合基本的計算公式來實現(xiàn)這些 CSS 的定義:

          @for $i from 0 through 24 {
           .el-col-offset-#{$i} {
           margin-left: (1 / 24 * $i * 100) * 1%;
           }
          }
          復制代碼
          

          對于不同偏移的分欄數(shù),會有對應的 margin 百分比,就很好地實現(xiàn)分欄偏移需求。

          對齊方式

          當一行分欄的總占比和沒有達到 24 的時候,我們是可以利用 flex 布局來對分欄做靈活的對齊。

          對于不同的對齊方式 flex 布局提供了 justify-content 屬性,所以對于這個需求,我們可以對 flex 布局做一層封裝即可實現(xiàn)。

          由于對齊方式的作用域是行,所以我們應該給 el-row 組件添加 type 和 justify 的配置,如下:

          <el-row type="flex" justify="center">
           <el-col :span="8">aaa</el-col>
           <el-col :span="8">bbb</el-col>
          </el-row>
          <el-row>
           ...
          </el-row>
          復制代碼
          

          由于我們是對 flex 布局的封裝,我們只需要根據(jù)傳入的這些 props 去生成對應的 CSS,在 CSS 中定義 flex 的布局屬性即可。

          我們繼續(xù)擴展 el-row 組件:

          render(h) {
           return h(this.tag, {
           class: [
           'el-row',
           this.justify !== 'start' ? `is-justify-${this.justify}` : '',
           { 'el-row--flex': this.type === 'flex' }
           ],
           style: this.style
           }, this.$slots.default);
          }
          復制代碼
          

          其中 type 和 justify 是定義在 props 中的,我們根據(jù)它們傳入的值生成對應的 CSS 添加到 DOM 中,接著我們需要定義對應的 CSS 樣式:

          @include b(row) {
           position: relative;
           box-sizing: border-box;
           @include utils-clearfix;
           @include m(flex) {
           display: flex;
           &:before,
           &:after {
           display: none;
           }
           @include when(justify-center) {
           justify-content: center;
           }
           @include when(justify-end) {
           justify-content: flex-end;
           }
           @include when(justify-space-between) {
           justify-content: space-between;
           }
           @include when(justify-space-around) {
           justify-content: space-around;
           }
           }
          }
          復制代碼
          

          element-ui 在編寫 sass 的時候主要遵循的是 BEM 的命名規(guī)則,并且編寫了很多自定義 @mixin 來配合樣式名的定義。

          這里我們來花點時間來學習一下它們,element-ui 的自定義 @mixin 定義在 pacakages/theme-chalk/src/mixins/ 目錄中,我并不會詳細解釋這里面的關(guān)鍵字,如果你對 sass 還不熟悉,我建議在學習這部分內(nèi)容的時候配合 sass 的官網(wǎng)文檔看。

          mixins/config.scss 中定義了一些全局變量:

          $namespace: 'el';
          $element-separator: '__';
          $modifier-separator: '--';
          $state-prefix: 'is-';
          復制代碼
          

          mixins/mixins.scss 中定義了 BEM 的自定義 @mixin,先來看一下定義組件樣式的 @mixin b:

          @mixin b($block) {
           $B: $namespace+'-'+$block !global;
           .#{$B} {
           @content;
           }
          }
          復制代碼
          

          這個 @mixin 很好理解,$B 是內(nèi)部定義的變量,它的值通過 $namespace+'-'+$block 計算得到,注意這里有一個 !global 關(guān)鍵字,它表示把這個局部變量變成全局的,意味著你也可以在其它 @mixin 中引用它。

          通過 @include 我們就可以去引用這個 @mixin,結(jié)合我們的 case 來看:

          @include b(row) {
           // xxx content
          }
          復制代碼
          

          會編譯成:

          .el-row {
           // xxx content
          }
          復制代碼
          

          再來看表示修飾符的 @mixin m:

          @mixin m($modifier) {
           $selector: &;
           $currentSelector: "";
           @each $unit in $modifier {
           $currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","};
           }
           @at-root {
           #{$currentSelector} {
           @content;
           }
           }
          }
          復制代碼
          

          這里是允許傳入的 $modifier 有多個,所以內(nèi)部用了 @each,& 表示父選擇器,$selector 和 $currentSelector 是內(nèi)部定義的 2 個局部變量,結(jié)合我們的 case 來看:

          @mixin b(row) {
           @include m(flex) {
           // xxx content
           }
          } 
          復制代碼
          

          會編譯成:

          .el-row--flex {
           // xxx content
          }
          復制代碼
          

          有同學可能會疑問,難道不是:

          .el-row {
           .el-row--flex {
           // xxx content
           }
          }
          復制代碼
          

          其實并不是,因為我們在該 @mixin 的內(nèi)部使用了 @at-root 指令,它會把樣式規(guī)則定義在根目錄下,而不是嵌套在其父選擇器下。

          最后來看一下表示同級樣式的 @mixin when:

          @mixin when($state) {
           @at-root {
           &.#{$state-prefix + $state} {
           @content;
           }
           }
          }
          復制代碼
          

          這個 @mixin 也很好理解,結(jié)合我們的 case 來看:

          @mixin b(row) {
           @include m(flex) {
           @include when(justify-center) {
           justify-content: center;
           }
           }
          }
          復制代碼
          

          會編譯成:

          .el-row--flex.is-justify-center {
           justify-content: center;
          }
          復制代碼
          

          關(guān)于 BEM 的 @mixin,常用的還有 @mixin e,用于定義組件內(nèi)部一些子元素樣式的,感興趣的同學可以自行去看。

          再回到我們的 el-row 組件的樣式,我們定義了幾種flex 布局的對齊方式,然后通過傳入不同的 justify 來生成對應的樣式,這樣我們就很好地實現(xiàn)了靈活對齊分欄的需求。

          響應式布局

          element-ui 參照了 Bootstrap 的響應式設計,預設了五個響應尺寸:xs、sm、md、lg 和 xl。

          允許我們在不同的屏幕尺寸下,設置不同的分欄配置,由于作用域是列,所以我們應該給 el-col 組件添加 xs xs、sm、md、lg 和 xl 的配置,如下:

          <el-row type="flex" justify="center">
           <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1">aaa</el-col>
           <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11">bbb</el-col>
           <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11">ccc</el-col>
           <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1">ddd</el-col>
          </el-row>
          <el-row>
           ...
          </el-row>
          復制代碼
          

          同理,我們?nèi)匀皇峭ㄟ^這些傳入的 props 去生成對應的 CSS,在 CSS 中利用媒體查詢?nèi)崿F(xiàn)響應式。

          我們繼續(xù)擴展 el-col 組件:

          render(h) {
           let classList = [];
           classList.push(`el-col-${this.span}`);
           classList.push(`el-col-offset-${this.offset}`);
           
           ['xs', 'sm', 'md', 'lg', 'xl'].forEach(size => {
           classList.push(`el-col-${size}-${this[size]}`); 
           });
           
           let style = {};
           
           if (this.gutter) {
           style.paddingLeft = this.gutter / 2 + 'px';
           style.paddingRight = style.paddingLeft;
           }
           
           return h(this.tag, {
           class: [
           'el-col',
           classList
           ]
           }, this.$slots.default);
          }
          復制代碼
          

          其中,xs、sm、md、lg 和 xl 是定義在 props 中的,實際上 element-ui 源碼還允許傳入一個對象,可以配置 span 和 offset,但這部分代碼我就不介紹了,無非就是對對象的解析,添加對應的樣式。

          我們來看一下對應的 CSS 樣式,以 xs 為例:

          @include res(xs) {
           .el-col-xs-0 {
           display: none;
           }
           @for $i from 0 through 24 {
           .el-col-xs-#{$i} {
           width: (1 / 24 * $i * 100) * 1%;
           }
           .el-col-xs-offset-#{$i} {
           margin-left: (1 / 24 * $i * 100) * 1%;
           }
           }
          }
          復制代碼
          

          這里又定義了表示響應式的 @mixin res,我們來看一下它的實現(xiàn):

          @mixin res($key, $map: $--breakpoints) {
           // 循環(huán)斷點Map,如果存在則返回
           @if map-has-key($map, $key) {
           @media only screen and #{inspect(map-get($map, $key))} {
           @content;
           }
           } @else {
           @warn "Undefeined points: `#{$map}`";
           }
          }
          復制代碼
          

          這個 @mixns 主要是查看 $map 中是否有 $key,如果有的話則定義一條媒體查詢規(guī)則,如果沒有則拋出警告。

          $map 參數(shù)的默認值是 $--breakpoints,定義在 pacakges/theme-chalk/src/common/var.scss 中:

          $--sm: 768px !default;
          $--md: 992px !default;
          $--lg: 1200px !default;
          $--xl: 1920px !default;
          $--breakpoints: (
           'xs' : (max-width: $--sm - 1),
           'sm' : (min-width: $--sm),
           'md' : (min-width: $--md),
           'lg' : (min-width: $--lg),
           'xl' : (min-width: $--xl)
          );
          復制代碼
          

          結(jié)合我們的 case 來看:

          @include res(xs) {
           .el-col-xs-0 {
           display: none;
           }
           @for $i from 0 through 24 {
           .el-col-xs-#{$i} {
           width: (1 / 24 * $i * 100) * 1%;
           }
           .el-col-xs-offset-#{$i} {
           margin-left: (1 / 24 * $i * 100) * 1%;
           }
           }
          }
          復制代碼
          

          會編譯成:

          @media only screen and (max-width: 767px) {
           .el-col-xs-0 {
           display: none;
           }
           .el-col-xs-1 {
           width: 4.16667%
           }
           .el-col-xs-offset-1 {
           margin-left: 4.16667%
           }
           // 后面循環(huán)的結(jié)果太長,就不貼了
          }
          復制代碼
          

          其它尺寸內(nèi)部的樣式定義規(guī)則也是類似,這樣我們就通過媒體查詢定義了各個屏幕尺寸下的樣式規(guī)則了。通過傳入 xs、sm 這些屬性的值不同,從而生成不同樣式,這樣在不同的屏幕尺寸下,可以做到分欄的占寬不同,很好地滿足了響應式需求。

          基于斷點的隱藏類

          Element 額外提供了一系列類名,用于在某些條件下隱藏元素,這些類名可以添加在任何 DOM 元素或自定義組件上。

          我們可以通過引入單獨的 display.css:

          import 'element-ui/lib/theme-chalk/display.css';
          復制代碼
          

          它包含的類名及其含義如下:

          • hidden-xs-only - 當視口在 xs 尺寸時隱藏
          • hidden-sm-only - 當視口在 sm 尺寸時隱藏
          • hidden-sm-and-down - 當視口在 sm 及以下尺寸時隱藏
          • hidden-sm-and-up - 當視口在 sm 及以上尺寸時隱藏
          • hidden-md-only - 當視口在 md 尺寸時隱藏
          • hidden-md-and-down - 當視口在 md 及以下尺寸時隱藏
          • hidden-md-and-up - 當視口在 md 及以上尺寸時隱藏
          • hidden-lg-only - 當視口在 lg 尺寸時隱藏
          • hidden-lg-and-down - 當視口在 lg 及以下尺寸時隱藏
          • hidden-lg-and-up - 當視口在 lg 及以上尺寸時隱藏
          • hidden-xl-only - 當視口在 xl 尺寸時隱藏

          我們來看一下它的實現(xiàn),看一下 display.scss:

          .hidden {
           @each $break-point-name, $value in $--breakpoints-spec {
           &-#{$break-point-name} {
           @include res($break-point-name, $--breakpoints-spec) {
           display: none !important;
           }
           }
           }
          }
          復制代碼
          

          實現(xiàn)很簡單,對 $--breakpoints-spec 遍歷,生成對應的 CSS 規(guī)則,$--breakpoints-spec 定義在 pacakges/theme-chalk/src/common/var.scss 中:

          $--breakpoints-spec: (
           'xs-only' : (max-width: $--sm - 1),
           'sm-and-up' : (min-width: $--sm),
           'sm-only': "(min-width: #{$--sm}) and (max-width: #{$--md - 1})",
           'sm-and-down': (max-width: $--md - 1),
           'md-and-up' : (min-width: $--md),
           'md-only': "(min-width: #{$--md}) and (max-width: #{$--lg - 1})",
           'md-and-down': (max-width: $--lg - 1),
           'lg-and-up' : (min-width: $--lg),
           'lg-only': "(min-width: #{$--lg}) and (max-width: #{$--xl - 1})",
           'lg-and-down': (max-width: $--xl - 1),
           'xl-only' : (min-width: $--xl),
          );
          復制代碼
          

          我們以 xs-only 為例,編譯后生成的 CSS 規(guī)則如下:

          .hidden-xs-only {
           @media only screen and (max-width:767px) {
           display: none !important;
           }
          }
          復制代碼
          

          本質(zhì)上還是利用媒體查詢定義了這些 CSS 規(guī)則,實現(xiàn)了在某些屏幕尺寸下隱藏的功能。

          總結(jié)

          其實 Layout 布局還支持了其它一些特性,我不一一列舉了,感興趣的同學可以自行去看。Layout 布局組件充分利用了數(shù)據(jù)驅(qū)動的思想,通過數(shù)據(jù)去生成對應的 CSS,本質(zhì)上還是通過 CSS 滿足各種靈活的布局。

          學習完這篇文章,你應該徹底弄懂 element-ui Layout 布局組件的實現(xiàn)原理,并且對 sass 的 @mixin 以及相關(guān)使用到的特性有所了解,對組件實現(xiàn)過程中可以優(yōu)化的部分,應該有自己的思考。

          把不會的東西學會了,那么你就進步了,如果你覺得這類文章有幫助,也歡迎把它推薦給你身邊的小伙伴。

          HTML5確實非常強大,小編之前也分享過很多基于HTML5 Canvas的動畫特效。但是你是否知道我們可以利用純CSS制作一些很酷的動畫效果?對,CSS3可以做到。2D炫酷動效是需要技術(shù)積累的,這里有4個重點大家可以著重掌握一下:

          CSS3 2D炫酷動效

          1. 了解canvas動效原理

          就是不斷清除畫布再繪制,清除再繪制。

          2. 一定的JS基本功

          了解實例對象的屬性如何獲取,以及上下文this指代什么;如何有效地遍歷以及數(shù)據(jù)存儲等等。

          3. 知道如何運用一些動畫算法

          4. 了解canvas所有API,尤其基本的繪圖API

          如何使用canvas繪制線條,繪制圓,繪制不規(guī)則圖形;如何描邊,如何填充,如何控制透明度等等,都是必須要牢固掌握的。因為,無論是是圓圈圈,還是角星星,都離不開這些基礎的API繪制。還需要了解圖像繪制API,例如,本demo的星星,實際上還可以基于圖片資源繪制,難度會稍微降低些,但可能要犧牲點效果。

          css3選擇器的用途與重要性

          css3選擇器是基于css2的一種創(chuàng)新,在css2的基礎上增加了目標偽類選擇器、語言偽類選擇器、UI元素狀態(tài)偽類選擇器、結(jié)構(gòu)偽類選擇器、否定偽類選擇器。

          大致有以下三點作用:

          1.網(wǎng)頁代碼更簡潔,結(jié)構(gòu)更清晰。

          2.免除起名的煩惱。

          3.避免css式樣不生效。

          在主頁制作時采用css3技術(shù),可以有效地對頁面的布局、字體、顏色、背景和其它效果實現(xiàn)更加精確的控制。只要對相應的代碼做一些簡單的修改,就可以改變同一頁面的不同部分,或者頁數(shù)不同的網(wǎng)頁的外觀和格式。css3提供了非常多新途徑去改善的設計工作,且做了不少重要的變化。

          css3將完全向后兼容,所以沒有必要修改現(xiàn)在的設計來讓它們繼續(xù)運作。網(wǎng)絡瀏覽器也還將繼續(xù)支持css2。對我們來說,css3主要的影響是將可以使用新的可用的選擇器和屬性,這些會允許實現(xiàn)新的設計效果(譬如動態(tài)和漸變),而且可以很簡單的設計出現(xiàn)在的設計效果(比如說使用分欄)。

          與css相比,使用css3有什么好處呢?最明顯的就是css3能讓頁面看起來非常炫、非常酷,使網(wǎng)站設計錦上添花,但它的好處遠遠不止這些。在大多數(shù)情況下,使用css3不僅有利于開發(fā)與維護,還能提高網(wǎng)站的性能。與此同時,還能增加網(wǎng)站的可訪問性、可用性,使網(wǎng)站能適配更多的設備,甚至還可以優(yōu)化網(wǎng)站SEO,提高網(wǎng)站的搜索排名結(jié)果。

          現(xiàn)在網(wǎng)站重視的更多的是用戶體驗,而優(yōu)秀的動效則能使你的應用更具交互性,從而吸引更多用戶的使用。在網(wǎng)站中加入一些動效會讓整個頁面看起來很有動感。但是如果你對CSS3中定義動效還不熟練,就需要多加學習、多加練習。


          主站蜘蛛池模板: 中文字幕AV无码一区二区三区| 日韩一区二区三区在线| 免费国产在线精品一区| 久久久久无码国产精品一区| 国产大秀视频一区二区三区| 亚洲AV无一区二区三区久久| 激情内射亚州一区二区三区爱妻| 韩国福利影视一区二区三区| 国模精品一区二区三区视频| 麻豆天美国产一区在线播放| 区三区激情福利综合中文字幕在线一区 | 久久国产免费一区| aⅴ一区二区三区无卡无码| 一区二区三区视频| 亚洲国产情侣一区二区三区| 国产一区二区三区久久| 高清一区二区三区视频| 日本精品一区二区三区在线视频| 97久久精品无码一区二区天美| 亚洲国产精品一区第二页| 无码乱人伦一区二区亚洲| 日韩电影一区二区| 亚洲福利一区二区| 色婷婷香蕉在线一区二区| 91视频一区二区三区| 一区二区不卡久久精品| 国产福利一区二区三区在线视频| 亚洲熟妇av一区二区三区| 91久久精品一区二区| 一区二区高清在线观看| 亚洲国产视频一区| 国产在线步兵一区二区三区| 色精品一区二区三区| 国产一区二区三区高清在线观看| 亚洲一区综合在线播放| 中文字幕日韩欧美一区二区三区| 国产一区二区三区乱码| 人妻av综合天堂一区| 久久一区二区三区免费播放| 日本无卡码免费一区二区三区| 97精品国产福利一区二区三区|