合格前端系列第八彈-造一個屬於自己的 UI 庫

qiangdada發表於2017-12-27

輪子嘛~總得造上一造~

專案介紹

vui:一個私人的vue ui 元件庫(移動端為主)

It's a A personal Vue UI component library .

文件官網

進入 PC 端直接是文件介面,想檢視 demo 效果直接將瀏覽器調成手機模式即可,如果喜歡,還請不要吝惜你的 star 哦~~

線上效果預覽

請掃描以下二維碼

合格前端系列第八彈-造一個屬於自己的 UI 庫

已有元件

安裝

npm i x-vui -S
複製程式碼

快速開始

構建專案(配合 vue-cli)

# 全域性安裝 vue-cli
npm install --global vue-cli
# 建立一個基於 webpack 模板的新專案
vue init webpack my-vui-project
# 安裝依賴,並下載x-vui
cd my-vui-project
npm install && npm install x-vui
# 專案啟動 預設埠localhost:8080
npm run dev
複製程式碼

完整引入

import Vue from 'vue'
import vui from 'x-vui'
import 'x-vui/lib/vui-css/index.css';

Vue.use(vui)
複製程式碼

部分引入

import Vue from 'vue'
import {
  Scroller,
  Select
  // ...
} from 'x-vui'
import 'x-vui/lib/vui-css/scroller.css';
import 'x-vui/lib/vui-css/select.css';

Vue.component(Scroller.name, Scroller)
Vue.component(Select.name, Select)
複製程式碼

引入外掛

注:完整引入了vui,則無需再註冊外掛

import Vue from 'vue';
import { 
  $Toast, 
  $Dialog 
  // ...
} from 'x-vui';

Vue.prototype.$toast = $Toast
Vue.prototype.$dialog = $Dialog
複製程式碼

元件用法

1. swiper

目前這裡預設為 swiper 輪播圖,如果你有特殊需要,也可以使用swipe和swipe-item組合出自己的swiper

基本用法

<template>
  <div class="swiper-page">
    <p>正常swiper</p>
    <v-swiper :items='items' :styles="{height: '200px'}" @change="changeHandle"></v-swiper>
    <p>縮略swiper</p>
    <v-swiper type='thum' :items='items' :styles="{height: '240px'}"></v-swiper>
  </div>
</template>
<script>
export default {
  data () {
    return {
      items: [
        require('../assets/beauty_1.png'),
        require('../assets/beauty_2.png'),
        require('../assets/beauty_3.png'),
        require('../assets/beauty_4.png'),
        require('../assets/beauty_5.png')
      ],
    }
  },
  methods: {
    changeHandle (index) {
      console.log(index);
    }
  }
}
</script>
複製程式碼

Attributes

引數 說明 型別 可選值 預設值
type swiper型別 string swiper(正常)/thum(縮略) swiper
auto 自動播放時長 number 5000
items swiper展示的列表 array []
showIndicators 是否展示swiper小圓點 boolean true
styles swiper樣式控制 object {}
resetTitle 重置title內容 string

Events

事件名稱 說明 回撥引數
change swiper滑動回撥 當前swiper item索引

2. scroller(下拉重新整理上拉載入)

經常用來做手機端的分頁功能,下拉重新整理,上拉載入

基本用法

<template>
  <div class="scroller-page">
    <v-scroller
      :on-refresh="refresh"
      :on-infinite="infinite"
    >
      <ul>
        <li v-for="(list, index) in lists" :key="index">{{list}}</li>
      </ul>
    </v-scroller>
  </div>
</template>
<script>
export default {
  data () {
    return {
      len: 6,
    }
  },
  computed: {
    lists () {
      let arr = []
      for (let i = 1; i < this.len + 1; i++) {
        arr.push('列表' + i)
      }
      return arr
    }
  },
  methods: {
    // 下拉重新整理
    refresh (done) {
      setTimeout(() => {
        this.len = 6
        done()
      }, 1000)
    },
    // 上拉載入
    infinite (done) {
      setTimeout(() => {
        if (this.len >= 7) {
          done(true)
          return
        }
        this.len++
        done()
      }, 1000)
    }
  }
}
</script>
複製程式碼

