UI組件庫從1到N開發心得-組件篇

正文

距離第一篇UI組件庫文章發佈已通過去3個月了,在此期間利用零零散散的時間持續更新owl-ui組件庫,目前owl-ui移動端組件庫已經更新3大類(基礎、表單、彈出層)9種組件(Button、Tabs、Input、Select、Switch、Drawer、Dialog、Picker、Toast)供使用。本篇文章主要講述我在這3個月內開發UI組件的我的心得。若是想了解項目結構能夠閱讀上一篇文章,若是想了解實現原理能夠閱讀源碼。全部鏈接在文章的結尾處。css

咱們從彈出層組件講起vue

前方多圖預警git

先看效果圖。github



我在選擇寫組件的時候,首先選擇作彈出層部分。爲何呢?我列出如下幾點。web

  1. 共性高、可複用。
  2. 兼容性高。
  3. 快速出貨,提高成就感。

先說第一點:共性高、可複用api

由於本人很是笨,因此作事以前須要構思好久,這樣會減小以後重複性的工做。好比在作彈出層的時候,很多人會發現以上組件的共同點。沒錯,他們都是顯示隱藏(廢話)。咱們接着往下分析,除了顯示或隱藏以外,他們大部分都有遮罩層部分。還有動畫效果也一致。咱們先根據這幾點把功能抽象出來,如何作呢?bash

在vue和less中都有mixins方式,根據mixins咱們很方便的將組件中的共性提取出來,達到代碼精簡的目的。如下代碼就是彈出層組件中顯示隱藏功能的mixins文件。less

// src/common/mixins/visibility.js

const EVENT_TOGGLE = 'toggle'

export default {
  model: {
    prop: 'visible',
    event: EVENT_TOGGLE
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    zIndex: {
      type: Number,
      default: 100
    },
    maskStyle: {
      type: Object,
      default: () => {}
    },
    containerStyle: {
      type: Object,
      default: () => {}
    }
  },
  data () {
    return {
      isVisible: false
    }
  },
  methods: {
    hide () {
      this.isVisible = false
    },
    show () {
      this.isVisible = true
    }
  },
  watch: {
    isVisible (val) {
      this.$emit('update:visible', val)
      this.$emit('callback', val)
      if (this.lockScroll) {
        document.body.style.overflow = val ? 'hidden' : ''
      }
    },
    visible: {
      handler (val) {
        this.isVisible = val
      }
    }
  },
  beforeDestroy () {
    this.lockScroll && (document.body.style.overflow = '')
  }
}
複製代碼

上面主要作一件事,根據visible屬性判斷組件展現隱藏ide

使用方式以下:函數

// 組件文件

<script>
import visibilityMixin from 'mixins/visibility'

export default {
    mixins: [ visibilityMixin ]
}
</script>
複製代碼

順便說一下項目中運用到less的mixins運用,好比1px問題。

// src/styles/common/border.less

.min-device-pixel-ratio(@scale2, @scale3) {
  @media screen and (min-device-pixel-ratio: 2), (-webkit-min-device-pixel-ratio: 2) {
    transform: @scale2;
  }
  @media screen and (min-device-pixel-ratio: 3), (-webkit-min-device-pixel-ratio: 3) {
    transform: @scale3;
  }
}

.border-1px(@color: #DDD, @radius: 2PX, @style: solid) {
  &::before {
    content: "";
    pointer-events: none;
    display: block;
    position: absolute;
    left: 0;
    top: 0;
    transform-origin: 0 0;
    border: 1PX @style @color;
    border-radius: @radius;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    @media screen and (min-device-pixel-ratio: 2), (-webkit-min-device-pixel-ratio: 2) {
      width: 200%;
      height: 200%;
      border-radius: @radius * 2;
      transform: scale(.5);
    }
    @media screen and (min-device-pixel-ratio: 3), (-webkit-min-device-pixel-ratio: 3) {
      width: 300%;
      height: 300%;
      border-radius: @radius * 3;
      transform: scale(.33);
    }
  }
}

.border-top-1px(@color: #DDD, @style: solid) {
  &::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    border-top: 1Px @style @color;
    transform-origin: 0 0;
    .min-device-pixel-ratio(scaleY(.5), scaleY(.33));
  }
}
複製代碼

該函數能夠經過傳參改變線的顏色和類型。

