qiangdada

个人技术站

欢迎来到 qiangdada 的个人技术站 ~

前端交流群:731175396

公众号:『合格前端』

img

造一个属于自己的组件库

一、项目介绍

vui:一个私人的vue ui 组件库(移动端为主)

It’s a A personal Vue UI component library .

二、文档官网

进入 PC 端直接是文档界面,想查看 demo 效果直接将浏览器调成手机模式即可,如果喜欢,还请不要吝惜你的 star 哦~~

在线效果预览

请扫描以下二维码

已有组件

三、安装

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"></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效果

常用于手机端搜索关键字,有时候还会进行高亮匹配

基本用法

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">¥/斤</p>
        <div class="gray r" v-show="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,值:</label><v-switch v-model="val1"></v-switch></li>
    <li><label>设置宽高,默认选中,值:</label><v-switch @change="handleChange" v-model="val2" width="50" height="30"></v-switch></li>
    <li><label>禁止点击,值:</label><v-switch :disabled="true"></v-switch></li>
    <li><label>禁止点击,默认选中,值:</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传送门:https://github.com/Brickies/vui

vui npm传送门:https://www.npmjs.com/package/x-vui

vui 文档官网传送门:https://brickies.github.io/vui

如果小伙伴们喜欢我的vui,欢迎 star 。

如果有什么问题欢迎小伙伴们随时提 Issue

如果有好的组件欢迎小伙伴们随时提PR,我会不定期进行merge

六、后期展望

组件库基本组件完成的差不多,我会做一个该项目搭建以及组件开发的分享,敬请期待~~~

回到顶部

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开 支付宝 或者 微信 扫一扫,即可进行扫码打赏哦