Attributes

引數 說明 型別 可選值 預設值
onRefresh 下拉回撥 function
onInfinite 上拉回撥 function
width scroller寬度 string 100%
height scroller高度 string 100%
isLoadMore 是否展示上拉載入 boolean true
refreshText 下拉文字內容 string 下拉重新整理
noDataText 無資料文字 string 沒有更多資料啦~
refreshLayerColor 下拉文字顏色 string #AAA
loadingLayerColor 上拉文字顏色 string #AAA
animating 是否有動畫 boolean true
animationDuration 動畫間隔 number 250
bouncing 是否有反彈效果 string true
cssClass content css class string

Events

事件名稱 說明 回撥引數
onRefresh 下拉回撥 裡面有個done callback用於結束loading效果
onInfinite 上拉回撥 裡面有個done callback用於結束loading效果

3. search

常用於手機端搜尋關鍵字,有時候還會進行高亮匹配

基本用法

1、只有搜尋框

<template>
  <v-search
    placeholder="請輸入搜尋關鍵字"
    @search="searchFn"
    @enter="searchEnter"
  ></v-search>
</template>
<script>
export default {
  methods: {
    searchFn (query) {
      console.log('search', query)
    },
    searchEnter (query) {
      console.log('enter', query)
    }
  }
}
</script>
複製程式碼

2、搭配 SearchList 搜尋結果列表

<template>
  <v-search
    placeholder="請輸入搜尋關鍵字"
    :async="false"
    @search="searchFn"
  >
    <v-search-list :result="filterResult" @listSearch="listSearch" v-show="visible"></v-search-list>
  </v-search>
</template>
<script>
export default {
  data () {
    return {
      keyword: '',
      visible: false, // 點選列表,列表是否消失
      defaultResult: [
        'Apple',
        'Banana',
        'Orange',
        'Durian',
        'Lemon',
        'Peach',
        'Cherry',
        'Berry',
        'Core',
        'Fig',
        'Haw',
        'Melon',
        'Plum',
        'Pear',
        'Peanut',
        'Other'
      ]
    }
  },
  watch: {
    keyword (val) {
      if (!val) {
        this.visible = false;
      }
    }
  },
  methods: {
    searchFn (query) {
      this.keyword = query;
      this.visible = true;
    }
  },
  computed: {
    filterResult() {
      return this.defaultResult.filter(item => new RegExp(this.keyword, 'i').test(item));
    }
  }
}
</script>
複製程式碼

高階用法

3、定製化結果列表,關鍵字高亮匹配

<template>
  <v-search
    placeholder="請輸入搜尋關鍵字"
    :async="false"
    @search="searchFn"
  >
    <v-search-list :result="filterResult" @listSearch="listSearch" v-show="visible">
      <div class="search-result" slot="list-item" slot-scope="props">
        <p class="l" v-html="props.slotValue.name"></p>
        <p class="gray" v-show="props.slotValue.price">¥{{props.slotValue.price}}/斤</p>
        <div class="gray r" v-show="props.slotValue.amount">剩餘{{props.slotValue.amount}}斤</div>
      </div>
    </v-search-list>
  </v-search>