使用方式以下:

// src/styles/packages/dialog.less

@import "../common/border";

@dialog-prefix-cls: ~"@{css-prefix}dialog";

.@{dialog-prefix-cls} {
    ...
    &-btns {
        ...
        .border-top-1px(); // Here
    }
}
複製代碼

合理的運用mixins可使得項目結構清晰、減小冗餘代碼更利於後期維護。

優化方式有不少種,每一個人有不一樣的編碼習慣,因人而異。可是目標都是一致的,讓本身的代碼變得簡潔、精煉和易讀。

在彈出層中將公共部分抽象封裝,好比遮罩層

// src/common/components/popup-mask.vue

<template>
  <div class="popup-mask"
       :style="{ ...maskStyle, zIndex: zIndex - 1 }"
       @click.stop.prevent="handleMask"></div>
</template>

<script>
export default {
  props: {
    name: String,
    maskStyle: Object,
    zIndex: Number
  },
  methods: {
    handleMask (event) {
      this.$emit('click', event)
    }
  }
}
</script>
複製代碼

第二點:兼容性高

我在工做中接觸的移動端需求比較多,PC端作過一些管理後臺。移動端與PC端的項目,給我最最直觀的感覺是,移動端要求UI極其嚴格,一像素都不能差,而PC端差很少就能夠了,UI設計師們也不會過多糾結PC端作出來的頁面是否跟原型圖徹底吻合。

在移動端,有的產品特別喜歡更改UI設計,特別是有表單部分的頁面,今天產品嫌棄字體小了,明天可能以爲字體又太大了;今天把輸入框改爲圓角,明天就喜歡直角。今天以爲橫向佈局好,沒準明天就要試試縱向佈局。產品以爲這麼改沒關係,卻不知若是項目中運用了UI組件庫,這麼修改完後,代碼冗餘太多。都是爲了更好的用戶體驗,慢慢也能理解。在那以後的幾個移動端項目裏,表單部分基本不會用到UI組件庫。可是彈出層部分沒有過多的限制,據我瞭解到的產品內部最統一的就是彈出層。若是有同窗想用owl-ui的彈出層部分的話,能夠放心用,支持按需加載。

第三點:快速出貨,提高成就感

我喜歡把長期計劃拆解成多個很小的事情來作,就是制定不少小目標。比如遊戲進度條同樣,使其量化。之因此這麼作的緣由是,我能週期性的看到個人工做成果,這樣能夠激勵本身,提高信心。

彈出層組件中,mixins作好以後,像toast、dialog、drawer組件只剩下設計api部分而已。而picker組件是基於drawer組件來實現的內容部分而已。當picker組件實現完成,這時已經說明表單的select組件也已經完成了。提及來簡單,其實作起來也不難。

最後在使用彈出層組件時,我想用api調用的方式來使用它。這裏我借鑑了cube-ui的vue-create-api,可是由於部分方法不太適合我,因此我稍加改動,借鑑(抄)到本身的庫中。

好比Toast組件,官網給出的使用方式以下:

const toast = this.$createToast({
    time: 1000,
    txt: 'Toast time 1s'
})
toast.show()
複製代碼

我是個懶人,對我來講使用一個消息提醒要寫這麼多,我就以爲很煩惱,因此我在owl-ui中把vue-create-api稍加改造後,Toast使用方式以下:

this.$toast('歡迎光臨')
複製代碼

清爽了不少。

其餘類型組件使用狀況,有人喜歡整套使用,有人喜歡部分使用。而我屬於後者。

結語

我寫組件庫的目的就兩點。第一點能夠幫助我從新梳理一遍vue的知識體系,瞭解到自身的不足,不斷的克服困難,讓本身成長。第二點結識更多圈內的朋友,提升見識。我會持續更新迭代owl-ui組件庫,歡迎喜歡技術的朋友多提建議。最後附上吳軍博士說過話,這句話讓我終身受益。

什麼事情從0分作到50分靠常識,從50分作到90分靠技術,從90分作到100分靠的是藝術。作到90分咱們能夠經過努力能達到,至因而否能作到更好,就依人而定了。

連接

UI組件庫從0到1開發心得

github

owl-ui主頁

vue-create-api更改版

less版1px方案

祝工做順利

鄧文斌

2019年5月20日

相關文章
相關標籤/搜索