本集定位:
這套ui組件我原本是先從button作的, 可是我發現每一個組件都要用到icon這個組件, 若是沒有他, 不少組件無法擴展, 並且icon自己不依賴其餘組件, 因此仍是先把它做爲本篇文章的重點吧.
icon組件
讀過element-ui源碼的同窗都知道, 他們選擇的是字體圖標的方式來作icon組件的, 而個人這套ui在寫法與用法上參考了他們的作法, 但組件自己是靠svg來書寫的,其中的區別仍是簡單闡述一下把.
icon font 與 svgcss
行動起來
上一集基本環境已經搭建好了, 這裏咱們採用'bem'的思想, 來構建組件的樣式, 全部的樣式抽離在一個文件夾裏面, 作到組件自己沒有樣式代碼,咱們來先書寫組件的代碼.結構以下:
html
index.js文件裏面是導出這個組件:vue
import Icon from './main/icon.vue' // 明白vue.use方法原理的同窗都能明白這段代碼的意義 // 當被use的時候, 進行icon組件的渲染 Icon.install = function(Vue) { Vue.component(Icon.name, Icon); }; export default Icon
這樣單抽出來作一個文件的好處是,更好的工程化, 保證職能的單一性.git
main文件夾
爲何main文件夾裏面只有一個文件還要單獨抽成一個文件夾??, 緣由是有的組件可能要配合本身獨有的容器組件一塊兒使用, 好比一個button的包裹容器, 他可讓內部的每一個button有相同的上下左右距離, 相同的圓角等等...github
icon.vue文件面試
// 使用方法以下: <svg class="icon"> // 把名字寫在下面的'xxx'處,就能夠正常顯示圖標了; <use xlink:href="#icon-xxx"></use> </svg>
第四步: 開始正式書寫組件.npm
<template> <div class='cc-icon' }"> <svg :style="{fill:color}"> <use :xlink:href='`#icon-${name}`'></use> </svg> </div> </template> <script> export default { name: "ccIcon", props: { color: String, name: { type: String, required: true } } }; </script>
props: {// 接受一個size屬性 size: { // 由於用戶可能傳帶單位的與不帶單位的 type: [Number, String], default: "1em" } }, computed: { // 計算屬性裏面對這個值進行操做, 類型若是是數字, 就咱們來給他加上單位吧,也就是默認單位是'px' iconSize() { if (typeof this.size === "number") return this.size + "px"; else return this.size; } }
<template> <div class='cc-icon' height: iconSize, // 在此使用 width: iconSize, // 在此使用 }"> <svg :style="{fill:color}"> <use :xlink:href='`#icon-${name}`'></use> </svg> </div> </template>
<svg :style="{fill:color}" :class="[ 'cc-icon-'+name, { //icon-loading這個class名, 只有在icon的name屬性裏面有load字段的時候加上, 這個屬性名裏面的屬性就是旋轉.'~'位運算符是很高效的書寫方式, 也就是對位求反,1變0,0變1,也就是求二進制的反碼, 這裏不懂的話, 先看犀牛書, 簡單的說就是把-1轉成0了, 變成了布爾中的false; 'icon-loading':~name.indexOf('load') } ]"> <use :xlink:href='`#icon-${name}`'></use> </svg>
<div class='cc-icon' :style="{ display: 'inline-flex', height: iconSize, width: iconSize, }">
<svg :style="{fill:color}" :class="[ 'cc-icon-'+name, { 'icon-loading':~name.indexOf('load'), 'is-disabled':disabled // 在這裏進行了定義 } ]"> <use :xlink:href='`#icon-${name}`'></use> </svg> props: { disabled: Boolean // 固然是布爾類型 },
小知識點: props裏面定義了默認類型是布爾,則用戶能夠直接在標籤上寫屬性名, 不給屬性值也是能夠表明true的, 可是默認不是布爾, 不給屬性值的話, 組件裏面獲得的就是undefined;element-ui
icon.scss文件 1:disabled狀態時禁止點擊 2:icon-loading 時旋轉 @import './common/mixin.scss'; @import "./common/animation.scss"; @include b(icon) { .#{$state-prefix}disabled { cursor: not-allowed; fill: $--color-disabled; } .icon-loading { animation: rotating 1s infinite linear; } }
mixin.scss文件裏面的b方法瀏覽器
抽象出$namespace方便管理 @mixin b($block) { $B: $namespace+'-'+$block !global; .#{$B} { @content; } }
animation.scss文件svg
@keyframes rotating { 0% { transform: rotateZ(0deg); } 100% { transform: rotateZ(360deg); } }
var.scss文件
// lulu的美工很差, 只是想作出點不一樣樣子的東西玩玩 // 基本色 $--color-black:#000000 !default; $--color-white:#FFFFFF !default; // 基本色鮮豔 $--color-nomal:#409EFF !default; $--color-success:#7CCD7C !default; $--color-warning:#FFB90F !default; $--color-danger: #FF0000 !default; $--color-disabled: #bbbbbb !default; $--color-difference: #F5F7FA !default; // 字體 $--size-big: 16px; $--size-nomal: 15px; $--size-small: 14px; // 輸入框 $--color-input-placeholder:#aaa
點擊下載到本地
取出js文件, 讓在本地
用index.js文件引用這個js文件就完成了!!
結束
icon組件是最小的組件, 其餘組件的代碼量與難道都大的多, 詳細code與用法能夠訪問下面的地址, npm同步更新!
下一期是關於button的,咱們一塊兒交流吧