</template>
<script>
export default {
  data () {
    return {
      keyword: '',
      visible: false,
      defaultResult: [
        {name: 'Apple', price: 5, amount: 20},
        {name: 'Banana', price: 5, amount: 30},
        {name: 'Orange', price: 3, amount: 10},
        {name: 'Durian', price: 10, amount: 25},
        {name: 'Lemon', price: 4, amount: 30},
        {name: 'Peach', price: 5, amount: 40},
        {name: 'Cherry', price: 20, amount: 50},
        {name: 'Berry', price: 15, amount: 60},
        {name: 'Core', price: 10, amount: 21},
        {name: 'Fig', price: 10, amount: 22},
        {name: 'Haw', price: 10, amount: 23},
        {name: 'Melon', price: 10, amount: 24},
        {name: 'Plum', price: 10, amount: 25},
        {name: 'Pear', price: 10, amount: 26},
        {name: 'Peanut', price: 10, amount: 27},
        {name: 'Other'}
      ],
      // 防止defaultResult值被汙染
      copy: []
    }
  },
  watch: {
    keyword (val) {
      if (!val) {
        this.visible = false;
      }
    }
  },
  methods: {
    searchFn (query) {
      this.keyword = query;
      this.visible = true;
    },
    listSearch (index) {
      this.visible = false;
      console.log(index, this.defaultResult[index].name)
    }
  },
  computed: {
    filterResult() {
      // i 忽略大小寫
      let result = this.defaultResult.filter(item => new RegExp(this.keyword, 'i').test(item.name));
      // 關鍵字高亮匹配
      this.copy = JSON.parse(JSON.stringify(result))
      this.copy.forEach((item, index) => {
        let name = item.name, word = this.keyword;
        name = name.toLowerCase();
        word = word.toLowerCase();

        if (word && name.indexOf(word) !== -1) {
          let arr    = item.name.split('')
          let i      = name.indexOf(word);
          let len    = word.length;
          let active = '<span class="price">' + arr.splice(i, len).join('') + '</span>';
          arr.splice(i, 0, active);
          item.name  = arr.join('');
        }
      })
      return this.copy;
    }
  }
}
</script>
複製程式碼

Attributes

引數 說明 型別 可選值 預設值
async 是否進行節流 boolean true
timeout 搜尋節流時長 number 100
styles search樣式 object
placeholder placeholder string '搜尋'
autofocus 是否自動聚焦(iOS端autofocus無效) boolean
clear 進行搜尋是否清空search框內容 boolean false

Events

事件名稱 說明 回撥引數
search search搜尋回撥 搜尋文字
enter enter時搜尋回撥 搜尋文字
close 點選搜尋關閉按鈕回撥 ''

4. Dialog 彈框

基本用法

<template>
  <example-block title="基礎用法">
    <button @click="showSimpleDialog">普通 Dialog</button>
  </example-block>
</template>
<script>
export default {
  methods: {
    showSimpleDialog () {
      this.$dialog({
        title: '普通 Dialog',
        cancelText: '取消',
        okText: '確定',
        content: '測試 Dialog,測試 Dialog,測試 Dialog~~~'
      })
    }
  }
}
</script>
複製程式碼

自定義 HTML

<template>
  <example-block title="自定義 HTML">
    <button @click="showHtmlDialog">HTML Dialog</button>
  </example-block>
</template>
<script>
export default {
  methods: {
    showHtmlDialog () {
      this.$dialog({
        title: '自定義 HTML',
        cancelText: '取消',
        okText: '確定',
        content: '<strong style="color: green">測試 Dialog,測試 Dialog,測試 Dialog~~~</strong style="color: green">'
      })
    }
  }
}
</script>
複製程式碼

高階Dialog元件用法

<template>
  <div>
    <example-block title="Dialog 模板">
      <button @click="showDialogTpl">Dialog Template</button>
    </example-block>
    <v-dialog
    title="Dialog 模板"
    cancelText="取消"
    okText="確認"
    content="測試 Dialog,測試 Dialog,測試 Dialog~~~"
    :show="showDialog"
    :onCancel="close"
    :onOk="close"
    >
      <p class="modal-text">Dialog Template slot !!!</p>
    </v-dialog>
  </div>
</template>

<script>
export default {
  data () {
    return {
      showDialog: false
    }
  },
  methods: {
    showDialogTpl () {
      this.showDialog = true
    },
    close () {
      this.showDialog = false
    }
  }
}
</script>

複製程式碼

Attributes(modal)

引數 說明 型別 可選值 預設值
show modal是否顯示 boolean
title modal標題 string
content modal內容 string
onOk 確定按鈕回撥 function
onCancel 取消按鈕回撥 function
okText 確定按鈕內容 string
cancelText 取消按鈕內容 string
showCloseIcon 是否顯示關閉icon boolean true

5. Toast 輕提示

基本用法

<template>
  <example-block title="基礎用法">
    <button @click="showSimpleToast">普通文字提示</button>
  </example-block>
