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

輪子嘛~總得造上一造~javascript

項目介紹

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

It's a A personal Vue UI component library .css

文檔官網

進入 PC 端直接是文檔界面,想查看 demo 效果直接將瀏覽器調成手機模式便可,若是喜歡,還請不要吝惜你的 star 哦~~html

在線效果預覽

請掃描如下二維碼vue

已有組件

安裝

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,則無需再註冊插件java

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

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

組件用法

1. swiper

目前這裏默認爲 swiper 輪播圖,若是你有特殊須要,也可使用swipe和swipe-item組合出本身的swiperwebpack

基本用法

<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(下拉刷新上拉加載)

常常用來作手機端的分頁功能,下拉刷新,上拉加載git

基本用法

<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

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

基本用法

一、只有搜索框web

<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>
複製代碼

二、搭配 SearchList 搜索結果列表vue-cli

<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>
複製代碼

高階用法

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

<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 種選擇器,時間,日期,時間與日期,以及普通選擇器

基本用法

一、時間類型選擇器(切換 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>
複製代碼

二、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

後期展望

組件庫基本組件完成的差很少,我會作一個該項目搭建以及組件開發的分享,敬請期待~~~

我的準備從新撿回本身的公衆號了,以後每週保證一篇高質量好文,感興趣的小夥伴能夠關注一波。

相關文章
相關標籤/搜索