</template>
<script>
export default {
  methods: {
    showSimpleToast () {
      this.$toast({msg: '我是文字提示~'});
    }
  }
}
</script>
複製程式碼

自定義 HTML

<template>
  <example-block title="自定義HTML">
    <button @click="showHtmlToast">自定義HTML文字提示</button>
  </example-block>
</template>
<script>
export default {
  methods: {
    showHtmlToast () {
      this.$toast('<strong style="font-size: 20px;">HTML文字提示~</strong>');
    }
  }
}
</script>
複製程式碼

Attributes

引數 說明 型別 可選值 預設值
msg msg文字內容 string
timeout msg顯示時長 number 2000
callback 回撥函式 function
icon 特殊icon string

6. Picker 選擇器

包含常用的 4 種選擇器,時間,日期,時間與日期,以及普通選擇器

基本用法

1、時間型別選擇器(切換 type 即可)

<template>
  <x-picker 
    title="選擇日期"
    placeholder="請選擇日期" 
    v-model="now_date" 
    type="date"
  ></x-picker>
</template>
<script>
export default {
  data() {
    return {
      now_date: null // new Date().getTime()/1000
    };
  }
};
</script>
複製程式碼

2、custom 普通選擇器

<template>
  <x-picker 
    v-model="gender.value" 
    placeholder="請選擇性別" 
    :default="gender.default" 
    title="選擇性別" 
    type="custom"
  ></x-picker>
</template>
<script>
export default {
  data() {
    return {
     gender: {
        default: -1,
        value: [
          { name: "保密", value: 0 },
          { name: "男", value: 1 },
          { name: "女", value: 2 }
        ]
      }
    };
  }
};
</script>
複製程式碼

高階用法

使用 timeStep 進行分鐘的粒度選擇

<template>
  <x-picker 
    title="選擇日期"
    placeholder="請選擇日期" 
    v-model="now_date" 
    type="date"
    :timeStep="20"
  ></x-picker>
</template>
<script>
export default {
  data() {
    return {
      now_date: null // new Date().getTime()/1000
    };
  }
};
</script>
複製程式碼

使用 startYear,endYear,startDate,endDate,startMinute,endMinute 進行時間的範圍選擇。(更多的可看實際情況進行搭配)

<template>
  <x-picker 
    title="選擇日期"
    placeholder="請選擇日期" 
    v-model="now_date" 
    type="date"
    startMinute="2" endMinute="30"
  ></x-picker>
</template>
<script>
export default {
  data() {
    return {
      now_date: null // new Date().getTime()/1000
    };
  }
};
</script>
複製程式碼

Attributes

引數 說明 型別 可選值 預設值
default picker預設選中的值 string/number
type picker型別 string date/time/datetime/custom datetime
title 選擇器彈窗標題 string
placeholder placeholder string 請選擇時間
timeStep 時間選擇粒度(有分鐘的選擇器) number 1
startYear 起始年份 number/string 今年
endYear 結束年份 number/string 10年的範圍
startDate 起始日期 string
endDate 結束日期 string
startHour 起始時間 number/string 0
endHour 結束時間 number/string 23
startMinute 起始分鐘 number/string 0
endMinute 結束分鐘 number/string 59
yearFormat “年“的格式化 string {value}年
monthFormat “月“的格式化 string {value}月
dayFormat “日“的格式化 string {value}日
hourFormat “時“的格式化 string {value}時
minuteFormat “分“的格式化 string {value}分

7. Select 選擇器

當選項過多時,使用下拉選單展示並選擇內容。

基礎用法

只有一個select

<template>
  <div>
    <x-select
    title="LIST ONE"
    defaultValue="0"
    :selectData="selectData"
    :alwaysShowTitle="false"
    @search="searchFn"
    ></x-select>
  </div>
</template>
<script>
export default {
  data() {
    return {
      selectData: [
        { id: 1, name: "LIST ONE 1" },
        { id: 2, name: "LIST ONE 2" },
        { id: 3, name: "LIST ONE 3" },
        { id: 4, name: "LIST ONE 4" },
        { id: 5, name: "LIST ONE 5" }
      ],
    };
  },
  methods: {
    searchFn(index, id) {
      console.log(index, id);
    }
  }
};
</script>
複製程式碼

兩個及多個(需設定width屬性)

<template>
  <div>
    <!-- first -->
    <v-select
    title="LIST ONE"
    width="50%"
    defaultValue="0"
    @search="searchFn"
    :selectData="selectData"
    :alwaysShowTitle="false"
    ></v-select>
    <!-- second -->
    <v-select
    title="LIST TWO"
    width="50%"
    ellipsisWidth="65px"
    defaultValue="1"
    @search="searchFn1"
    :selectData="selectData1"
    ></v-select>
  </div>
</template>
<script>
export default {
  data() {
    return {
      selectData: [
        { id: 1, name: "LIST ONE 1" },
        { id: 2, name: "LIST ONE 2" },
        { id: 3, name: "LIST ONE 3" },
        { id: 4, name: "LIST ONE 4" },
        { id: 5, name: "LIST ONE 5" }
      ],
      selectData1: [
        { id: 1, name: "LIST TWO 1" },
        { id: 2, name: "LIST TWO 2" },
        { id: 3, name: "LIST TWO 3" },
        { id: 4, name: "LIST TWO 4" },
        { id: 5, name: "LIST TWO 5" }
      ]
    };
  },
  methods: {
    searchFn(index, id) {
      console.log(index, id);
    },
    searchFn1(index, id) {
      console.log(index, id);
    }
  }
};
</script>
複製程式碼

Attributes

引數 說明 型別 可選值 預設值
selectData 下拉資料 array []
title 預設顯示的標題 string
alwaysShowTitle 是否一直顯示預設標題 boolean false
defaultValue 預設選中的值 number/string 0
width select元件的寬度 string 100%
ellipsisWidth select文字超過多出省略號的寬度 string 120px

Events

事件名稱 說明 回撥引數
search select 選擇時的回撥函式 引數1:索引,引數2:所中項的id值

8. switch

表示兩種相互對立的狀態間的切換,多用於觸發「開/關」。

基本用法

注:如果未使用v-model指令進行值的雙向繫結,則switch會顯示value值對應的位置,但不能進行on-off操作

<template>
  <ul class='v-list'>
    <li><label>預設switch,值:{{val1}}</label><v-switch v-model="val1"></v-switch></li>
    <li><label>設定寬高,預設選中,值:{{val2}}</label><v-switch @change="handleChange" v-model="val2" width="50" height="30"></v-switch></li>
    <li><label>禁止點選,值:{{val3}}</label><v-switch :disabled="true"></v-switch></li>
    <li><label>禁止點選,預設選中,值:{{val4}}</label><v-switch :disabled="true" v-model="val4"></v-switch></li>
  </ul>
</template>
<script>
export default {
  data () {
    return {
      val1: false,
      val2: true,
      val3: false,
      val4: true
    }
  },
  methods: {
    handleChange (val, oldVal) {
      console.log(val, oldVal);
    }
  }
}
</script>
複製程式碼

Attributes

引數 說明 型別 可選值 預設值
width switch的寬度(畫素) number/string 60
height switch的高度(畫素) number/string
disabled 是否禁用 boolean false
value switch初始化選擇狀態 boolean/number/string 0
activeClass switch 開啟時的class string avtive
inactiveClass switch 關閉時的class string inactive

Events

事件名稱 說明 回撥引數
change switch 狀態發生變化時的回撥函式 新狀態的值

以上元件便是目前vui所有的元件了,後期會不斷的進行維護並進行新元件的開發。

vui github傳送門:github.com/Brickies/vu…

vui npm傳送門:www.npmjs.com/package/x-v…

vui 文件官網傳送門:brickies.github.io/vui

如果小夥伴們喜歡我的vui,歡迎 star

如果有什麼問題歡迎小夥伴們隨時提 Issue

如果有好的元件歡迎小夥伴們隨時提PR,我會不定期進行merge

後期展望

元件庫基本元件完成的差不多,我會做一個該專案搭建以及元件開發的分享,敬請期待~~~

相關文章