25 changed files with 6222 additions and 0 deletions
@ -0,0 +1,47 @@ |
|||
## 1.0.4(2024-01-27) |
|||
- 修复 修复错别字chagne为change |
|||
## 1.0.3(2022-09-16) |
|||
- 可以使用 uni-scss 控制主题色 |
|||
## 1.0.2(2022-06-30) |
|||
- 优化 在 uni-forms 中的依赖注入方式 |
|||
## 1.0.1(2022-02-07) |
|||
- 修复 multiple 为 true 时,v-model 的值为 null 报错的 bug |
|||
## 1.0.0(2021-11-19) |
|||
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) |
|||
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-data-checkbox](https://uniapp.dcloud.io/component/uniui/uni-data-checkbox) |
|||
## 0.2.5(2021-08-23) |
|||
- 修复 在uni-forms中 modelValue 中不存在当前字段,当前字段必填写也不参与校验的问题 |
|||
## 0.2.4(2021-08-17) |
|||
- 修复 单选 list 模式下 ,icon 为 left 时,选中图标不显示的问题 |
|||
## 0.2.3(2021-08-11) |
|||
- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题 |
|||
## 0.2.2(2021-07-30) |
|||
- 优化 在uni-forms组件,与label不对齐的问题 |
|||
## 0.2.1(2021-07-27) |
|||
- 修复 单选默认值为0不能选中的Bug |
|||
## 0.2.0(2021-07-13) |
|||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) |
|||
## 0.1.11(2021-07-06) |
|||
- 优化 删除无用日志 |
|||
## 0.1.10(2021-07-05) |
|||
- 修复 由 0.1.9 引起的非 nvue 端图标不显示的问题 |
|||
## 0.1.9(2021-07-05) |
|||
- 修复 nvue 黑框样式问题 |
|||
## 0.1.8(2021-06-28) |
|||
- 修复 selectedTextColor 属性不生效的Bug |
|||
## 0.1.7(2021-06-02) |
|||
- 新增 map 属性,可以方便映射text/value属性 |
|||
## 0.1.6(2021-05-26) |
|||
- 修复 不关联服务空间的情况下组件报错的Bug |
|||
## 0.1.5(2021-05-12) |
|||
- 新增 组件示例地址 |
|||
## 0.1.4(2021-04-09) |
|||
- 修复 nvue 下无法选中的问题 |
|||
## 0.1.3(2021-03-22) |
|||
- 新增 disabled属性 |
|||
## 0.1.2(2021-02-24) |
|||
- 优化 默认颜色显示 |
|||
## 0.1.1(2021-02-24) |
|||
- 新增 支持nvue |
|||
## 0.1.0(2021-02-18) |
|||
- “暂无数据”显示居中 |
|||
@ -0,0 +1,821 @@ |
|||
<template> |
|||
<view class="uni-data-checklist" :style="{'margin-top':isTop+'px'}"> |
|||
<template v-if="!isLocal"> |
|||
<view class="uni-data-loading"> |
|||
<uni-load-more v-if="!mixinDatacomErrorMessage" status="loading" iconType="snow" :iconSize="18" :content-text="contentText"></uni-load-more> |
|||
<text v-else>{{mixinDatacomErrorMessage}}</text> |
|||
</view> |
|||
</template> |
|||
<template v-else> |
|||
<checkbox-group v-if="multiple" class="checklist-group" :class="{'is-list':mode==='list' || wrap}" @change="change"> |
|||
<label class="checklist-box" :class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']" |
|||
:style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index"> |
|||
<checkbox class="hidden" hidden :disabled="disabled || !!item.disabled" :value="item[map.value]+''" :checked="item.selected" /> |
|||
<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')" class="checkbox__inner" :style="item.styleIcon"> |
|||
<view class="checkbox__inner-icon"></view> |
|||
</view> |
|||
<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}"> |
|||
<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text> |
|||
<view v-if="mode === 'list' && icon === 'right'" class="checkobx__list" :style="item.styleBackgroud"></view> |
|||
</view> |
|||
</label> |
|||
</checkbox-group> |
|||
<radio-group v-else class="checklist-group" :class="{'is-list':mode==='list','is-wrap':wrap}" @change="change"> |
|||
<!-- --> |
|||
<label class="checklist-box" :class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']" |
|||
:style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index"> |
|||
<radio class="hidden" hidden :disabled="disabled || item.disabled" :value="item[map.value]+''" :checked="item.selected" /> |
|||
<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')" class="radio__inner" |
|||
:style="item.styleBackgroud"> |
|||
<view class="radio__inner-icon" :style="item.styleIcon"></view> |
|||
</view> |
|||
<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}"> |
|||
<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text> |
|||
<view v-if="mode === 'list' && icon === 'right'" :style="item.styleRightIcon" class="checkobx__list"></view> |
|||
</view> |
|||
</label> |
|||
</radio-group> |
|||
</template> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
/** |
|||
* DataChecklist 数据选择器 |
|||
* @description 通过数据渲染 checkbox 和 radio |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=xxx |
|||
* @property {String} mode = [default| list | button | tag] 显示模式 |
|||
* @value default 默认横排模式 |
|||
* @value list 列表模式 |
|||
* @value button 按钮模式 |
|||
* @value tag 标签模式 |
|||
* @property {Boolean} multiple = [true|false] 是否多选 |
|||
* @property {Array|String|Number} value 默认值 |
|||
* @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}] |
|||
* @property {Number|String} min 最小选择个数 ,multiple为true时生效 |
|||
* @property {Number|String} max 最大选择个数 ,multiple为true时生效 |
|||
* @property {Boolean} wrap 是否换行显示 |
|||
* @property {String} icon = [left|right] list 列表模式下icon显示位置 |
|||
* @property {Boolean} selectedColor 选中颜色 |
|||
* @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效 |
|||
* @property {Boolean} selectedTextColor 选中文本颜色,如不填写则自动显示 |
|||
* @property {Object} map 字段映射, 默认 map={text:'text',value:'value'} |
|||
* @value left 左侧显示 |
|||
* @value right 右侧显示 |
|||
* @event {Function} change 选中发生变化触发 |
|||
*/ |
|||
|
|||
export default { |
|||
name: 'uniDataChecklist', |
|||
mixins: [uniCloud.mixinDatacom || {}], |
|||
emits:['input','update:modelValue','change'], |
|||
props: { |
|||
mode: { |
|||
type: String, |
|||
default: 'default' |
|||
}, |
|||
|
|||
multiple: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
value: { |
|||
type: [Array, String, Number], |
|||
default () { |
|||
return '' |
|||
} |
|||
}, |
|||
// TODO vue3 |
|||
modelValue: { |
|||
type: [Array, String, Number], |
|||
default() { |
|||
return ''; |
|||
} |
|||
}, |
|||
localdata: { |
|||
type: Array, |
|||
default () { |
|||
return [] |
|||
} |
|||
}, |
|||
min: { |
|||
type: [Number, String], |
|||
default: '' |
|||
}, |
|||
max: { |
|||
type: [Number, String], |
|||
default: '' |
|||
}, |
|||
wrap: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
icon: { |
|||
type: String, |
|||
default: 'left' |
|||
}, |
|||
selectedColor: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
selectedTextColor: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
emptyText:{ |
|||
type: String, |
|||
default: '暂无数据' |
|||
}, |
|||
disabled:{ |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
map:{ |
|||
type: Object, |
|||
default(){ |
|||
return { |
|||
text:'text', |
|||
value:'value' |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
watch: { |
|||
localdata: { |
|||
handler(newVal) { |
|||
this.range = newVal |
|||
this.dataList = this.getDataList(this.getSelectedValue(newVal)) |
|||
}, |
|||
deep: true |
|||
}, |
|||
mixinDatacomResData(newVal) { |
|||
this.range = newVal |
|||
this.dataList = this.getDataList(this.getSelectedValue(newVal)) |
|||
}, |
|||
value(newVal) { |
|||
this.dataList = this.getDataList(newVal) |
|||
// fix by mehaotian is_reset 在 uni-forms 中定义 |
|||
// if(!this.is_reset){ |
|||
// this.is_reset = false |
|||
// this.formItem && this.formItem.setValue(newVal) |
|||
// } |
|||
}, |
|||
modelValue(newVal) { |
|||
this.dataList = this.getDataList(newVal); |
|||
// if(!this.is_reset){ |
|||
// this.is_reset = false |
|||
// this.formItem && this.formItem.setValue(newVal) |
|||
// } |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
dataList: [], |
|||
range: [], |
|||
contentText: { |
|||
contentdown: '查看更多', |
|||
contentrefresh: '加载中', |
|||
contentnomore: '没有更多' |
|||
}, |
|||
isLocal:true, |
|||
styles: { |
|||
selectedColor: '#2979ff', |
|||
selectedTextColor: '#666', |
|||
}, |
|||
isTop:0 |
|||
}; |
|||
}, |
|||
computed:{ |
|||
dataValue(){ |
|||
if(this.value === '')return this.modelValue |
|||
if(this.modelValue === '') return this.value |
|||
return this.value |
|||
} |
|||
}, |
|||
created() { |
|||
// this.form = this.getForm('uniForms') |
|||
// this.formItem = this.getForm('uniFormsItem') |
|||
// this.formItem && this.formItem.setValue(this.value) |
|||
|
|||
// if (this.formItem) { |
|||
// this.isTop = 6 |
|||
// if (this.formItem.name) { |
|||
// // 如果存在name添加默认值,否则formData 中不存在这个字段不校验 |
|||
// if(!this.is_reset){ |
|||
// this.is_reset = false |
|||
// this.formItem.setValue(this.dataValue) |
|||
// } |
|||
// this.rename = this.formItem.name |
|||
// this.form.inputChildrens.push(this) |
|||
// } |
|||
// } |
|||
|
|||
if (this.localdata && this.localdata.length !== 0) { |
|||
this.isLocal = true |
|||
this.range = this.localdata |
|||
this.dataList = this.getDataList(this.getSelectedValue(this.range)) |
|||
} else { |
|||
if (this.collection) { |
|||
this.isLocal = false |
|||
this.loadData() |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
loadData() { |
|||
this.mixinDatacomGet().then(res=>{ |
|||
this.mixinDatacomResData = res.result.data |
|||
if(this.mixinDatacomResData.length === 0){ |
|||
this.isLocal = false |
|||
this.mixinDatacomErrorMessage = this.emptyText |
|||
}else{ |
|||
this.isLocal = true |
|||
} |
|||
}).catch(err=>{ |
|||
this.mixinDatacomErrorMessage = err.message |
|||
}) |
|||
}, |
|||
/** |
|||
* 获取父元素实例 |
|||
*/ |
|||
getForm(name = 'uniForms') { |
|||
let parent = this.$parent; |
|||
let parentName = parent.$options.name; |
|||
while (parentName !== name) { |
|||
parent = parent.$parent; |
|||
if (!parent) return false |
|||
parentName = parent.$options.name; |
|||
} |
|||
return parent; |
|||
}, |
|||
change(e) { |
|||
const values = e.detail.value |
|||
|
|||
let detail = { |
|||
value: [], |
|||
data: [] |
|||
} |
|||
|
|||
if (this.multiple) { |
|||
this.range.forEach(item => { |
|||
|
|||
if (values.includes(item[this.map.value] + '')) { |
|||
detail.value.push(item[this.map.value]) |
|||
detail.data.push(item) |
|||
} |
|||
}) |
|||
} else { |
|||
const range = this.range.find(item => (item[this.map.value] + '') === values) |
|||
if (range) { |
|||
detail = { |
|||
value: range[this.map.value], |
|||
data: range |
|||
} |
|||
} |
|||
} |
|||
// this.formItem && this.formItem.setValue(detail.value) |
|||
// TODO 兼容 vue2 |
|||
this.$emit('input', detail.value); |
|||
// // TOTO 兼容 vue3 |
|||
this.$emit('update:modelValue', detail.value); |
|||
this.$emit('change', { |
|||
detail |
|||
}) |
|||
if (this.multiple) { |
|||
// 如果 v-model 没有绑定 ,则走内部逻辑 |
|||
// if (this.value.length === 0) { |
|||
this.dataList = this.getDataList(detail.value, true) |
|||
// } |
|||
} else { |
|||
this.dataList = this.getDataList(detail.value) |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 获取渲染的新数组 |
|||
* @param {Object} value 选中内容 |
|||
*/ |
|||
getDataList(value) { |
|||
// 解除引用关系,破坏原引用关系,避免污染源数据 |
|||
let dataList = JSON.parse(JSON.stringify(this.range)) |
|||
let list = [] |
|||
if (this.multiple) { |
|||
if (!Array.isArray(value)) { |
|||
value = [] |
|||
} |
|||
} |
|||
dataList.forEach((item, index) => { |
|||
item.disabled = item.disable || item.disabled || false |
|||
if (this.multiple) { |
|||
if (value.length > 0) { |
|||
let have = value.find(val => val === item[this.map.value]) |
|||
item.selected = have !== undefined |
|||
} else { |
|||
item.selected = false |
|||
} |
|||
} else { |
|||
item.selected = value === item[this.map.value] |
|||
} |
|||
|
|||
list.push(item) |
|||
}) |
|||
return this.setRange(list) |
|||
}, |
|||
/** |
|||
* 处理最大最小值 |
|||
* @param {Object} list |
|||
*/ |
|||
setRange(list) { |
|||
let selectList = list.filter(item => item.selected) |
|||
let min = Number(this.min) || 0 |
|||
let max = Number(this.max) || '' |
|||
list.forEach((item, index) => { |
|||
if (this.multiple) { |
|||
if (selectList.length <= min) { |
|||
let have = selectList.find(val => val[this.map.value] === item[this.map.value]) |
|||
if (have !== undefined) { |
|||
item.disabled = true |
|||
} |
|||
} |
|||
|
|||
if (selectList.length >= max && max !== '') { |
|||
let have = selectList.find(val => val[this.map.value] === item[this.map.value]) |
|||
if (have === undefined) { |
|||
item.disabled = true |
|||
} |
|||
} |
|||
} |
|||
this.setStyles(item, index) |
|||
list[index] = item |
|||
}) |
|||
return list |
|||
}, |
|||
/** |
|||
* 设置 class |
|||
* @param {Object} item |
|||
* @param {Object} index |
|||
*/ |
|||
setStyles(item, index) { |
|||
// 设置自定义样式 |
|||
item.styleBackgroud = this.setStyleBackgroud(item) |
|||
item.styleIcon = this.setStyleIcon(item) |
|||
item.styleIconText = this.setStyleIconText(item) |
|||
item.styleRightIcon = this.setStyleRightIcon(item) |
|||
}, |
|||
|
|||
/** |
|||
* 获取选中值 |
|||
* @param {Object} range |
|||
*/ |
|||
getSelectedValue(range) { |
|||
if (!this.multiple) return this.dataValue |
|||
let selectedArr = [] |
|||
range.forEach((item) => { |
|||
if (item.selected) { |
|||
selectedArr.push(item[this.map.value]) |
|||
} |
|||
}) |
|||
return this.dataValue.length > 0 ? this.dataValue : selectedArr |
|||
}, |
|||
|
|||
/** |
|||
* 设置背景样式 |
|||
*/ |
|||
setStyleBackgroud(item) { |
|||
let styles = {} |
|||
let selectedColor = this.selectedColor?this.selectedColor:'#2979ff' |
|||
if (this.selectedColor) { |
|||
if (this.mode !== 'list') { |
|||
styles['border-color'] = item.selected?selectedColor:'#DCDFE6' |
|||
} |
|||
if (this.mode === 'tag') { |
|||
styles['background-color'] = item.selected? selectedColor:'#f5f5f5' |
|||
} |
|||
} |
|||
let classles = '' |
|||
for (let i in styles) { |
|||
classles += `${i}:${styles[i]};` |
|||
} |
|||
return classles |
|||
}, |
|||
setStyleIcon(item) { |
|||
let styles = {} |
|||
let classles = '' |
|||
if (this.selectedColor) { |
|||
let selectedColor = this.selectedColor?this.selectedColor:'#2979ff' |
|||
styles['background-color'] = item.selected?selectedColor:'#fff' |
|||
styles['border-color'] = item.selected?selectedColor:'#DCDFE6' |
|||
|
|||
if(!item.selected && item.disabled){ |
|||
styles['background-color'] = '#F2F6FC' |
|||
styles['border-color'] = item.selected?selectedColor:'#DCDFE6' |
|||
} |
|||
} |
|||
for (let i in styles) { |
|||
classles += `${i}:${styles[i]};` |
|||
} |
|||
return classles |
|||
}, |
|||
setStyleIconText(item) { |
|||
let styles = {} |
|||
let classles = '' |
|||
if (this.selectedColor) { |
|||
let selectedColor = this.selectedColor?this.selectedColor:'#2979ff' |
|||
if (this.mode === 'tag') { |
|||
styles.color = item.selected?(this.selectedTextColor?this.selectedTextColor:'#fff'):'#666' |
|||
} else { |
|||
styles.color = item.selected?(this.selectedTextColor?this.selectedTextColor:selectedColor):'#666' |
|||
} |
|||
if(!item.selected && item.disabled){ |
|||
styles.color = '#999' |
|||
} |
|||
} |
|||
for (let i in styles) { |
|||
classles += `${i}:${styles[i]};` |
|||
} |
|||
return classles |
|||
}, |
|||
setStyleRightIcon(item) { |
|||
let styles = {} |
|||
let classles = '' |
|||
if (this.mode === 'list') { |
|||
styles['border-color'] = item.selected?this.styles.selectedColor:'#DCDFE6' |
|||
} |
|||
for (let i in styles) { |
|||
classles += `${i}:${styles[i]};` |
|||
} |
|||
|
|||
return classles |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
$uni-primary: #2979ff !default; |
|||
$border-color: #DCDFE6; |
|||
$disable:0.4; |
|||
|
|||
@mixin flex { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.uni-data-loading { |
|||
@include flex; |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
align-items: center; |
|||
height: 36px; |
|||
padding-left: 10px; |
|||
color: #999; |
|||
} |
|||
|
|||
.uni-data-checklist { |
|||
position: relative; |
|||
z-index: 0; |
|||
flex: 1; |
|||
// 多选样式 |
|||
.checklist-group { |
|||
@include flex; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
|
|||
&.is-list { |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.checklist-box { |
|||
@include flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
position: relative; |
|||
margin: 5px 0; |
|||
margin-right: 25px; |
|||
|
|||
.hidden { |
|||
position: absolute; |
|||
opacity: 0; |
|||
} |
|||
|
|||
// 文字样式 |
|||
.checklist-content { |
|||
@include flex; |
|||
flex: 1; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
.checklist-text { |
|||
font-size: 14px; |
|||
color: #666; |
|||
margin-left: 5px; |
|||
line-height: 14px; |
|||
} |
|||
|
|||
.checkobx__list { |
|||
border-right-width: 1px; |
|||
border-right-color: #007aff; |
|||
border-right-style: solid; |
|||
border-bottom-width:1px; |
|||
border-bottom-color: #007aff; |
|||
border-bottom-style: solid; |
|||
height: 12px; |
|||
width: 6px; |
|||
left: -5px; |
|||
transform-origin: center; |
|||
transform: rotate(45deg); |
|||
opacity: 0; |
|||
} |
|||
} |
|||
|
|||
// 多选样式 |
|||
.checkbox__inner { |
|||
/* #ifndef APP-NVUE */ |
|||
flex-shrink: 0; |
|||
box-sizing: border-box; |
|||
/* #endif */ |
|||
position: relative; |
|||
width: 16px; |
|||
height: 16px; |
|||
border: 1px solid $border-color; |
|||
border-radius: 4px; |
|||
background-color: #fff; |
|||
z-index: 1; |
|||
.checkbox__inner-icon { |
|||
position: absolute; |
|||
/* #ifdef APP-NVUE */ |
|||
top: 2px; |
|||
/* #endif */ |
|||
/* #ifndef APP-NVUE */ |
|||
top: 1px; |
|||
/* #endif */ |
|||
left: 5px; |
|||
height: 8px; |
|||
width: 4px; |
|||
border-right-width: 1px; |
|||
border-right-color: #fff; |
|||
border-right-style: solid; |
|||
border-bottom-width:1px ; |
|||
border-bottom-color: #fff; |
|||
border-bottom-style: solid; |
|||
opacity: 0; |
|||
transform-origin: center; |
|||
transform: rotate(40deg); |
|||
} |
|||
} |
|||
|
|||
// 单选样式 |
|||
.radio__inner { |
|||
@include flex; |
|||
/* #ifndef APP-NVUE */ |
|||
flex-shrink: 0; |
|||
box-sizing: border-box; |
|||
/* #endif */ |
|||
justify-content: center; |
|||
align-items: center; |
|||
position: relative; |
|||
width: 16px; |
|||
height: 16px; |
|||
border: 1px solid $border-color; |
|||
border-radius: 16px; |
|||
background-color: #fff; |
|||
z-index: 1; |
|||
|
|||
.radio__inner-icon { |
|||
width: 8px; |
|||
height: 8px; |
|||
border-radius: 10px; |
|||
opacity: 0; |
|||
} |
|||
} |
|||
|
|||
// 默认样式 |
|||
&.is--default { |
|||
|
|||
// 禁用 |
|||
&.is-disable { |
|||
/* #ifdef H5 */ |
|||
cursor: not-allowed; |
|||
/* #endif */ |
|||
.checkbox__inner { |
|||
background-color: #F2F6FC; |
|||
border-color: $border-color; |
|||
/* #ifdef H5 */ |
|||
cursor: not-allowed; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.radio__inner { |
|||
background-color: #F2F6FC; |
|||
border-color: $border-color; |
|||
} |
|||
.checklist-text { |
|||
color: #999; |
|||
} |
|||
} |
|||
|
|||
// 选中 |
|||
&.is-checked { |
|||
.checkbox__inner { |
|||
border-color: $uni-primary; |
|||
background-color: $uni-primary; |
|||
|
|||
.checkbox__inner-icon { |
|||
opacity: 1; |
|||
transform: rotate(45deg); |
|||
} |
|||
} |
|||
.radio__inner { |
|||
border-color: $uni-primary; |
|||
.radio__inner-icon { |
|||
opacity: 1; |
|||
background-color: $uni-primary; |
|||
} |
|||
} |
|||
.checklist-text { |
|||
color: $uni-primary; |
|||
} |
|||
// 选中禁用 |
|||
&.is-disable { |
|||
.checkbox__inner { |
|||
opacity: $disable; |
|||
} |
|||
|
|||
.checklist-text { |
|||
opacity: $disable; |
|||
} |
|||
.radio__inner { |
|||
opacity: $disable; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 按钮样式 |
|||
&.is--button { |
|||
margin-right: 10px; |
|||
padding: 5px 10px; |
|||
border: 1px $border-color solid; |
|||
border-radius: 3px; |
|||
transition: border-color 0.2s; |
|||
|
|||
// 禁用 |
|||
&.is-disable { |
|||
/* #ifdef H5 */ |
|||
cursor: not-allowed; |
|||
/* #endif */ |
|||
border: 1px #eee solid; |
|||
opacity: $disable; |
|||
.checkbox__inner { |
|||
background-color: #F2F6FC; |
|||
border-color: $border-color; |
|||
/* #ifdef H5 */ |
|||
cursor: not-allowed; |
|||
/* #endif */ |
|||
} |
|||
.radio__inner { |
|||
background-color: #F2F6FC; |
|||
border-color: $border-color; |
|||
/* #ifdef H5 */ |
|||
cursor: not-allowed; |
|||
/* #endif */ |
|||
} |
|||
.checklist-text { |
|||
color: #999; |
|||
} |
|||
} |
|||
|
|||
&.is-checked { |
|||
border-color: $uni-primary; |
|||
.checkbox__inner { |
|||
border-color: $uni-primary; |
|||
background-color: $uni-primary; |
|||
.checkbox__inner-icon { |
|||
opacity: 1; |
|||
transform: rotate(45deg); |
|||
} |
|||
} |
|||
|
|||
.radio__inner { |
|||
border-color: $uni-primary; |
|||
|
|||
.radio__inner-icon { |
|||
opacity: 1; |
|||
background-color: $uni-primary; |
|||
} |
|||
} |
|||
|
|||
.checklist-text { |
|||
color: $uni-primary; |
|||
} |
|||
|
|||
// 选中禁用 |
|||
&.is-disable { |
|||
opacity: $disable; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 标签样式 |
|||
&.is--tag { |
|||
margin-right: 10px; |
|||
padding: 5px 10px; |
|||
border: 1px $border-color solid; |
|||
border-radius: 3px; |
|||
background-color: #f5f5f5; |
|||
|
|||
.checklist-text { |
|||
margin: 0; |
|||
color: #666; |
|||
} |
|||
|
|||
// 禁用 |
|||
&.is-disable { |
|||
/* #ifdef H5 */ |
|||
cursor: not-allowed; |
|||
/* #endif */ |
|||
opacity: $disable; |
|||
} |
|||
|
|||
&.is-checked { |
|||
background-color: $uni-primary; |
|||
border-color: $uni-primary; |
|||
|
|||
.checklist-text { |
|||
color: #fff; |
|||
} |
|||
} |
|||
} |
|||
// 列表样式 |
|||
&.is--list { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
/* #endif */ |
|||
padding: 10px 15px; |
|||
padding-left: 0; |
|||
margin: 0; |
|||
|
|||
&.is-list-border { |
|||
border-top: 1px #eee solid; |
|||
} |
|||
|
|||
// 禁用 |
|||
&.is-disable { |
|||
/* #ifdef H5 */ |
|||
cursor: not-allowed; |
|||
/* #endif */ |
|||
.checkbox__inner { |
|||
background-color: #F2F6FC; |
|||
border-color: $border-color; |
|||
/* #ifdef H5 */ |
|||
cursor: not-allowed; |
|||
/* #endif */ |
|||
} |
|||
.checklist-text { |
|||
color: #999; |
|||
} |
|||
} |
|||
|
|||
&.is-checked { |
|||
.checkbox__inner { |
|||
border-color: $uni-primary; |
|||
background-color: $uni-primary; |
|||
|
|||
.checkbox__inner-icon { |
|||
opacity: 1; |
|||
transform: rotate(45deg); |
|||
} |
|||
} |
|||
.radio__inner { |
|||
.radio__inner-icon { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
.checklist-text { |
|||
color: $uni-primary; |
|||
} |
|||
|
|||
.checklist-content { |
|||
.checkobx__list { |
|||
opacity: 1; |
|||
border-color: $uni-primary; |
|||
} |
|||
} |
|||
|
|||
// 选中禁用 |
|||
&.is-disable { |
|||
.checkbox__inner { |
|||
opacity: $disable; |
|||
} |
|||
|
|||
.checklist-text { |
|||
opacity: $disable; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,84 @@ |
|||
{ |
|||
"id": "uni-data-checkbox", |
|||
"displayName": "uni-data-checkbox 数据选择器", |
|||
"version": "1.0.4", |
|||
"description": "通过数据驱动的单选框和复选框", |
|||
"keywords": [ |
|||
"uni-ui", |
|||
"checkbox", |
|||
"单选", |
|||
"多选", |
|||
"单选多选" |
|||
], |
|||
"repository": "https://github.com/dcloudio/uni-ui", |
|||
"engines": { |
|||
"HBuilderX": "^3.1.1" |
|||
}, |
|||
"directories": { |
|||
"example": "../../temps/example_temps" |
|||
}, |
|||
"dcloudext": { |
|||
"sale": { |
|||
"regular": { |
|||
"price": "0.00" |
|||
}, |
|||
"sourcecode": { |
|||
"price": "0.00" |
|||
} |
|||
}, |
|||
"contact": { |
|||
"qq": "" |
|||
}, |
|||
"declaration": { |
|||
"ads": "无", |
|||
"data": "无", |
|||
"permissions": "无" |
|||
}, |
|||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", |
|||
"type": "component-vue" |
|||
}, |
|||
"uni_modules": { |
|||
"dependencies": ["uni-load-more","uni-scss"], |
|||
"encrypt": [], |
|||
"platforms": { |
|||
"cloud": { |
|||
"tcb": "y", |
|||
"aliyun": "y" |
|||
}, |
|||
"client": { |
|||
"App": { |
|||
"app-vue": "y", |
|||
"app-nvue": "y" |
|||
}, |
|||
"H5-mobile": { |
|||
"Safari": "y", |
|||
"Android Browser": "y", |
|||
"微信浏览器(Android)": "y", |
|||
"QQ浏览器(Android)": "y" |
|||
}, |
|||
"H5-pc": { |
|||
"Chrome": "y", |
|||
"IE": "y", |
|||
"Edge": "y", |
|||
"Firefox": "y", |
|||
"Safari": "y" |
|||
}, |
|||
"小程序": { |
|||
"微信": "y", |
|||
"阿里": "y", |
|||
"百度": "y", |
|||
"字节跳动": "y", |
|||
"QQ": "y" |
|||
}, |
|||
"快应用": { |
|||
"华为": "u", |
|||
"联盟": "u" |
|||
}, |
|||
"Vue": { |
|||
"vue2": "y", |
|||
"vue3": "y" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
|
|||
|
|||
## DataCheckbox 数据驱动的单选复选框 |
|||
> **组件名:uni-data-checkbox** |
|||
> 代码块: `uDataCheckbox` |
|||
|
|||
|
|||
本组件是基于uni-app基础组件checkbox的封装。本组件要解决问题包括: |
|||
|
|||
1. 数据绑定型组件:给本组件绑定一个data,会自动渲染一组候选内容。再以往,开发者需要编写不少代码实现类似功能 |
|||
2. 自动的表单校验:组件绑定了data,且符合[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)组件的表单校验规范,搭配使用会自动实现表单校验 |
|||
3. 本组件合并了单选多选 |
|||
4. 本组件有若干风格选择,如普通的单选多选框、并列button风格、tag风格。开发者可以快速选择需要的风格。但作为一个封装组件,样式代码虽然不用自己写了,却会牺牲一定的样式自定义性 |
|||
|
|||
在uniCloud开发中,`DB Schema`中配置了enum枚举等类型后,在web控制台的[自动生成表单](https://uniapp.dcloud.io/uniCloud/schema?id=autocode)功能中,会自动生成``uni-data-checkbox``组件并绑定好data |
|||
|
|||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-checkbox) |
|||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |
|||
@ -0,0 +1,107 @@ |
|||
## 1.1.15(2024-02-21) |
|||
- 新增 左侧插槽:left |
|||
## 1.1.14(2024-02-19) |
|||
- 修复 onBlur的emit传值错误 |
|||
## 1.1.12(2024-01-29) |
|||
- 补充 adjust-position文档属性补充 |
|||
## 1.1.11(2024-01-29) |
|||
- 补充 adjust-position属性传递值:(Boolean)当键盘弹起时,是否自动上推页面 |
|||
## 1.1.10(2024-01-22) |
|||
- 去除 移除无用的log输出 |
|||
## 1.1.9(2023-04-11) |
|||
- 修复 vue3 下 keyboardheightchange 事件报错的bug |
|||
## 1.1.8(2023-03-29) |
|||
- 优化 trim 属性默认值 |
|||
## 1.1.7(2023-03-29) |
|||
- 新增 cursor-spacing 属性 |
|||
## 1.1.6(2023-01-28) |
|||
- 新增 keyboardheightchange 事件,可监听键盘高度变化 |
|||
## 1.1.5(2022-11-29) |
|||
- 优化 主题样式 |
|||
## 1.1.4(2022-10-27) |
|||
- 修复 props 中背景颜色无默认值的bug |
|||
## 1.1.0(2022-06-30) |
|||
|
|||
- 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容 |
|||
- 新增 clear 事件,点击右侧叉号图标触发 |
|||
- 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发 |
|||
- 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等 |
|||
|
|||
## 1.0.5(2022-06-07) |
|||
|
|||
- 优化 clearable 显示策略 |
|||
|
|||
## 1.0.4(2022-06-07) |
|||
|
|||
- 优化 clearable 显示策略 |
|||
|
|||
## 1.0.3(2022-05-20) |
|||
|
|||
- 修复 关闭图标某些情况下无法取消的 bug |
|||
|
|||
## 1.0.2(2022-04-12) |
|||
|
|||
- 修复 默认值不生效的 bug |
|||
|
|||
## 1.0.1(2022-04-02) |
|||
|
|||
- 修复 value 不能为 0 的 bug |
|||
|
|||
## 1.0.0(2021-11-19) |
|||
|
|||
- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) |
|||
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-easyinput](https://uniapp.dcloud.io/component/uniui/uni-easyinput) |
|||
|
|||
## 0.1.4(2021-08-20) |
|||
|
|||
- 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug |
|||
|
|||
## 0.1.3(2021-08-11) |
|||
|
|||
- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题 |
|||
|
|||
## 0.1.2(2021-07-30) |
|||
|
|||
- 优化 vue3 下事件警告的问题 |
|||
|
|||
## 0.1.1 |
|||
|
|||
- 优化 errorMessage 属性支持 Boolean 类型 |
|||
|
|||
## 0.1.0(2021-07-13) |
|||
|
|||
- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) |
|||
|
|||
## 0.0.16(2021-06-29) |
|||
|
|||
- 修复 confirmType 属性(仅 type="text" 生效)导致多行文本框无法换行的 bug |
|||
|
|||
## 0.0.15(2021-06-21) |
|||
|
|||
- 修复 passwordIcon 属性拼写错误的 bug |
|||
|
|||
## 0.0.14(2021-06-18) |
|||
|
|||
- 新增 passwordIcon 属性,当 type=password 时是否显示小眼睛图标 |
|||
- 修复 confirmType 属性不生效的问题 |
|||
|
|||
## 0.0.13(2021-06-04) |
|||
|
|||
- 修复 disabled 状态可清出内容的 bug |
|||
|
|||
## 0.0.12(2021-05-12) |
|||
|
|||
- 新增 组件示例地址 |
|||
|
|||
## 0.0.11(2021-05-07) |
|||
|
|||
- 修复 input-border 属性不生效的问题 |
|||
|
|||
## 0.0.10(2021-04-30) |
|||
|
|||
- 修复 ios 遮挡文字、显示一半的问题 |
|||
|
|||
## 0.0.9(2021-02-05) |
|||
|
|||
- 调整为 uni_modules 目录规范 |
|||
- 优化 兼容 nvue 页面 |
|||
@ -0,0 +1,54 @@ |
|||
/** |
|||
* @desc 函数防抖 |
|||
* @param func 目标函数 |
|||
* @param wait 延迟执行毫秒数 |
|||
* @param immediate true - 立即执行, false - 延迟执行 |
|||
*/ |
|||
export const debounce = function(func, wait = 1000, immediate = true) { |
|||
let timer; |
|||
return function() { |
|||
let context = this, |
|||
args = arguments; |
|||
if (timer) clearTimeout(timer); |
|||
if (immediate) { |
|||
let callNow = !timer; |
|||
timer = setTimeout(() => { |
|||
timer = null; |
|||
}, wait); |
|||
if (callNow) func.apply(context, args); |
|||
} else { |
|||
timer = setTimeout(() => { |
|||
func.apply(context, args); |
|||
}, wait) |
|||
} |
|||
} |
|||
} |
|||
/** |
|||
* @desc 函数节流 |
|||
* @param func 函数 |
|||
* @param wait 延迟执行毫秒数 |
|||
* @param type 1 使用表时间戳,在时间段开始的时候触发 2 使用表定时器,在时间段结束的时候触发 |
|||
*/ |
|||
export const throttle = (func, wait = 1000, type = 1) => { |
|||
let previous = 0; |
|||
let timeout; |
|||
return function() { |
|||
let context = this; |
|||
let args = arguments; |
|||
if (type === 1) { |
|||
let now = Date.now(); |
|||
|
|||
if (now - previous > wait) { |
|||
func.apply(context, args); |
|||
previous = now; |
|||
} |
|||
} else if (type === 2) { |
|||
if (!timeout) { |
|||
timeout = setTimeout(() => { |
|||
timeout = null; |
|||
func.apply(context, args) |
|||
}, wait) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,671 @@ |
|||
<template> |
|||
<view class="uni-easyinput" :class="{ 'uni-easyinput-error': msg }" :style="boxStyle"> |
|||
<view class="uni-easyinput__content" :class="inputContentClass" :style="inputContentStyle"> |
|||
<uni-icons v-if="prefixIcon" class="content-clear-icon" :type="prefixIcon" color="#c0c4cc" @click="onClickIcon('prefix')" size="22"></uni-icons> |
|||
<slot name="left"> |
|||
</slot> |
|||
<textarea |
|||
v-if="type === 'textarea'" |
|||
class="uni-easyinput__content-textarea" |
|||
:class="{ 'input-padding': inputBorder }" |
|||
:name="name" |
|||
:value="val" |
|||
:placeholder="placeholder" |
|||
:placeholderStyle="placeholderStyle" |
|||
:disabled="disabled" |
|||
placeholder-class="uni-easyinput__placeholder-class" |
|||
:maxlength="inputMaxlength" |
|||
:focus="focused" |
|||
:autoHeight="autoHeight" |
|||
:cursor-spacing="cursorSpacing" |
|||
:adjust-position="adjustPosition" |
|||
@input="onInput" |
|||
@blur="_Blur" |
|||
@focus="_Focus" |
|||
@confirm="onConfirm" |
|||
@keyboardheightchange="onkeyboardheightchange" |
|||
></textarea> |
|||
<input |
|||
v-else |
|||
:type="type === 'password' ? 'text' : type" |
|||
class="uni-easyinput__content-input" |
|||
:style="inputStyle" |
|||
:name="name" |
|||
:value="val" |
|||
:password="!showPassword && type === 'password'" |
|||
:placeholder="placeholder" |
|||
:placeholderStyle="placeholderStyle" |
|||
placeholder-class="uni-easyinput__placeholder-class" |
|||
:disabled="disabled" |
|||
:maxlength="inputMaxlength" |
|||
:focus="focused" |
|||
:confirmType="confirmType" |
|||
:cursor-spacing="cursorSpacing" |
|||
:adjust-position="adjustPosition" |
|||
@focus="_Focus" |
|||
@blur="_Blur" |
|||
@input="onInput" |
|||
@confirm="onConfirm" |
|||
@keyboardheightchange="onkeyboardheightchange" |
|||
/> |
|||
|
|||
<template v-if="type === 'password' && passwordIcon"> |
|||
<!-- 开启密码时显示小眼睛 --> |
|||
<uni-icons |
|||
v-if="isVal" |
|||
class="content-clear-icon" |
|||
:class="{ 'is-textarea-icon': type === 'textarea' }" |
|||
:type="showPassword ? 'eye-slash-filled' : 'eye-filled'" |
|||
:size="22" |
|||
:color="focusShow ? primaryColor : '#c0c4cc'" |
|||
@click="onEyes" |
|||
></uni-icons> |
|||
</template> |
|||
<template v-else-if="suffixIcon"> |
|||
<uni-icons v-if="suffixIcon" class="content-clear-icon" :type="suffixIcon" color="#c0c4cc" @click="onClickIcon('suffix')" size="22"></uni-icons> |
|||
</template> |
|||
<template v-else> |
|||
<uni-icons |
|||
v-if="clearable && isVal && !disabled && type !== 'textarea'" |
|||
class="content-clear-icon" |
|||
:class="{ 'is-textarea-icon': type === 'textarea' }" |
|||
type="clear" |
|||
:size="clearSize" |
|||
:color="msg ? '#dd524d' : focusShow ? primaryColor : '#c0c4cc'" |
|||
@click="onClear" |
|||
></uni-icons> |
|||
</template> |
|||
<slot name="right"></slot> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
/** |
|||
* Easyinput 输入框 |
|||
* @description 此组件可以实现表单的输入与校验,包括 "text" 和 "textarea" 类型。 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=3455 |
|||
* @property {String} value 输入内容 |
|||
* @property {String } type 输入框的类型(默认text) password/text/textarea/.. |
|||
* @value text 文本输入键盘 |
|||
* @value textarea 多行文本输入键盘 |
|||
* @value password 密码输入键盘 |
|||
* @value number 数字输入键盘,注意iOS上app-vue弹出的数字键盘并非9宫格方式 |
|||
* @value idcard 身份证输入键盘,信、支付宝、百度、QQ小程序 |
|||
* @value digit 带小数点的数字键盘 ,App的nvue页面、微信、支付宝、百度、头条、QQ小程序支持 |
|||
* @property {Boolean} clearable 是否显示右侧清空内容的图标控件,点击可清空输入框内容(默认true) |
|||
* @property {Boolean} autoHeight 是否自动增高输入区域,type为textarea时有效(默认true) |
|||
* @property {String } placeholder 输入框的提示文字 |
|||
* @property {String } placeholderStyle placeholder的样式(内联样式,字符串),如"color: #ddd" |
|||
* @property {Boolean} focus 是否自动获得焦点(默认false) |
|||
* @property {Boolean} disabled 是否禁用(默认false) |
|||
* @property {Number } maxlength 最大输入长度,设置为 -1 的时候不限制最大长度(默认140) |
|||
* @property {String } confirmType 设置键盘右下角按钮的文字,仅在type="text"时生效(默认done) |
|||
* @property {Number } clearSize 清除图标的大小,单位px(默认15) |
|||
* @property {String} prefixIcon 输入框头部图标 |
|||
* @property {String} suffixIcon 输入框尾部图标 |
|||
* @property {String} primaryColor 设置主题色(默认#2979ff) |
|||
* @property {Boolean} trim 是否自动去除两端的空格 |
|||
* @property {Boolean} cursorSpacing 指定光标与键盘的距离,单位 px |
|||
* @property {Boolean} ajust-position 当键盘弹起时,是否上推内容,默认值:true |
|||
* @value both 去除两端空格 |
|||
* @value left 去除左侧空格 |
|||
* @value right 去除右侧空格 |
|||
* @value start 去除左侧空格 |
|||
* @value end 去除右侧空格 |
|||
* @value all 去除全部空格 |
|||
* @value none 不去除空格 |
|||
* @property {Boolean} inputBorder 是否显示input输入框的边框(默认true) |
|||
* @property {Boolean} passwordIcon type=password时是否显示小眼睛图标 |
|||
* @property {Object} styles 自定义颜色 |
|||
* @event {Function} input 输入框内容发生变化时触发 |
|||
* @event {Function} focus 输入框获得焦点时触发 |
|||
* @event {Function} blur 输入框失去焦点时触发 |
|||
* @event {Function} confirm 点击完成按钮时触发 |
|||
* @event {Function} iconClick 点击图标时触发 |
|||
* @example <uni-easyinput v-model="mobile"></uni-easyinput> |
|||
*/ |
|||
function obj2strClass(obj) { |
|||
let classess = ''; |
|||
for (let key in obj) { |
|||
const val = obj[key]; |
|||
if (val) { |
|||
classess += `${key} `; |
|||
} |
|||
} |
|||
return classess; |
|||
} |
|||
|
|||
function obj2strStyle(obj) { |
|||
let style = ''; |
|||
for (let key in obj) { |
|||
const val = obj[key]; |
|||
style += `${key}:${val};`; |
|||
} |
|||
return style; |
|||
} |
|||
import uniIcons from '../../../uni-icons/components/uni-icons/uni-icons'; |
|||
export default { |
|||
name: 'uni-easyinput', |
|||
emits: ['click', 'iconClick', 'update:modelValue', 'input', 'focus', 'blur', 'confirm', 'clear', 'eyes', 'change', 'keyboardheightchange'], |
|||
components: { |
|||
'uni-icons': uniIcons, |
|||
}, |
|||
model: { |
|||
prop: 'modelValue', |
|||
event: 'update:modelValue' |
|||
}, |
|||
options: { |
|||
virtualHost: true |
|||
}, |
|||
inject: { |
|||
form: { |
|||
from: 'uniForm', |
|||
default: null |
|||
}, |
|||
formItem: { |
|||
from: 'uniFormItem', |
|||
default: null |
|||
} |
|||
}, |
|||
props: { |
|||
name: String, |
|||
value: [Number, String], |
|||
modelValue: [Number, String], |
|||
type: { |
|||
type: String, |
|||
default: 'text' |
|||
}, |
|||
clearable: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
autoHeight: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
placeholder: { |
|||
type: String, |
|||
default: ' ' |
|||
}, |
|||
placeholderStyle: String, |
|||
focus: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
disabled: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
maxlength: { |
|||
type: [Number, String], |
|||
default: 140 |
|||
}, |
|||
confirmType: { |
|||
type: String, |
|||
default: 'done' |
|||
}, |
|||
clearSize: { |
|||
type: [Number, String], |
|||
default: 24 |
|||
}, |
|||
inputBorder: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
prefixIcon: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
suffixIcon: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
trim: { |
|||
type: [Boolean, String], |
|||
default: false |
|||
}, |
|||
cursorSpacing: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
passwordIcon: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
adjustPosition:{ |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
primaryColor: { |
|||
type: String, |
|||
default: '#2979ff' |
|||
}, |
|||
styles: { |
|||
type: Object, |
|||
default() { |
|||
return { |
|||
color: '#333', |
|||
backgroundColor: '#fff', |
|||
disableColor: '#F7F6F6', |
|||
borderColor: '#e5e5e5' |
|||
}; |
|||
} |
|||
}, |
|||
errorMessage: { |
|||
type: [String, Boolean], |
|||
default: '' |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
focused: false, |
|||
val: '', |
|||
showMsg: '', |
|||
border: false, |
|||
isFirstBorder: false, |
|||
showClearIcon: false, |
|||
showPassword: false, |
|||
focusShow: false, |
|||
localMsg: '', |
|||
isEnter: false // 用于判断当前是否是使用回车操作 |
|||
}; |
|||
}, |
|||
computed: { |
|||
// 输入框内是否有值 |
|||
isVal() { |
|||
const val = this.val; |
|||
// fixed by mehaotian 处理值为0的情况,字符串0不在处理范围 |
|||
if (val || val === 0) { |
|||
return true; |
|||
} |
|||
return false; |
|||
}, |
|||
|
|||
msg() { |
|||
// console.log('computed', this.form, this.formItem); |
|||
// if (this.form) { |
|||
// return this.errorMessage || this.formItem.errMsg; |
|||
// } |
|||
// TODO 处理头条 formItem 中 errMsg 不更新的问题 |
|||
return this.localMsg || this.errorMessage; |
|||
}, |
|||
// 因为uniapp的input组件的maxlength组件必须要数值,这里转为数值,用户可以传入字符串数值 |
|||
inputMaxlength() { |
|||
return Number(this.maxlength); |
|||
}, |
|||
|
|||
// 处理外层样式的style |
|||
boxStyle() { |
|||
return `color:${this.inputBorder && this.msg ? '#e43d33' : this.styles.color};`; |
|||
}, |
|||
// input 内容的类和样式处理 |
|||
inputContentClass() { |
|||
return obj2strClass({ |
|||
'is-input-border': this.inputBorder, |
|||
'is-input-error-border': this.inputBorder && this.msg, |
|||
'is-textarea': this.type === 'textarea', |
|||
'is-disabled': this.disabled, |
|||
'is-focused': this.focusShow |
|||
}); |
|||
}, |
|||
inputContentStyle() { |
|||
const focusColor = this.focusShow ? this.primaryColor : this.styles.borderColor; |
|||
const borderColor = this.inputBorder && this.msg ? '#dd524d' : focusColor; |
|||
return obj2strStyle({ |
|||
'border-color': borderColor || '#e5e5e5', |
|||
'background-color': this.disabled ? this.styles.disableColor : this.styles.backgroundColor |
|||
}); |
|||
}, |
|||
// input右侧样式 |
|||
inputStyle() { |
|||
const paddingRight = this.type === 'password' || this.clearable || this.prefixIcon ? '' : '10px'; |
|||
return obj2strStyle({ |
|||
'padding-right': paddingRight, |
|||
'padding-left': this.prefixIcon ? '' : '10px' |
|||
}); |
|||
} |
|||
}, |
|||
watch: { |
|||
value(newVal) { |
|||
this.val = newVal; |
|||
}, |
|||
modelValue(newVal) { |
|||
this.val = newVal; |
|||
}, |
|||
focus(newVal) { |
|||
this.$nextTick(() => { |
|||
this.focused = this.focus; |
|||
this.focusShow = this.focus; |
|||
}); |
|||
} |
|||
}, |
|||
created() { |
|||
this.init(); |
|||
// TODO 处理头条vue3 computed 不监听 inject 更改的问题(formItem.errMsg) |
|||
if (this.form && this.formItem) { |
|||
this.$watch('formItem.errMsg', newVal => { |
|||
this.localMsg = newVal; |
|||
}); |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.$nextTick(() => { |
|||
this.focused = this.focus; |
|||
this.focusShow = this.focus; |
|||
}); |
|||
}, |
|||
methods: { |
|||
/** |
|||
* 初始化变量值 |
|||
*/ |
|||
init() { |
|||
if (this.value || this.value === 0) { |
|||
this.val = this.value; |
|||
} else if (this.modelValue || this.modelValue === 0 || this.modelValue === '') { |
|||
this.val = this.modelValue; |
|||
} else { |
|||
this.val = null; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 点击图标时触发 |
|||
* @param {Object} type |
|||
*/ |
|||
onClickIcon(type) { |
|||
this.$emit('iconClick', type); |
|||
}, |
|||
|
|||
/** |
|||
* 显示隐藏内容,密码框时生效 |
|||
*/ |
|||
onEyes() { |
|||
this.showPassword = !this.showPassword; |
|||
this.$emit('eyes', this.showPassword); |
|||
}, |
|||
|
|||
/** |
|||
* 输入时触发 |
|||
* @param {Object} event |
|||
*/ |
|||
onInput(event) { |
|||
let value = event.detail.value; |
|||
// 判断是否去除空格 |
|||
if (this.trim) { |
|||
if (typeof this.trim === 'boolean' && this.trim) { |
|||
value = this.trimStr(value); |
|||
} |
|||
if (typeof this.trim === 'string') { |
|||
value = this.trimStr(value, this.trim); |
|||
} |
|||
} |
|||
if (this.errMsg) this.errMsg = ''; |
|||
this.val = value; |
|||
// TODO 兼容 vue2 |
|||
this.$emit('input', value); |
|||
// TODO 兼容 vue3 |
|||
this.$emit('update:modelValue', value); |
|||
}, |
|||
|
|||
/** |
|||
* 外部调用方法 |
|||
* 获取焦点时触发 |
|||
* @param {Object} event |
|||
*/ |
|||
onFocus() { |
|||
this.$nextTick(() => { |
|||
this.focused = true; |
|||
}); |
|||
this.$emit('focus', null); |
|||
}, |
|||
|
|||
_Focus(event) { |
|||
this.focusShow = true; |
|||
this.$emit('focus', event); |
|||
}, |
|||
|
|||
/** |
|||
* 外部调用方法 |
|||
* 失去焦点时触发 |
|||
* @param {Object} event |
|||
*/ |
|||
onBlur() { |
|||
this.focused = false; |
|||
this.$emit('blur', null); |
|||
}, |
|||
_Blur(event) { |
|||
let value = event.detail.value; |
|||
this.focusShow = false; |
|||
this.$emit('blur', event); |
|||
// 根据类型返回值,在event中获取的值理论上讲都是string |
|||
if (this.isEnter === false) { |
|||
this.$emit('change', this.val); |
|||
} |
|||
// 失去焦点时参与表单校验 |
|||
if (this.form && this.formItem) { |
|||
const { validateTrigger } = this.form; |
|||
if (validateTrigger === 'blur') { |
|||
this.formItem.onFieldChange(); |
|||
} |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 按下键盘的发送键 |
|||
* @param {Object} e |
|||
*/ |
|||
onConfirm(e) { |
|||
this.$emit('confirm', this.val); |
|||
this.isEnter = true; |
|||
this.$emit('change', this.val); |
|||
this.$nextTick(() => { |
|||
this.isEnter = false; |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 清理内容 |
|||
* @param {Object} event |
|||
*/ |
|||
onClear(event) { |
|||
this.val = ''; |
|||
// TODO 兼容 vue2 |
|||
this.$emit('input', ''); |
|||
// TODO 兼容 vue2 |
|||
// TODO 兼容 vue3 |
|||
this.$emit('update:modelValue', ''); |
|||
// 点击叉号触发 |
|||
this.$emit('clear'); |
|||
}, |
|||
|
|||
/** |
|||
* 键盘高度发生变化的时候触发此事件 |
|||
* 兼容性:微信小程序2.7.0+、App 3.1.0+ |
|||
* @param {Object} event |
|||
*/ |
|||
onkeyboardheightchange(event) { |
|||
this.$emit("keyboardheightchange",event); |
|||
}, |
|||
|
|||
/** |
|||
* 去除空格 |
|||
*/ |
|||
trimStr(str, pos = 'both') { |
|||
if (pos === 'both') { |
|||
return str.trim(); |
|||
} else if (pos === 'left') { |
|||
return str.trimLeft(); |
|||
} else if (pos === 'right') { |
|||
return str.trimRight(); |
|||
} else if (pos === 'start') { |
|||
return str.trimStart(); |
|||
} else if (pos === 'end') { |
|||
return str.trimEnd(); |
|||
} else if (pos === 'all') { |
|||
return str.replace(/\s+/g, ''); |
|||
} else if (pos === 'none') { |
|||
return str; |
|||
} |
|||
return str; |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
$uni-error: #e43d33; |
|||
$uni-border-1: #dcdfe6 !default; |
|||
|
|||
.uni-easyinput { |
|||
/* #ifndef APP-NVUE */ |
|||
width: 100%; |
|||
/* #endif */ |
|||
flex: 1; |
|||
position: relative; |
|||
text-align: left; |
|||
color: #333; |
|||
font-size: 14px; |
|||
} |
|||
|
|||
.uni-easyinput__content { |
|||
flex: 1; |
|||
/* #ifndef APP-NVUE */ |
|||
width: 100%; |
|||
display: flex; |
|||
box-sizing: border-box; |
|||
// min-height: 36px; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
align-items: center; |
|||
// 处理border动画刚开始显示黑色的问题 |
|||
border-color: #fff; |
|||
transition-property: border-color; |
|||
transition-duration: 0.3s; |
|||
} |
|||
|
|||
.uni-easyinput__content-input { |
|||
/* #ifndef APP-NVUE */ |
|||
width: auto; |
|||
/* #endif */ |
|||
position: relative; |
|||
overflow: hidden; |
|||
flex: 1; |
|||
line-height: 1; |
|||
font-size: 14px; |
|||
height: 35px; |
|||
// min-height: 36px; |
|||
} |
|||
|
|||
.uni-easyinput__placeholder-class { |
|||
color: #999; |
|||
font-size: 12px; |
|||
// font-weight: 200; |
|||
} |
|||
|
|||
.is-textarea { |
|||
align-items: flex-start; |
|||
} |
|||
|
|||
.is-textarea-icon { |
|||
margin-top: 5px; |
|||
} |
|||
|
|||
.uni-easyinput__content-textarea { |
|||
position: relative; |
|||
overflow: hidden; |
|||
flex: 1; |
|||
line-height: 1.5; |
|||
font-size: 14px; |
|||
margin: 6px; |
|||
margin-left: 0; |
|||
height: 80px; |
|||
min-height: 80px; |
|||
/* #ifndef APP-NVUE */ |
|||
min-height: 80px; |
|||
width: auto; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.input-padding { |
|||
padding-left: 10px; |
|||
} |
|||
|
|||
.content-clear-icon { |
|||
padding: 0 5px; |
|||
} |
|||
|
|||
.label-icon { |
|||
margin-right: 5px; |
|||
margin-top: -1px; |
|||
} |
|||
|
|||
// 显示边框 |
|||
.is-input-border { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
box-sizing: border-box; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
align-items: center; |
|||
border: 1px solid $uni-border-1; |
|||
border-radius: 4px; |
|||
/* #ifdef MP-ALIPAY */ |
|||
overflow: hidden; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.uni-error-message { |
|||
position: absolute; |
|||
bottom: -17px; |
|||
left: 0; |
|||
line-height: 12px; |
|||
color: $uni-error; |
|||
font-size: 12px; |
|||
text-align: left; |
|||
} |
|||
|
|||
.uni-error-msg--boeder { |
|||
position: relative; |
|||
bottom: 0; |
|||
line-height: 22px; |
|||
} |
|||
|
|||
.is-input-error-border { |
|||
border-color: $uni-error; |
|||
|
|||
.uni-easyinput__placeholder-class { |
|||
color: mix(#fff, $uni-error, 50%); |
|||
} |
|||
} |
|||
|
|||
.uni-easyinput--border { |
|||
margin-bottom: 0; |
|||
padding: 10px 15px; |
|||
// padding-bottom: 0; |
|||
border-top: 1px #eee solid; |
|||
} |
|||
|
|||
.uni-easyinput-error { |
|||
padding-bottom: 0; |
|||
} |
|||
|
|||
.is-first-border { |
|||
/* #ifndef APP-NVUE */ |
|||
border: none; |
|||
/* #endif */ |
|||
/* #ifdef APP-NVUE */ |
|||
border-width: 0; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.is-disabled { |
|||
background-color: #f7f6f6; |
|||
color: #d5d5d5; |
|||
|
|||
.uni-easyinput__placeholder-class { |
|||
color: #d5d5d5; |
|||
font-size: 12px; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,87 @@ |
|||
{ |
|||
"id": "uni-easyinput", |
|||
"displayName": "uni-easyinput 增强输入框", |
|||
"version": "1.1.15", |
|||
"description": "Easyinput 组件是对原生input组件的增强", |
|||
"keywords": [ |
|||
"uni-ui", |
|||
"uniui", |
|||
"input", |
|||
"uni-easyinput", |
|||
"输入框" |
|||
], |
|||
"repository": "https://github.com/dcloudio/uni-ui", |
|||
"engines": { |
|||
"HBuilderX": "" |
|||
}, |
|||
"directories": { |
|||
"example": "../../temps/example_temps" |
|||
}, |
|||
"dcloudext": { |
|||
"sale": { |
|||
"regular": { |
|||
"price": "0.00" |
|||
}, |
|||
"sourcecode": { |
|||
"price": "0.00" |
|||
} |
|||
}, |
|||
"contact": { |
|||
"qq": "" |
|||
}, |
|||
"declaration": { |
|||
"ads": "无", |
|||
"data": "无", |
|||
"permissions": "无" |
|||
}, |
|||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", |
|||
"type": "component-vue" |
|||
}, |
|||
"uni_modules": { |
|||
"dependencies": [ |
|||
"uni-scss", |
|||
"uni-icons" |
|||
], |
|||
"encrypt": [], |
|||
"platforms": { |
|||
"cloud": { |
|||
"tcb": "y", |
|||
"aliyun": "y" |
|||
}, |
|||
"client": { |
|||
"App": { |
|||
"app-vue": "y", |
|||
"app-nvue": "y" |
|||
}, |
|||
"H5-mobile": { |
|||
"Safari": "y", |
|||
"Android Browser": "y", |
|||
"微信浏览器(Android)": "y", |
|||
"QQ浏览器(Android)": "y" |
|||
}, |
|||
"H5-pc": { |
|||
"Chrome": "y", |
|||
"IE": "y", |
|||
"Edge": "y", |
|||
"Firefox": "y", |
|||
"Safari": "y" |
|||
}, |
|||
"小程序": { |
|||
"微信": "y", |
|||
"阿里": "y", |
|||
"百度": "y", |
|||
"字节跳动": "y", |
|||
"QQ": "y" |
|||
}, |
|||
"快应用": { |
|||
"华为": "u", |
|||
"联盟": "u" |
|||
}, |
|||
"Vue": { |
|||
"vue2": "y", |
|||
"vue3": "y" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
|
|||
|
|||
### Easyinput 增强输入框 |
|||
> **组件名:uni-easyinput** |
|||
> 代码块: `uEasyinput` |
|||
|
|||
|
|||
easyinput 组件是对原生input组件的增强 ,是专门为配合表单组件[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)而设计的,easyinput 内置了边框,图标等,同时包含 input 所有功能 |
|||
|
|||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-easyinput) |
|||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |
|||
@ -0,0 +1,94 @@ |
|||
## 1.4.10(2023-11-03) |
|||
- 优化 labelWidth 描述错误 |
|||
## 1.4.9(2023-02-10) |
|||
- 修复 required 参数无法动态绑定 |
|||
## 1.4.8(2022-08-23) |
|||
- 优化 根据 rules 自动添加 required 的问题 |
|||
## 1.4.7(2022-08-22) |
|||
- 修复 item 未设置 require 属性,rules 设置 require 后,星号也显示的 bug,详见:[https://ask.dcloud.net.cn/question/151540](https://ask.dcloud.net.cn/question/151540) |
|||
## 1.4.6(2022-07-13) |
|||
- 修复 model 需要校验的值没有声明对应字段时,导致第一次不触发校验的bug |
|||
## 1.4.5(2022-07-05) |
|||
- 新增 更多表单示例 |
|||
- 优化 子表单组件过期提示的问题 |
|||
- 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式 |
|||
## 1.4.4(2022-07-04) |
|||
- 更新 删除组件日志 |
|||
## 1.4.3(2022-07-04) |
|||
- 修复 由 1.4.0 引发的 label 插槽不生效的bug |
|||
## 1.4.2(2022-07-04) |
|||
- 修复 子组件找不到 setValue 报错的bug |
|||
## 1.4.1(2022-07-04) |
|||
- 修复 uni-data-picker 在 uni-forms-item 中报错的bug |
|||
- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug |
|||
## 1.4.0(2022-06-30) |
|||
- 【重要】组件逻辑重构,部分用法用旧版本不兼容,请注意兼容问题 |
|||
- 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力 |
|||
- 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃 |
|||
- 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效 |
|||
- 新增 onFieldChange 方法,可以对子表单进行校验,可替代binddata方法 |
|||
- 新增 子表单的 setRules 方法,配合自定义校验函数使用 |
|||
- 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则 |
|||
- 优化 动态表单校验方式,废弃拼接name的方式 |
|||
## 1.3.3(2022-06-22) |
|||
- 修复 表单校验顺序无序问题 |
|||
## 1.3.2(2021-12-09) |
|||
- |
|||
## 1.3.1(2021-11-19) |
|||
- 修复 label 插槽不生效的bug |
|||
## 1.3.0(2021-11-19) |
|||
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) |
|||
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-forms](https://uniapp.dcloud.io/component/uniui/uni-forms) |
|||
## 1.2.7(2021-08-13) |
|||
- 修复 没有添加校验规则的字段依然报错的Bug |
|||
## 1.2.6(2021-08-11) |
|||
- 修复 重置表单错误信息无法清除的问题 |
|||
## 1.2.5(2021-08-11) |
|||
- 优化 组件文档 |
|||
## 1.2.4(2021-08-11) |
|||
- 修复 表单验证只生效一次的问题 |
|||
## 1.2.3(2021-07-30) |
|||
- 优化 vue3下事件警告的问题 |
|||
## 1.2.2(2021-07-26) |
|||
- 修复 vue2 下条件编译导致destroyed生命周期失效的Bug |
|||
- 修复 1.2.1 引起的示例在小程序平台报错的Bug |
|||
## 1.2.1(2021-07-22) |
|||
- 修复 动态校验表单,默认值为空的情况下校验失效的Bug |
|||
- 修复 不指定name属性时,运行报错的Bug |
|||
- 优化 label默认宽度从65调整至70,使required为true且四字时不换行 |
|||
- 优化 组件示例,新增动态校验示例代码 |
|||
- 优化 组件文档,使用方式更清晰 |
|||
## 1.2.0(2021-07-13) |
|||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) |
|||
## 1.1.2(2021-06-25) |
|||
- 修复 pattern 属性在微信小程序平台无效的问题 |
|||
## 1.1.1(2021-06-22) |
|||
- 修复 validate-trigger属性为submit且err-show-type属性为toast时不能弹出的Bug |
|||
## 1.1.0(2021-06-22) |
|||
- 修复 只写setRules方法而导致校验不生效的Bug |
|||
- 修复 由上个办法引发的错误提示文字错位的Bug |
|||
## 1.0.48(2021-06-21) |
|||
- 修复 不设置 label 属性 ,无法设置label插槽的问题 |
|||
## 1.0.47(2021-06-21) |
|||
- 修复 不设置label属性,label-width属性不生效的bug |
|||
- 修复 setRules 方法与rules属性冲突的问题 |
|||
## 1.0.46(2021-06-04) |
|||
- 修复 动态删减数据导致报错的问题 |
|||
## 1.0.45(2021-06-04) |
|||
- 新增 modelValue 属性 ,value 即将废弃 |
|||
## 1.0.44(2021-06-02) |
|||
- 新增 uni-forms-item 可以设置单独的 rules |
|||
- 新增 validate 事件增加 keepitem 参数,可以选择那些字段不过滤 |
|||
- 优化 submit 事件重命名为 validate |
|||
## 1.0.43(2021-05-12) |
|||
- 新增 组件示例地址 |
|||
## 1.0.42(2021-04-30) |
|||
- 修复 自定义检验器失效的问题 |
|||
## 1.0.41(2021-03-05) |
|||
- 更新 校验器 |
|||
- 修复 表单规则设置类型为 number 的情况下,值为0校验失败的Bug |
|||
## 1.0.40(2021-03-04) |
|||
- 修复 动态显示uni-forms-item的情况下,submit 方法获取值错误的Bug |
|||
## 1.0.39(2021-02-05) |
|||
- 调整为uni_modules目录规范 |
|||
- 修复 校验器传入 int 等类型 ,返回String类型的Bug |
|||
@ -0,0 +1,627 @@ |
|||
<template> |
|||
<view class="uni-forms-item" |
|||
:class="['is-direction-' + localLabelPos ,border?'uni-forms-item--border':'' ,border && isFirstBorder?'is-first-border':'']"> |
|||
<slot name="label"> |
|||
<view class="uni-forms-item__label" :class="{'no-label':!label && !required}" |
|||
:style="{width:localLabelWidth,justifyContent: localLabelAlign}"> |
|||
<text v-if="required" class="is-required">*</text> |
|||
<text>{{label}}</text> |
|||
</view> |
|||
</slot> |
|||
<!-- #ifndef APP-NVUE --> |
|||
<view class="uni-forms-item__content"> |
|||
<slot></slot> |
|||
<view class="uni-forms-item__error" :class="{'msg--active':msg}"> |
|||
<text>{{msg}}</text> |
|||
</view> |
|||
</view> |
|||
<!-- #endif --> |
|||
<!-- #ifdef APP-NVUE --> |
|||
<view class="uni-forms-item__nuve-content"> |
|||
<view class="uni-forms-item__content"> |
|||
<slot></slot> |
|||
</view> |
|||
<view class="uni-forms-item__error" :class="{'msg--active':msg}"> |
|||
<text class="error-text">{{msg}}</text> |
|||
</view> |
|||
</view> |
|||
<!-- #endif --> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
/** |
|||
* uni-fomrs-item 表单子组件 |
|||
* @description uni-fomrs-item 表单子组件,提供了基础布局已经校验能力 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=2773 |
|||
* @property {Boolean} required 是否必填,左边显示红色"*"号 |
|||
* @property {String } label 输入框左边的文字提示 |
|||
* @property {Number } labelWidth label的宽度,单位px(默认70) |
|||
* @property {String } labelAlign = [left|center|right] label的文字对齐方式(默认left) |
|||
* @value left label 左侧显示 |
|||
* @value center label 居中 |
|||
* @value right label 右侧对齐 |
|||
* @property {String } errorMessage 显示的错误提示内容,如果为空字符串或者false,则不显示错误信息 |
|||
* @property {String } name 表单域的属性名,在使用校验规则时必填 |
|||
* @property {String } leftIcon 【1.4.0废弃】label左边的图标,限 uni-ui 的图标名称 |
|||
* @property {String } iconColor 【1.4.0废弃】左边通过icon配置的图标的颜色(默认#606266) |
|||
* @property {String} validateTrigger = [bind|submit|blur] 【1.4.0废弃】校验触发器方式 默认 submit |
|||
* @value bind 发生变化时触发 |
|||
* @value submit 提交时触发 |
|||
* @value blur 失去焦点触发 |
|||
* @property {String } labelPosition = [top|left] 【1.4.0废弃】label的文字的位置(默认left) |
|||
* @value top 顶部显示 label |
|||
* @value left 左侧显示 label |
|||
*/ |
|||
|
|||
export default { |
|||
name: 'uniFormsItem', |
|||
options: { |
|||
virtualHost: true |
|||
}, |
|||
provide() { |
|||
return { |
|||
uniFormItem: this |
|||
} |
|||
}, |
|||
inject: { |
|||
form: { |
|||
from: 'uniForm', |
|||
default: null |
|||
}, |
|||
}, |
|||
props: { |
|||
// 表单校验规则 |
|||
rules: { |
|||
type: Array, |
|||
default () { |
|||
return null; |
|||
} |
|||
}, |
|||
// 表单域的属性名,在使用校验规则时必填 |
|||
name: { |
|||
type: [String, Array], |
|||
default: '' |
|||
}, |
|||
required: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
label: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
// label的宽度 |
|||
labelWidth: { |
|||
type: [String, Number], |
|||
default: '' |
|||
}, |
|||
// label 居中方式,默认 left 取值 left/center/right |
|||
labelAlign: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
// 强制显示错误信息 |
|||
errorMessage: { |
|||
type: [String, Boolean], |
|||
default: '' |
|||
}, |
|||
// 1.4.0 弃用,统一使用 form 的校验时机 |
|||
// validateTrigger: { |
|||
// type: String, |
|||
// default: '' |
|||
// }, |
|||
// 1.4.0 弃用,统一使用 form 的label 位置 |
|||
// labelPosition: { |
|||
// type: String, |
|||
// default: '' |
|||
// }, |
|||
// 1.4.0 以下属性已经废弃,请使用 #label 插槽代替 |
|||
leftIcon: String, |
|||
iconColor: { |
|||
type: String, |
|||
default: '#606266' |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
errMsg: '', |
|||
userRules: null, |
|||
localLabelAlign: 'left', |
|||
localLabelWidth: '70px', |
|||
localLabelPos: 'left', |
|||
border: false, |
|||
isFirstBorder: false, |
|||
}; |
|||
}, |
|||
computed: { |
|||
// 处理错误信息 |
|||
msg() { |
|||
return this.errorMessage || this.errMsg; |
|||
} |
|||
}, |
|||
watch: { |
|||
// 规则发生变化通知子组件更新 |
|||
'form.formRules'(val) { |
|||
// TODO 处理头条vue3 watch不生效的问题 |
|||
// #ifndef MP-TOUTIAO |
|||
this.init() |
|||
// #endif |
|||
}, |
|||
'form.labelWidth'(val) { |
|||
// 宽度 |
|||
this.localLabelWidth = this._labelWidthUnit(val) |
|||
|
|||
}, |
|||
'form.labelPosition'(val) { |
|||
// 标签位置 |
|||
this.localLabelPos = this._labelPosition() |
|||
}, |
|||
'form.labelAlign'(val) { |
|||
|
|||
} |
|||
}, |
|||
created() { |
|||
this.init(true) |
|||
if (this.name && this.form) { |
|||
// TODO 处理头条vue3 watch不生效的问题 |
|||
// #ifdef MP-TOUTIAO |
|||
this.$watch('form.formRules', () => { |
|||
this.init() |
|||
}) |
|||
// #endif |
|||
|
|||
// 监听变化 |
|||
this.$watch( |
|||
() => { |
|||
const val = this.form._getDataValue(this.name, this.form.localData) |
|||
return val |
|||
}, |
|||
(value, oldVal) => { |
|||
const isEqual = this.form._isEqual(value, oldVal) |
|||
// 简单判断前后值的变化,只有发生变化才会发生校验 |
|||
// TODO 如果 oldVal = undefined ,那么大概率是源数据里没有值导致 ,这个情况不哦校验 ,可能不严谨 ,需要在做观察 |
|||
// fix by mehaotian 暂时取消 && oldVal !== undefined ,如果formData 中不存在,可能会不校验 |
|||
if (!isEqual) { |
|||
const val = this.itemSetValue(value) |
|||
this.onFieldChange(val, false) |
|||
} |
|||
}, { |
|||
immediate: false |
|||
} |
|||
); |
|||
} |
|||
|
|||
}, |
|||
// #ifndef VUE3 |
|||
destroyed() { |
|||
if (this.__isUnmounted) return |
|||
this.unInit() |
|||
}, |
|||
// #endif |
|||
// #ifdef VUE3 |
|||
unmounted() { |
|||
this.__isUnmounted = true |
|||
this.unInit() |
|||
}, |
|||
// #endif |
|||
methods: { |
|||
/** |
|||
* 外部调用方法 |
|||
* 设置规则 ,主要用于小程序自定义检验规则 |
|||
* @param {Array} rules 规则源数据 |
|||
*/ |
|||
setRules(rules = null) { |
|||
this.userRules = rules |
|||
this.init(false) |
|||
}, |
|||
// 兼容老版本表单组件 |
|||
setValue() { |
|||
// console.log('setValue 方法已经弃用,请使用最新版本的 uni-forms 表单组件以及其他关联组件。'); |
|||
}, |
|||
/** |
|||
* 外部调用方法 |
|||
* 校验数据 |
|||
* @param {any} value 需要校验的数据 |
|||
* @param {boolean} 是否立即校验 |
|||
* @return {Array|null} 校验内容 |
|||
*/ |
|||
async onFieldChange(value, formtrigger = true) { |
|||
const { |
|||
formData, |
|||
localData, |
|||
errShowType, |
|||
validateCheck, |
|||
validateTrigger, |
|||
_isRequiredField, |
|||
_realName |
|||
} = this.form |
|||
const name = _realName(this.name) |
|||
if (!value) { |
|||
value = this.form.formData[name] |
|||
} |
|||
// fixd by mehaotian 不在校验前清空信息,解决闪屏的问题 |
|||
// this.errMsg = ''; |
|||
|
|||
// fix by mehaotian 解决没有检验规则的情况下,抛出错误的问题 |
|||
const ruleLen = this.itemRules.rules && this.itemRules.rules.length |
|||
if (!this.validator || !ruleLen || ruleLen === 0) return; |
|||
|
|||
// 检验时机 |
|||
// let trigger = this.isTrigger(this.itemRules.validateTrigger, this.validateTrigger, validateTrigger); |
|||
const isRequiredField = _isRequiredField(this.itemRules.rules || []); |
|||
let result = null; |
|||
// 只有等于 bind 时 ,才能开启时实校验 |
|||
if (validateTrigger === 'bind' || formtrigger) { |
|||
// 校验当前表单项 |
|||
result = await this.validator.validateUpdate({ |
|||
[name]: value |
|||
}, |
|||
formData |
|||
); |
|||
|
|||
// 判断是否必填,非必填,不填不校验,填写才校验 ,暂时只处理 undefined 和空的情况 |
|||
if (!isRequiredField && (value === undefined || value === '')) { |
|||
result = null; |
|||
} |
|||
|
|||
// 判断错误信息显示类型 |
|||
if (result && result.errorMessage) { |
|||
if (errShowType === 'undertext') { |
|||
// 获取错误信息 |
|||
this.errMsg = !result ? '' : result.errorMessage; |
|||
} |
|||
if (errShowType === 'toast') { |
|||
uni.showToast({ |
|||
title: result.errorMessage || '校验错误', |
|||
icon: 'none' |
|||
}); |
|||
} |
|||
if (errShowType === 'modal') { |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: result.errorMessage || '校验错误' |
|||
}); |
|||
} |
|||
} else { |
|||
this.errMsg = '' |
|||
} |
|||
// 通知 form 组件更新事件 |
|||
validateCheck(result ? result : null) |
|||
} else { |
|||
this.errMsg = '' |
|||
} |
|||
return result ? result : null; |
|||
}, |
|||
/** |
|||
* 初始组件数据 |
|||
*/ |
|||
init(type = false) { |
|||
const { |
|||
validator, |
|||
formRules, |
|||
childrens, |
|||
formData, |
|||
localData, |
|||
_realName, |
|||
labelWidth, |
|||
_getDataValue, |
|||
_setDataValue |
|||
} = this.form || {} |
|||
// 对齐方式 |
|||
this.localLabelAlign = this._justifyContent() |
|||
// 宽度 |
|||
this.localLabelWidth = this._labelWidthUnit(labelWidth) |
|||
// 标签位置 |
|||
this.localLabelPos = this._labelPosition() |
|||
// 将需要校验的子组件加入form 队列 |
|||
this.form && type && childrens.push(this) |
|||
|
|||
if (!validator || !formRules) return |
|||
// 判断第一个 item |
|||
if (!this.form.isFirstBorder) { |
|||
this.form.isFirstBorder = true; |
|||
this.isFirstBorder = true; |
|||
} |
|||
|
|||
// 判断 group 里的第一个 item |
|||
if (this.group) { |
|||
if (!this.group.isFirstBorder) { |
|||
this.group.isFirstBorder = true; |
|||
this.isFirstBorder = true; |
|||
} |
|||
} |
|||
this.border = this.form.border; |
|||
// 获取子域的真实名称 |
|||
const name = _realName(this.name) |
|||
const itemRule = this.userRules || this.rules |
|||
if (typeof formRules === 'object' && itemRule) { |
|||
// 子规则替换父规则 |
|||
formRules[name] = { |
|||
rules: itemRule |
|||
} |
|||
validator.updateSchema(formRules); |
|||
} |
|||
// 注册校验规则 |
|||
const itemRules = formRules[name] || {} |
|||
this.itemRules = itemRules |
|||
// 注册校验函数 |
|||
this.validator = validator |
|||
// 默认值赋予 |
|||
this.itemSetValue(_getDataValue(this.name, localData)) |
|||
}, |
|||
unInit() { |
|||
if (this.form) { |
|||
const { |
|||
childrens, |
|||
formData, |
|||
_realName |
|||
} = this.form |
|||
childrens.forEach((item, index) => { |
|||
if (item === this) { |
|||
this.form.childrens.splice(index, 1) |
|||
delete formData[_realName(item.name)] |
|||
} |
|||
}) |
|||
} |
|||
}, |
|||
// 设置item 的值 |
|||
itemSetValue(value) { |
|||
const name = this.form._realName(this.name) |
|||
const rules = this.itemRules.rules || [] |
|||
const val = this.form._getValue(name, value, rules) |
|||
this.form._setDataValue(name, this.form.formData, val) |
|||
return val |
|||
}, |
|||
|
|||
/** |
|||
* 移除该表单项的校验结果 |
|||
*/ |
|||
clearValidate() { |
|||
this.errMsg = ''; |
|||
}, |
|||
|
|||
// 是否显示星号 |
|||
_isRequired() { |
|||
// TODO 不根据规则显示 星号,考虑后续兼容 |
|||
// if (this.form) { |
|||
// if (this.form._isRequiredField(this.itemRules.rules || []) && this.required) { |
|||
// return true |
|||
// } |
|||
// return false |
|||
// } |
|||
return this.required |
|||
}, |
|||
|
|||
// 处理对齐方式 |
|||
_justifyContent() { |
|||
if (this.form) { |
|||
const { |
|||
labelAlign |
|||
} = this.form |
|||
let labelAli = this.labelAlign ? this.labelAlign : labelAlign; |
|||
if (labelAli === 'left') return 'flex-start'; |
|||
if (labelAli === 'center') return 'center'; |
|||
if (labelAli === 'right') return 'flex-end'; |
|||
} |
|||
return 'flex-start'; |
|||
}, |
|||
// 处理 label宽度单位 ,继承父元素的值 |
|||
_labelWidthUnit(labelWidth) { |
|||
|
|||
// if (this.form) { |
|||
// const { |
|||
// labelWidth |
|||
// } = this.form |
|||
return this.num2px(this.labelWidth ? this.labelWidth : (labelWidth || (this.label ? 90 : 'auto'))) |
|||
// } |
|||
// return '70px' |
|||
}, |
|||
// 处理 label 位置 |
|||
_labelPosition() { |
|||
if (this.form) return this.form.labelPosition || 'left' |
|||
return 'left' |
|||
|
|||
}, |
|||
|
|||
/** |
|||
* 触发时机 |
|||
* @param {Object} rule 当前规则内时机 |
|||
* @param {Object} itemRlue 当前组件时机 |
|||
* @param {Object} parentRule 父组件时机 |
|||
*/ |
|||
isTrigger(rule, itemRlue, parentRule) { |
|||
// bind submit |
|||
if (rule === 'submit' || !rule) { |
|||
if (rule === undefined) { |
|||
if (itemRlue !== 'bind') { |
|||
if (!itemRlue) { |
|||
return parentRule === '' ? 'bind' : 'submit'; |
|||
} |
|||
return 'submit'; |
|||
} |
|||
return 'bind'; |
|||
} |
|||
return 'submit'; |
|||
} |
|||
return 'bind'; |
|||
}, |
|||
num2px(num) { |
|||
if (typeof num === 'number') { |
|||
return `${num}px` |
|||
} |
|||
return num |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.uni-forms-item { |
|||
position: relative; |
|||
display: flex; |
|||
/* #ifdef APP-NVUE */ |
|||
// 在 nvue 中,使用 margin-bottom error 信息会被隐藏 |
|||
padding-bottom: 22px; |
|||
/* #endif */ |
|||
/* #ifndef APP-NVUE */ |
|||
margin-bottom: 22px; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
|
|||
&__label { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
text-align: left; |
|||
font-size: 14px; |
|||
color: #606266; |
|||
height: 36px; |
|||
padding: 0 12px 0 0; |
|||
/* #ifndef APP-NVUE */ |
|||
vertical-align: middle; |
|||
flex-shrink: 0; |
|||
/* #endif */ |
|||
|
|||
/* #ifndef APP-NVUE */ |
|||
box-sizing: border-box; |
|||
|
|||
/* #endif */ |
|||
&.no-label { |
|||
padding: 0; |
|||
} |
|||
} |
|||
|
|||
&__content { |
|||
/* #ifndef MP-TOUTIAO */ |
|||
// display: flex; |
|||
// align-items: center; |
|||
/* #endif */ |
|||
position: relative; |
|||
font-size: 14px; |
|||
flex: 1; |
|||
/* #ifndef APP-NVUE */ |
|||
box-sizing: border-box; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
|
|||
/* #ifndef APP || H5 || MP-WEIXIN || APP-NVUE */ |
|||
// TODO 因为小程序平台会多一层标签节点 ,所以需要在多余节点继承当前样式 |
|||
&>uni-easyinput, |
|||
&>uni-data-picker { |
|||
width: 100%; |
|||
} |
|||
|
|||
/* #endif */ |
|||
|
|||
} |
|||
|
|||
& .uni-forms-item__nuve-content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
flex: 1; |
|||
} |
|||
|
|||
&__error { |
|||
color: #f56c6c; |
|||
font-size: 12px; |
|||
line-height: 1; |
|||
padding-top: 4px; |
|||
position: absolute; |
|||
/* #ifndef APP-NVUE */ |
|||
top: 100%; |
|||
left: 0; |
|||
transition: transform 0.3s; |
|||
transform: translateY(-100%); |
|||
/* #endif */ |
|||
/* #ifdef APP-NVUE */ |
|||
bottom: 5px; |
|||
/* #endif */ |
|||
|
|||
opacity: 0; |
|||
|
|||
.error-text { |
|||
// 只有 nvue 下这个样式才生效 |
|||
color: #f56c6c; |
|||
font-size: 12px; |
|||
} |
|||
|
|||
&.msg--active { |
|||
opacity: 1; |
|||
transform: translateY(0%); |
|||
} |
|||
} |
|||
|
|||
// 位置修饰样式 |
|||
&.is-direction-left { |
|||
flex-direction: row; |
|||
} |
|||
|
|||
&.is-direction-top { |
|||
flex-direction: column; |
|||
|
|||
.uni-forms-item__label { |
|||
padding: 0 0 8px; |
|||
line-height: 1.5715; |
|||
text-align: left; |
|||
/* #ifndef APP-NVUE */ |
|||
white-space: initial; |
|||
/* #endif */ |
|||
} |
|||
} |
|||
|
|||
.is-required { |
|||
// color: $uni-color-error; |
|||
color: #dd524d; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
|
|||
|
|||
.uni-forms-item--border { |
|||
margin-bottom: 0; |
|||
padding: 10px 0; |
|||
// padding-bottom: 0; |
|||
border-top: 1px #eee solid; |
|||
|
|||
/* #ifndef APP-NVUE */ |
|||
.uni-forms-item__content { |
|||
flex-direction: column; |
|||
justify-content: flex-start; |
|||
align-items: flex-start; |
|||
|
|||
.uni-forms-item__error { |
|||
position: relative; |
|||
top: 5px; |
|||
left: 0; |
|||
padding-top: 0; |
|||
} |
|||
} |
|||
|
|||
/* #endif */ |
|||
|
|||
/* #ifdef APP-NVUE */ |
|||
display: flex; |
|||
flex-direction: column; |
|||
|
|||
.uni-forms-item__error { |
|||
position: relative; |
|||
top: 0px; |
|||
left: 0; |
|||
padding-top: 0; |
|||
margin-top: 5px; |
|||
} |
|||
|
|||
/* #endif */ |
|||
|
|||
} |
|||
|
|||
.is-first-border { |
|||
/* #ifndef APP-NVUE */ |
|||
border: none; |
|||
/* #endif */ |
|||
/* #ifdef APP-NVUE */ |
|||
border-width: 0; |
|||
/* #endif */ |
|||
} |
|||
</style> |
|||
@ -0,0 +1,397 @@ |
|||
<template> |
|||
<view class="uni-forms"> |
|||
<form> |
|||
<slot></slot> |
|||
</form> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import Validator from './validate.js'; |
|||
import { |
|||
deepCopy, |
|||
getValue, |
|||
isRequiredField, |
|||
setDataValue, |
|||
getDataValue, |
|||
realName, |
|||
isRealName, |
|||
rawData, |
|||
isEqual |
|||
} from './utils.js' |
|||
|
|||
// #ifndef VUE3 |
|||
// 后续会慢慢废弃这个方法 |
|||
import Vue from 'vue'; |
|||
Vue.prototype.binddata = function(name, value, formName) { |
|||
if (formName) { |
|||
this.$refs[formName].setValue(name, value); |
|||
} else { |
|||
let formVm; |
|||
for (let i in this.$refs) { |
|||
const vm = this.$refs[i]; |
|||
if (vm && vm.$options && vm.$options.name === 'uniForms') { |
|||
formVm = vm; |
|||
break; |
|||
} |
|||
} |
|||
if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性'); |
|||
formVm.setValue(name, value); |
|||
} |
|||
}; |
|||
// #endif |
|||
/** |
|||
* Forms 表单 |
|||
* @description 由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=2773 |
|||
* @property {Object} rules 表单校验规则 |
|||
* @property {String} validateTrigger = [bind|submit|blur] 校验触发器方式 默认 submit |
|||
* @value bind 发生变化时触发 |
|||
* @value submit 提交时触发 |
|||
* @value blur 失去焦点时触发 |
|||
* @property {String} labelPosition = [top|left] label 位置 默认 left |
|||
* @value top 顶部显示 label |
|||
* @value left 左侧显示 label |
|||
* @property {String} labelWidth label 宽度,默认 70px |
|||
* @property {String} labelAlign = [left|center|right] label 居中方式 默认 left |
|||
* @value left label 左侧显示 |
|||
* @value center label 居中 |
|||
* @value right label 右侧对齐 |
|||
* @property {String} errShowType = [undertext|toast|modal] 校验错误信息提示方式 |
|||
* @value undertext 错误信息在底部显示 |
|||
* @value toast 错误信息toast显示 |
|||
* @value modal 错误信息modal显示 |
|||
* @event {Function} submit 提交时触发 |
|||
* @event {Function} validate 校验结果发生变化触发 |
|||
*/ |
|||
export default { |
|||
name: 'uniForms', |
|||
emits: ['validate', 'submit'], |
|||
options: { |
|||
virtualHost: true |
|||
}, |
|||
props: { |
|||
// 即将弃用 |
|||
value: { |
|||
type: Object, |
|||
default () { |
|||
return null; |
|||
} |
|||
}, |
|||
// vue3 替换 value 属性 |
|||
modelValue: { |
|||
type: Object, |
|||
default () { |
|||
return null; |
|||
} |
|||
}, |
|||
// 1.4.0 开始将不支持 v-model ,且废弃 value 和 modelValue |
|||
model: { |
|||
type: Object, |
|||
default () { |
|||
return null; |
|||
} |
|||
}, |
|||
// 表单校验规则 |
|||
rules: { |
|||
type: Object, |
|||
default () { |
|||
return {}; |
|||
} |
|||
}, |
|||
//校验错误信息提示方式 默认 undertext 取值 [undertext|toast|modal] |
|||
errShowType: { |
|||
type: String, |
|||
default: 'undertext' |
|||
}, |
|||
// 校验触发器方式 默认 bind 取值 [bind|submit] |
|||
validateTrigger: { |
|||
type: String, |
|||
default: 'submit' |
|||
}, |
|||
// label 位置,默认 left 取值 top/left |
|||
labelPosition: { |
|||
type: String, |
|||
default: 'left' |
|||
}, |
|||
// label 宽度 |
|||
labelWidth: { |
|||
type: [String, Number], |
|||
default: '' |
|||
}, |
|||
// label 居中方式,默认 left 取值 left/center/right |
|||
labelAlign: { |
|||
type: String, |
|||
default: 'left' |
|||
}, |
|||
border: { |
|||
type: Boolean, |
|||
default: false |
|||
} |
|||
}, |
|||
provide() { |
|||
return { |
|||
uniForm: this |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
// 表单本地值的记录,不应该与传如的值进行关联 |
|||
formData: {}, |
|||
formRules: {} |
|||
}; |
|||
}, |
|||
computed: { |
|||
// 计算数据源变化的 |
|||
localData() { |
|||
const localVal = this.model || this.modelValue || this.value |
|||
if (localVal) { |
|||
return deepCopy(localVal) |
|||
} |
|||
return {} |
|||
} |
|||
}, |
|||
watch: { |
|||
// 监听数据变化 ,暂时不使用,需要单独赋值 |
|||
// localData: {}, |
|||
// 监听规则变化 |
|||
rules: { |
|||
handler: function(val, oldVal) { |
|||
this.setRules(val) |
|||
}, |
|||
deep: true, |
|||
immediate: true |
|||
} |
|||
}, |
|||
created() { |
|||
// #ifdef VUE3 |
|||
let getbinddata = getApp().$vm.$.appContext.config.globalProperties.binddata |
|||
if (!getbinddata) { |
|||
getApp().$vm.$.appContext.config.globalProperties.binddata = function(name, value, formName) { |
|||
if (formName) { |
|||
this.$refs[formName].setValue(name, value); |
|||
} else { |
|||
let formVm; |
|||
for (let i in this.$refs) { |
|||
const vm = this.$refs[i]; |
|||
if (vm && vm.$options && vm.$options.name === 'uniForms') { |
|||
formVm = vm; |
|||
break; |
|||
} |
|||
} |
|||
if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性'); |
|||
formVm.setValue(name, value); |
|||
} |
|||
} |
|||
} |
|||
// #endif |
|||
|
|||
// 子组件实例数组 |
|||
this.childrens = [] |
|||
// TODO 兼容旧版 uni-data-picker ,新版本中无效,只是避免报错 |
|||
this.inputChildrens = [] |
|||
this.setRules(this.rules) |
|||
}, |
|||
methods: { |
|||
/** |
|||
* 外部调用方法 |
|||
* 设置规则 ,主要用于小程序自定义检验规则 |
|||
* @param {Array} rules 规则源数据 |
|||
*/ |
|||
setRules(rules) { |
|||
// TODO 有可能子组件合并规则的时机比这个要早,所以需要合并对象 ,而不是直接赋值,可能会被覆盖 |
|||
this.formRules = Object.assign({}, this.formRules, rules) |
|||
// 初始化校验函数 |
|||
this.validator = new Validator(rules); |
|||
}, |
|||
|
|||
/** |
|||
* 外部调用方法 |
|||
* 设置数据,用于设置表单数据,公开给用户使用 , 不支持在动态表单中使用 |
|||
* @param {Object} key |
|||
* @param {Object} value |
|||
*/ |
|||
setValue(key, value) { |
|||
let example = this.childrens.find(child => child.name === key); |
|||
if (!example) return null; |
|||
this.formData[key] = getValue(key, value, (this.formRules[key] && this.formRules[key].rules) || []) |
|||
return example.onFieldChange(this.formData[key]); |
|||
}, |
|||
|
|||
/** |
|||
* 外部调用方法 |
|||
* 手动提交校验表单 |
|||
* 对整个表单进行校验的方法,参数为一个回调函数。 |
|||
* @param {Array} keepitem 保留不参与校验的字段 |
|||
* @param {type} callback 方法回调 |
|||
*/ |
|||
validate(keepitem, callback) { |
|||
return this.checkAll(this.formData, keepitem, callback); |
|||
}, |
|||
|
|||
/** |
|||
* 外部调用方法 |
|||
* 部分表单校验 |
|||
* @param {Array|String} props 需要校验的字段 |
|||
* @param {Function} 回调函数 |
|||
*/ |
|||
validateField(props = [], callback) { |
|||
props = [].concat(props); |
|||
let invalidFields = {}; |
|||
this.childrens.forEach(item => { |
|||
const name = realName(item.name) |
|||
if (props.indexOf(name) !== -1) { |
|||
invalidFields = Object.assign({}, invalidFields, { |
|||
[name]: this.formData[name] |
|||
}); |
|||
} |
|||
}); |
|||
return this.checkAll(invalidFields, [], callback); |
|||
}, |
|||
|
|||
/** |
|||
* 外部调用方法 |
|||
* 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果 |
|||
* @param {Array|String} props 需要移除校验的字段 ,不填为所有 |
|||
*/ |
|||
clearValidate(props = []) { |
|||
props = [].concat(props); |
|||
this.childrens.forEach(item => { |
|||
if (props.length === 0) { |
|||
item.errMsg = ''; |
|||
} else { |
|||
const name = realName(item.name) |
|||
if (props.indexOf(name) !== -1) { |
|||
item.errMsg = ''; |
|||
} |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 外部调用方法 ,即将废弃 |
|||
* 手动提交校验表单 |
|||
* 对整个表单进行校验的方法,参数为一个回调函数。 |
|||
* @param {Array} keepitem 保留不参与校验的字段 |
|||
* @param {type} callback 方法回调 |
|||
*/ |
|||
submit(keepitem, callback, type) { |
|||
for (let i in this.dataValue) { |
|||
const itemData = this.childrens.find(v => v.name === i); |
|||
if (itemData) { |
|||
if (this.formData[i] === undefined) { |
|||
this.formData[i] = this._getValue(i, this.dataValue[i]); |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (!type) { |
|||
console.warn('submit 方法即将废弃,请使用validate方法代替!'); |
|||
} |
|||
|
|||
return this.checkAll(this.formData, keepitem, callback, 'submit'); |
|||
}, |
|||
|
|||
// 校验所有 |
|||
async checkAll(invalidFields, keepitem, callback, type) { |
|||
// 不存在校验规则 ,则停止校验流程 |
|||
if (!this.validator) return |
|||
let childrens = [] |
|||
// 处理参与校验的item实例 |
|||
for (let i in invalidFields) { |
|||
const item = this.childrens.find(v => realName(v.name) === i) |
|||
if (item) { |
|||
childrens.push(item) |
|||
} |
|||
} |
|||
|
|||
// 如果validate第一个参数是funciont ,那就走回调 |
|||
if (!callback && typeof keepitem === 'function') { |
|||
callback = keepitem; |
|||
} |
|||
|
|||
let promise; |
|||
// 如果不存在回调,那么使用 Promise 方式返回 |
|||
if (!callback && typeof callback !== 'function' && Promise) { |
|||
promise = new Promise((resolve, reject) => { |
|||
callback = function(valid, invalidFields) { |
|||
!valid ? resolve(invalidFields) : reject(valid); |
|||
}; |
|||
}); |
|||
} |
|||
|
|||
let results = []; |
|||
// 避免引用错乱 ,建议拷贝对象处理 |
|||
let tempFormData = JSON.parse(JSON.stringify(invalidFields)) |
|||
// 所有子组件参与校验,使用 for 可以使用 awiat |
|||
for (let i in childrens) { |
|||
const child = childrens[i] |
|||
let name = realName(child.name); |
|||
const result = await child.onFieldChange(tempFormData[name]); |
|||
if (result) { |
|||
results.push(result); |
|||
// toast ,modal 只需要执行第一次就可以 |
|||
if (this.errShowType === 'toast' || this.errShowType === 'modal') break; |
|||
} |
|||
} |
|||
|
|||
|
|||
if (Array.isArray(results)) { |
|||
if (results.length === 0) results = null; |
|||
} |
|||
if (Array.isArray(keepitem)) { |
|||
keepitem.forEach(v => { |
|||
let vName = realName(v); |
|||
let value = getDataValue(v, this.localData) |
|||
if (value !== undefined) { |
|||
tempFormData[vName] = value |
|||
} |
|||
}); |
|||
} |
|||
|
|||
// TODO submit 即将废弃 |
|||
if (type === 'submit') { |
|||
this.$emit('submit', { |
|||
detail: { |
|||
value: tempFormData, |
|||
errors: results |
|||
} |
|||
}); |
|||
} else { |
|||
this.$emit('validate', results); |
|||
} |
|||
|
|||
// const resetFormData = rawData(tempFormData, this.localData, this.name) |
|||
let resetFormData = {} |
|||
resetFormData = rawData(tempFormData, this.name) |
|||
callback && typeof callback === 'function' && callback(results, resetFormData); |
|||
|
|||
if (promise && callback) { |
|||
return promise; |
|||
} else { |
|||
return null; |
|||
} |
|||
|
|||
}, |
|||
|
|||
/** |
|||
* 返回validate事件 |
|||
* @param {Object} result |
|||
*/ |
|||
validateCheck(result) { |
|||
this.$emit('validate', result); |
|||
}, |
|||
_getValue: getValue, |
|||
_isRequiredField: isRequiredField, |
|||
_setDataValue: setDataValue, |
|||
_getDataValue: getDataValue, |
|||
_realName: realName, |
|||
_isRealName: isRealName, |
|||
_isEqual: isEqual |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.uni-forms {} |
|||
</style> |
|||
@ -0,0 +1,293 @@ |
|||
/** |
|||
* 简单处理对象拷贝 |
|||
* @param {Obejct} 被拷贝对象 |
|||
* @@return {Object} 拷贝对象 |
|||
*/ |
|||
export const deepCopy = (val) => { |
|||
return JSON.parse(JSON.stringify(val)) |
|||
} |
|||
/** |
|||
* 过滤数字类型 |
|||
* @param {String} format 数字类型 |
|||
* @@return {Boolean} 返回是否为数字类型 |
|||
*/ |
|||
export const typeFilter = (format) => { |
|||
return format === 'int' || format === 'double' || format === 'number' || format === 'timestamp'; |
|||
} |
|||
|
|||
/** |
|||
* 把 value 转换成指定的类型,用于处理初始值,原因是初始值需要入库不能为 undefined |
|||
* @param {String} key 字段名 |
|||
* @param {any} value 字段值 |
|||
* @param {Object} rules 表单校验规则 |
|||
*/ |
|||
export const getValue = (key, value, rules) => { |
|||
const isRuleNumType = rules.find(val => val.format && typeFilter(val.format)); |
|||
const isRuleBoolType = rules.find(val => (val.format && val.format === 'boolean') || val.format === 'bool'); |
|||
// 输入类型为 number
|
|||
if (!!isRuleNumType) { |
|||
if (!value && value !== 0) { |
|||
value = null |
|||
} else { |
|||
value = isNumber(Number(value)) ? Number(value) : value |
|||
} |
|||
} |
|||
|
|||
// 输入类型为 boolean
|
|||
if (!!isRuleBoolType) { |
|||
value = isBoolean(value) ? value : false |
|||
} |
|||
|
|||
return value; |
|||
} |
|||
|
|||
/** |
|||
* 获取表单数据 |
|||
* @param {String|Array} name 真实名称,需要使用 realName 获取 |
|||
* @param {Object} data 原始数据 |
|||
* @param {any} value 需要设置的值 |
|||
*/ |
|||
export const setDataValue = (field, formdata, value) => { |
|||
formdata[field] = value |
|||
return value || '' |
|||
} |
|||
|
|||
/** |
|||
* 获取表单数据 |
|||
* @param {String|Array} field 真实名称,需要使用 realName 获取 |
|||
* @param {Object} data 原始数据 |
|||
*/ |
|||
export const getDataValue = (field, data) => { |
|||
return objGet(data, field) |
|||
} |
|||
|
|||
/** |
|||
* 获取表单类型 |
|||
* @param {String|Array} field 真实名称,需要使用 realName 获取 |
|||
*/ |
|||
export const getDataValueType = (field, data) => { |
|||
const value = getDataValue(field, data) |
|||
return { |
|||
type: type(value), |
|||
value |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取表单可用的真实name |
|||
* @param {String|Array} name 表单name |
|||
* @@return {String} 表单可用的真实name |
|||
*/ |
|||
export const realName = (name, data = {}) => { |
|||
const base_name = _basePath(name) |
|||
if (typeof base_name === 'object' && Array.isArray(base_name) && base_name.length > 1) { |
|||
const realname = base_name.reduce((a, b) => a += `#${b}`, '_formdata_') |
|||
return realname |
|||
} |
|||
return base_name[0] || name |
|||
} |
|||
|
|||
/** |
|||
* 判断是否表单可用的真实name |
|||
* @param {String|Array} name 表单name |
|||
* @@return {String} 表单可用的真实name |
|||
*/ |
|||
export const isRealName = (name) => { |
|||
const reg = /^_formdata_#*/ |
|||
return reg.test(name) |
|||
} |
|||
|
|||
/** |
|||
* 获取表单数据的原始格式 |
|||
* @@return {Object|Array} object 需要解析的数据 |
|||
*/ |
|||
export const rawData = (object = {}, name) => { |
|||
let newData = JSON.parse(JSON.stringify(object)) |
|||
let formData = {} |
|||
for(let i in newData){ |
|||
let path = name2arr(i) |
|||
objSet(formData,path,newData[i]) |
|||
} |
|||
return formData |
|||
} |
|||
|
|||
/** |
|||
* 真实name还原为 array |
|||
* @param {*} name |
|||
*/ |
|||
export const name2arr = (name) => { |
|||
let field = name.replace('_formdata_#', '') |
|||
field = field.split('#').map(v => (isNumber(v) ? Number(v) : v)) |
|||
return field |
|||
} |
|||
|
|||
/** |
|||
* 对象中设置值 |
|||
* @param {Object|Array} object 源数据 |
|||
* @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c'] |
|||
* @param {String} value 需要设置的值 |
|||
*/ |
|||
export const objSet = (object, path, value) => { |
|||
if (typeof object !== 'object') return object; |
|||
_basePath(path).reduce((o, k, i, _) => { |
|||
if (i === _.length - 1) { |
|||
// 若遍历结束直接赋值
|
|||
o[k] = value |
|||
return null |
|||
} else if (k in o) { |
|||
// 若存在对应路径,则返回找到的对象,进行下一次遍历
|
|||
return o[k] |
|||
} else { |
|||
// 若不存在对应路径,则创建对应对象,若下一路径是数字,新对象赋值为空数组,否则赋值为空对象
|
|||
o[k] = /^[0-9]{1,}$/.test(_[i + 1]) ? [] : {} |
|||
return o[k] |
|||
} |
|||
}, object) |
|||
// 返回object
|
|||
return object; |
|||
} |
|||
|
|||
// 处理 path, path有三种形式:'a[0].b.c'、'a.0.b.c' 和 ['a','0','b','c'],需要统一处理成数组,便于后续使用
|
|||
function _basePath(path) { |
|||
// 若是数组,则直接返回
|
|||
if (Array.isArray(path)) return path |
|||
// 若有 '[',']',则替换成将 '[' 替换成 '.',去掉 ']'
|
|||
return path.replace(/\[/g, '.').replace(/\]/g, '').split('.') |
|||
} |
|||
|
|||
/** |
|||
* 从对象中获取值 |
|||
* @param {Object|Array} object 源数据 |
|||
* @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c'] |
|||
* @param {String} defaultVal 如果无法从调用链中获取值的默认值 |
|||
*/ |
|||
export const objGet = (object, path, defaultVal = 'undefined') => { |
|||
// 先将path处理成统一格式
|
|||
let newPath = _basePath(path) |
|||
// 递归处理,返回最后结果
|
|||
let val = newPath.reduce((o, k) => { |
|||
return (o || {})[k] |
|||
}, object); |
|||
return !val || val !== undefined ? val : defaultVal |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 是否为 number 类型 |
|||
* @param {any} num 需要判断的值 |
|||
* @return {Boolean} 是否为 number |
|||
*/ |
|||
export const isNumber = (num) => { |
|||
return !isNaN(Number(num)) |
|||
} |
|||
|
|||
/** |
|||
* 是否为 boolean 类型 |
|||
* @param {any} bool 需要判断的值 |
|||
* @return {Boolean} 是否为 boolean |
|||
*/ |
|||
export const isBoolean = (bool) => { |
|||
return (typeof bool === 'boolean') |
|||
} |
|||
/** |
|||
* 是否有必填字段 |
|||
* @param {Object} rules 规则 |
|||
* @return {Boolean} 是否有必填字段 |
|||
*/ |
|||
export const isRequiredField = (rules) => { |
|||
let isNoField = false; |
|||
for (let i = 0; i < rules.length; i++) { |
|||
const ruleData = rules[i]; |
|||
if (ruleData.required) { |
|||
isNoField = true; |
|||
break; |
|||
} |
|||
} |
|||
return isNoField; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 获取数据类型 |
|||
* @param {Any} obj 需要获取数据类型的值 |
|||
*/ |
|||
export const type = (obj) => { |
|||
var class2type = {}; |
|||
|
|||
// 生成class2type映射
|
|||
"Boolean Number String Function Array Date RegExp Object Error".split(" ").map(function(item, index) { |
|||
class2type["[object " + item + "]"] = item.toLowerCase(); |
|||
}) |
|||
if (obj == null) { |
|||
return obj + ""; |
|||
} |
|||
return typeof obj === "object" || typeof obj === "function" ? |
|||
class2type[Object.prototype.toString.call(obj)] || "object" : |
|||
typeof obj; |
|||
} |
|||
|
|||
/** |
|||
* 判断两个值是否相等 |
|||
* @param {any} a 值 |
|||
* @param {any} b 值 |
|||
* @return {Boolean} 是否相等 |
|||
*/ |
|||
export const isEqual = (a, b) => { |
|||
//如果a和b本来就全等
|
|||
if (a === b) { |
|||
//判断是否为0和-0
|
|||
return a !== 0 || 1 / a === 1 / b; |
|||
} |
|||
//判断是否为null和undefined
|
|||
if (a == null || b == null) { |
|||
return a === b; |
|||
} |
|||
//接下来判断a和b的数据类型
|
|||
var classNameA = toString.call(a), |
|||
classNameB = toString.call(b); |
|||
//如果数据类型不相等,则返回false
|
|||
if (classNameA !== classNameB) { |
|||
return false; |
|||
} |
|||
//如果数据类型相等,再根据不同数据类型分别判断
|
|||
switch (classNameA) { |
|||
case '[object RegExp]': |
|||
case '[object String]': |
|||
//进行字符串转换比较
|
|||
return '' + a === '' + b; |
|||
case '[object Number]': |
|||
//进行数字转换比较,判断是否为NaN
|
|||
if (+a !== +a) { |
|||
return +b !== +b; |
|||
} |
|||
//判断是否为0或-0
|
|||
return +a === 0 ? 1 / +a === 1 / b : +a === +b; |
|||
case '[object Date]': |
|||
case '[object Boolean]': |
|||
return +a === +b; |
|||
} |
|||
//如果是对象类型
|
|||
if (classNameA == '[object Object]') { |
|||
//获取a和b的属性长度
|
|||
var propsA = Object.getOwnPropertyNames(a), |
|||
propsB = Object.getOwnPropertyNames(b); |
|||
if (propsA.length != propsB.length) { |
|||
return false; |
|||
} |
|||
for (var i = 0; i < propsA.length; i++) { |
|||
var propName = propsA[i]; |
|||
//如果对应属性对应值不相等,则返回false
|
|||
if (a[propName] !== b[propName]) { |
|||
return false; |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
//如果是数组类型
|
|||
if (classNameA == '[object Array]') { |
|||
if (a.toString() == b.toString()) { |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
} |
|||
@ -0,0 +1,486 @@ |
|||
var pattern = { |
|||
email: /^\S+?@\S+?\.\S+?$/, |
|||
idcard: /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/, |
|||
url: new RegExp( |
|||
"^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$", |
|||
'i') |
|||
}; |
|||
|
|||
const FORMAT_MAPPING = { |
|||
"int": 'integer', |
|||
"bool": 'boolean', |
|||
"double": 'number', |
|||
"long": 'number', |
|||
"password": 'string' |
|||
// "fileurls": 'array'
|
|||
} |
|||
|
|||
function formatMessage(args, resources = '') { |
|||
var defaultMessage = ['label'] |
|||
defaultMessage.forEach((item) => { |
|||
if (args[item] === undefined) { |
|||
args[item] = '' |
|||
} |
|||
}) |
|||
|
|||
let str = resources |
|||
for (let key in args) { |
|||
let reg = new RegExp('{' + key + '}') |
|||
str = str.replace(reg, args[key]) |
|||
} |
|||
return str |
|||
} |
|||
|
|||
function isEmptyValue(value, type) { |
|||
if (value === undefined || value === null) { |
|||
return true; |
|||
} |
|||
|
|||
if (typeof value === 'string' && !value) { |
|||
return true; |
|||
} |
|||
|
|||
if (Array.isArray(value) && !value.length) { |
|||
return true; |
|||
} |
|||
|
|||
if (type === 'object' && !Object.keys(value).length) { |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
const types = { |
|||
integer(value) { |
|||
return types.number(value) && parseInt(value, 10) === value; |
|||
}, |
|||
string(value) { |
|||
return typeof value === 'string'; |
|||
}, |
|||
number(value) { |
|||
if (isNaN(value)) { |
|||
return false; |
|||
} |
|||
return typeof value === 'number'; |
|||
}, |
|||
"boolean": function(value) { |
|||
return typeof value === 'boolean'; |
|||
}, |
|||
"float": function(value) { |
|||
return types.number(value) && !types.integer(value); |
|||
}, |
|||
array(value) { |
|||
return Array.isArray(value); |
|||
}, |
|||
object(value) { |
|||
return typeof value === 'object' && !types.array(value); |
|||
}, |
|||
date(value) { |
|||
return value instanceof Date; |
|||
}, |
|||
timestamp(value) { |
|||
if (!this.integer(value) || Math.abs(value).toString().length > 16) { |
|||
return false |
|||
} |
|||
return true; |
|||
}, |
|||
file(value) { |
|||
return typeof value.url === 'string'; |
|||
}, |
|||
email(value) { |
|||
return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255; |
|||
}, |
|||
url(value) { |
|||
return typeof value === 'string' && !!value.match(pattern.url); |
|||
}, |
|||
pattern(reg, value) { |
|||
try { |
|||
return new RegExp(reg).test(value); |
|||
} catch (e) { |
|||
return false; |
|||
} |
|||
}, |
|||
method(value) { |
|||
return typeof value === 'function'; |
|||
}, |
|||
idcard(value) { |
|||
return typeof value === 'string' && !!value.match(pattern.idcard); |
|||
}, |
|||
'url-https'(value) { |
|||
return this.url(value) && value.startsWith('https://'); |
|||
}, |
|||
'url-scheme'(value) { |
|||
return value.startsWith('://'); |
|||
}, |
|||
'url-web'(value) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
class RuleValidator { |
|||
|
|||
constructor(message) { |
|||
this._message = message |
|||
} |
|||
|
|||
async validateRule(fieldKey, fieldValue, value, data, allData) { |
|||
var result = null |
|||
|
|||
let rules = fieldValue.rules |
|||
|
|||
let hasRequired = rules.findIndex((item) => { |
|||
return item.required |
|||
}) |
|||
if (hasRequired < 0) { |
|||
if (value === null || value === undefined) { |
|||
return result |
|||
} |
|||
if (typeof value === 'string' && !value.length) { |
|||
return result |
|||
} |
|||
} |
|||
|
|||
var message = this._message |
|||
|
|||
if (rules === undefined) { |
|||
return message['default'] |
|||
} |
|||
|
|||
for (var i = 0; i < rules.length; i++) { |
|||
let rule = rules[i] |
|||
let vt = this._getValidateType(rule) |
|||
|
|||
Object.assign(rule, { |
|||
label: fieldValue.label || `["${fieldKey}"]` |
|||
}) |
|||
|
|||
if (RuleValidatorHelper[vt]) { |
|||
result = RuleValidatorHelper[vt](rule, value, message) |
|||
if (result != null) { |
|||
break |
|||
} |
|||
} |
|||
|
|||
if (rule.validateExpr) { |
|||
let now = Date.now() |
|||
let resultExpr = rule.validateExpr(value, allData, now) |
|||
if (resultExpr === false) { |
|||
result = this._getMessage(rule, rule.errorMessage || this._message['default']) |
|||
break |
|||
} |
|||
} |
|||
|
|||
if (rule.validateFunction) { |
|||
result = await this.validateFunction(rule, value, data, allData, vt) |
|||
if (result !== null) { |
|||
break |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (result !== null) { |
|||
result = message.TAG + result |
|||
} |
|||
|
|||
return result |
|||
} |
|||
|
|||
async validateFunction(rule, value, data, allData, vt) { |
|||
let result = null |
|||
try { |
|||
let callbackMessage = null |
|||
const res = await rule.validateFunction(rule, value, allData || data, (message) => { |
|||
callbackMessage = message |
|||
}) |
|||
if (callbackMessage || (typeof res === 'string' && res) || res === false) { |
|||
result = this._getMessage(rule, callbackMessage || res, vt) |
|||
} |
|||
} catch (e) { |
|||
result = this._getMessage(rule, e.message, vt) |
|||
} |
|||
return result |
|||
} |
|||
|
|||
_getMessage(rule, message, vt) { |
|||
return formatMessage(rule, message || rule.errorMessage || this._message[vt] || message['default']) |
|||
} |
|||
|
|||
_getValidateType(rule) { |
|||
var result = '' |
|||
if (rule.required) { |
|||
result = 'required' |
|||
} else if (rule.format) { |
|||
result = 'format' |
|||
} else if (rule.arrayType) { |
|||
result = 'arrayTypeFormat' |
|||
} else if (rule.range) { |
|||
result = 'range' |
|||
} else if (rule.maximum !== undefined || rule.minimum !== undefined) { |
|||
result = 'rangeNumber' |
|||
} else if (rule.maxLength !== undefined || rule.minLength !== undefined) { |
|||
result = 'rangeLength' |
|||
} else if (rule.pattern) { |
|||
result = 'pattern' |
|||
} else if (rule.validateFunction) { |
|||
result = 'validateFunction' |
|||
} |
|||
return result |
|||
} |
|||
} |
|||
|
|||
const RuleValidatorHelper = { |
|||
required(rule, value, message) { |
|||
if (rule.required && isEmptyValue(value, rule.format || typeof value)) { |
|||
return formatMessage(rule, rule.errorMessage || message.required); |
|||
} |
|||
|
|||
return null |
|||
}, |
|||
|
|||
range(rule, value, message) { |
|||
const { |
|||
range, |
|||
errorMessage |
|||
} = rule; |
|||
|
|||
let list = new Array(range.length); |
|||
for (let i = 0; i < range.length; i++) { |
|||
const item = range[i]; |
|||
if (types.object(item) && item.value !== undefined) { |
|||
list[i] = item.value; |
|||
} else { |
|||
list[i] = item; |
|||
} |
|||
} |
|||
|
|||
let result = false |
|||
if (Array.isArray(value)) { |
|||
result = (new Set(value.concat(list)).size === list.length); |
|||
} else { |
|||
if (list.indexOf(value) > -1) { |
|||
result = true; |
|||
} |
|||
} |
|||
|
|||
if (!result) { |
|||
return formatMessage(rule, errorMessage || message['enum']); |
|||
} |
|||
|
|||
return null |
|||
}, |
|||
|
|||
rangeNumber(rule, value, message) { |
|||
if (!types.number(value)) { |
|||
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); |
|||
} |
|||
|
|||
let { |
|||
minimum, |
|||
maximum, |
|||
exclusiveMinimum, |
|||
exclusiveMaximum |
|||
} = rule; |
|||
let min = exclusiveMinimum ? value <= minimum : value < minimum; |
|||
let max = exclusiveMaximum ? value >= maximum : value > maximum; |
|||
|
|||
if (minimum !== undefined && min) { |
|||
return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMinimum ? |
|||
'exclusiveMinimum' : 'minimum' |
|||
]) |
|||
} else if (maximum !== undefined && max) { |
|||
return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMaximum ? |
|||
'exclusiveMaximum' : 'maximum' |
|||
]) |
|||
} else if (minimum !== undefined && maximum !== undefined && (min || max)) { |
|||
return formatMessage(rule, rule.errorMessage || message['number'].range) |
|||
} |
|||
|
|||
return null |
|||
}, |
|||
|
|||
rangeLength(rule, value, message) { |
|||
if (!types.string(value) && !types.array(value)) { |
|||
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); |
|||
} |
|||
|
|||
let min = rule.minLength; |
|||
let max = rule.maxLength; |
|||
let val = value.length; |
|||
|
|||
if (min !== undefined && val < min) { |
|||
return formatMessage(rule, rule.errorMessage || message['length'].minLength) |
|||
} else if (max !== undefined && val > max) { |
|||
return formatMessage(rule, rule.errorMessage || message['length'].maxLength) |
|||
} else if (min !== undefined && max !== undefined && (val < min || val > max)) { |
|||
return formatMessage(rule, rule.errorMessage || message['length'].range) |
|||
} |
|||
|
|||
return null |
|||
}, |
|||
|
|||
pattern(rule, value, message) { |
|||
if (!types['pattern'](rule.pattern, value)) { |
|||
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); |
|||
} |
|||
|
|||
return null |
|||
}, |
|||
|
|||
format(rule, value, message) { |
|||
var customTypes = Object.keys(types); |
|||
var format = FORMAT_MAPPING[rule.format] ? FORMAT_MAPPING[rule.format] : (rule.format || rule.arrayType); |
|||
|
|||
if (customTypes.indexOf(format) > -1) { |
|||
if (!types[format](value)) { |
|||
return formatMessage(rule, rule.errorMessage || message.typeError); |
|||
} |
|||
} |
|||
|
|||
return null |
|||
}, |
|||
|
|||
arrayTypeFormat(rule, value, message) { |
|||
if (!Array.isArray(value)) { |
|||
return formatMessage(rule, rule.errorMessage || message.typeError); |
|||
} |
|||
|
|||
for (let i = 0; i < value.length; i++) { |
|||
const element = value[i]; |
|||
let formatResult = this.format(rule, element, message) |
|||
if (formatResult !== null) { |
|||
return formatResult |
|||
} |
|||
} |
|||
|
|||
return null |
|||
} |
|||
} |
|||
|
|||
class SchemaValidator extends RuleValidator { |
|||
|
|||
constructor(schema, options) { |
|||
super(SchemaValidator.message); |
|||
|
|||
this._schema = schema |
|||
this._options = options || null |
|||
} |
|||
|
|||
updateSchema(schema) { |
|||
this._schema = schema |
|||
} |
|||
|
|||
async validate(data, allData) { |
|||
let result = this._checkFieldInSchema(data) |
|||
if (!result) { |
|||
result = await this.invokeValidate(data, false, allData) |
|||
} |
|||
return result.length ? result[0] : null |
|||
} |
|||
|
|||
async validateAll(data, allData) { |
|||
let result = this._checkFieldInSchema(data) |
|||
if (!result) { |
|||
result = await this.invokeValidate(data, true, allData) |
|||
} |
|||
return result |
|||
} |
|||
|
|||
async validateUpdate(data, allData) { |
|||
let result = this._checkFieldInSchema(data) |
|||
if (!result) { |
|||
result = await this.invokeValidateUpdate(data, false, allData) |
|||
} |
|||
return result.length ? result[0] : null |
|||
} |
|||
|
|||
async invokeValidate(data, all, allData) { |
|||
let result = [] |
|||
let schema = this._schema |
|||
for (let key in schema) { |
|||
let value = schema[key] |
|||
let errorMessage = await this.validateRule(key, value, data[key], data, allData) |
|||
if (errorMessage != null) { |
|||
result.push({ |
|||
key, |
|||
errorMessage |
|||
}) |
|||
if (!all) break |
|||
} |
|||
} |
|||
return result |
|||
} |
|||
|
|||
async invokeValidateUpdate(data, all, allData) { |
|||
let result = [] |
|||
for (let key in data) { |
|||
let errorMessage = await this.validateRule(key, this._schema[key], data[key], data, allData) |
|||
if (errorMessage != null) { |
|||
result.push({ |
|||
key, |
|||
errorMessage |
|||
}) |
|||
if (!all) break |
|||
} |
|||
} |
|||
return result |
|||
} |
|||
|
|||
_checkFieldInSchema(data) { |
|||
var keys = Object.keys(data) |
|||
var keys2 = Object.keys(this._schema) |
|||
if (new Set(keys.concat(keys2)).size === keys2.length) { |
|||
return '' |
|||
} |
|||
|
|||
var noExistFields = keys.filter((key) => { |
|||
return keys2.indexOf(key) < 0; |
|||
}) |
|||
var errorMessage = formatMessage({ |
|||
field: JSON.stringify(noExistFields) |
|||
}, SchemaValidator.message.TAG + SchemaValidator.message['defaultInvalid']) |
|||
return [{ |
|||
key: 'invalid', |
|||
errorMessage |
|||
}] |
|||
} |
|||
} |
|||
|
|||
function Message() { |
|||
return { |
|||
TAG: "", |
|||
default: '验证错误', |
|||
defaultInvalid: '提交的字段{field}在数据库中并不存在', |
|||
validateFunction: '验证无效', |
|||
required: '{label}必填', |
|||
'enum': '{label}超出范围', |
|||
timestamp: '{label}格式无效', |
|||
whitespace: '{label}不能为空', |
|||
typeError: '{label}类型无效', |
|||
date: { |
|||
format: '{label}日期{value}格式无效', |
|||
parse: '{label}日期无法解析,{value}无效', |
|||
invalid: '{label}日期{value}无效' |
|||
}, |
|||
length: { |
|||
minLength: '{label}长度不能少于{minLength}', |
|||
maxLength: '{label}长度不能超过{maxLength}', |
|||
range: '{label}必须介于{minLength}和{maxLength}之间' |
|||
}, |
|||
number: { |
|||
minimum: '{label}不能小于{minimum}', |
|||
maximum: '{label}不能大于{maximum}', |
|||
exclusiveMinimum: '{label}不能小于等于{minimum}', |
|||
exclusiveMaximum: '{label}不能大于等于{maximum}', |
|||
range: '{label}必须介于{minimum}and{maximum}之间' |
|||
}, |
|||
pattern: { |
|||
mismatch: '{label}格式不匹配' |
|||
} |
|||
}; |
|||
} |
|||
|
|||
|
|||
SchemaValidator.message = new Message(); |
|||
|
|||
export default SchemaValidator |
|||
@ -0,0 +1,88 @@ |
|||
{ |
|||
"id": "uni-forms", |
|||
"displayName": "uni-forms 表单", |
|||
"version": "1.4.10", |
|||
"description": "由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据", |
|||
"keywords": [ |
|||
"uni-ui", |
|||
"表单", |
|||
"校验", |
|||
"表单校验", |
|||
"表单验证" |
|||
], |
|||
"repository": "https://github.com/dcloudio/uni-ui", |
|||
"engines": { |
|||
"HBuilderX": "" |
|||
}, |
|||
"directories": { |
|||
"example": "../../temps/example_temps" |
|||
}, |
|||
"dcloudext": { |
|||
"sale": { |
|||
"regular": { |
|||
"price": "0.00" |
|||
}, |
|||
"sourcecode": { |
|||
"price": "0.00" |
|||
} |
|||
}, |
|||
"contact": { |
|||
"qq": "" |
|||
}, |
|||
"declaration": { |
|||
"ads": "无", |
|||
"data": "无", |
|||
"permissions": "无" |
|||
}, |
|||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", |
|||
"type": "component-vue" |
|||
}, |
|||
"uni_modules": { |
|||
"dependencies": [ |
|||
"uni-scss", |
|||
"uni-icons" |
|||
], |
|||
"encrypt": [], |
|||
"platforms": { |
|||
"cloud": { |
|||
"tcb": "y", |
|||
"aliyun": "y" |
|||
}, |
|||
"client": { |
|||
"App": { |
|||
"app-vue": "y", |
|||
"app-nvue": "y" |
|||
}, |
|||
"H5-mobile": { |
|||
"Safari": "y", |
|||
"Android Browser": "y", |
|||
"微信浏览器(Android)": "y", |
|||
"QQ浏览器(Android)": "y" |
|||
}, |
|||
"H5-pc": { |
|||
"Chrome": "y", |
|||
"IE": "y", |
|||
"Edge": "y", |
|||
"Firefox": "y", |
|||
"Safari": "y" |
|||
}, |
|||
"小程序": { |
|||
"微信": "y", |
|||
"阿里": "y", |
|||
"百度": "y", |
|||
"字节跳动": "y", |
|||
"QQ": "y", |
|||
"京东": "u" |
|||
}, |
|||
"快应用": { |
|||
"华为": "u", |
|||
"联盟": "u" |
|||
}, |
|||
"Vue": { |
|||
"vue2": "y", |
|||
"vue3": "y" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
|
|||
|
|||
## Forms 表单 |
|||
|
|||
> **组件名:uni-forms** |
|||
> 代码块: `uForms`、`uni-forms-item` |
|||
> 关联组件:`uni-forms-item`、`uni-easyinput`、`uni-data-checkbox`、`uni-group`。 |
|||
|
|||
|
|||
uni-app的内置组件已经有了 `<form>`组件,用于提交表单内容。 |
|||
|
|||
然而几乎每个表单都需要做表单验证,为了方便做表单验证,减少重复开发,`uni ui` 又基于 `<form>`组件封装了 `<uni-forms>`组件,内置了表单验证功能。 |
|||
|
|||
`<uni-forms>` 提供了 `rules`属性来描述校验规则、`<uni-forms-item>`子组件来包裹具体的表单项,以及给原生或三方组件提供了 `binddata()` 来设置表单值。 |
|||
|
|||
每个要校验的表单项,不管input还是checkbox,都必须放在`<uni-forms-item>`组件中,且一个`<uni-forms-item>`组件只能放置一个表单项。 |
|||
|
|||
`<uni-forms-item>`组件内部预留了显示error message的区域,默认是在表单项的底部。 |
|||
|
|||
另外,`<uni-forms>`组件下面的各个表单项,可以通过`<uni-group>`包裹为不同的分组。同一`<uni-group>`下的不同表单项目将聚拢在一起,同其他group保持垂直间距。`<uni-group>`仅影响视觉效果。 |
|||
|
|||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-forms) |
|||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |
|||
@ -0,0 +1,40 @@ |
|||
## 2.0.9(2024-01-12) |
|||
fix: 修复图标大小默认值错误的问题 |
|||
## 2.0.8(2023-12-14) |
|||
- 修复 项目未使用 ts 情况下,打包报错的bug |
|||
## 2.0.7(2023-12-14) |
|||
- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug |
|||
## 2.0.6(2023-12-11) |
|||
- 优化 兼容老版本icon类型,如 top ,bottom 等 |
|||
## 2.0.5(2023-12-11) |
|||
- 优化 兼容老版本icon类型,如 top ,bottom 等 |
|||
## 2.0.4(2023-12-06) |
|||
- 优化 uni-app x 下示例项目图标排序 |
|||
## 2.0.3(2023-12-06) |
|||
- 修复 nvue下引入组件报错的bug |
|||
## 2.0.2(2023-12-05) |
|||
-优化 size 属性支持单位 |
|||
## 2.0.1(2023-12-05) |
|||
- 新增 uni-app x 支持定义图标 |
|||
## 1.3.5(2022-01-24) |
|||
- 优化 size 属性可以传入不带单位的字符串数值 |
|||
## 1.3.4(2022-01-24) |
|||
- 优化 size 支持其他单位 |
|||
## 1.3.3(2022-01-17) |
|||
- 修复 nvue 有些图标不显示的bug,兼容老版本图标 |
|||
## 1.3.2(2021-12-01) |
|||
- 优化 示例可复制图标名称 |
|||
## 1.3.1(2021-11-23) |
|||
- 优化 兼容旧组件 type 值 |
|||
## 1.3.0(2021-11-19) |
|||
- 新增 更多图标 |
|||
- 优化 自定义图标使用方式 |
|||
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) |
|||
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons) |
|||
## 1.1.7(2021-11-08) |
|||
## 1.2.0(2021-07-30) |
|||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) |
|||
## 1.1.5(2021-05-12) |
|||
- 新增 组件示例地址 |
|||
## 1.1.4(2021-02-05) |
|||
- 调整为uni_modules目录规范 |
|||
@ -0,0 +1,91 @@ |
|||
<template> |
|||
<text class="uni-icons" :style="styleObj"> |
|||
<slot>{{unicode}}</slot> |
|||
</text> |
|||
</template> |
|||
|
|||
<script> |
|||
import { fontData, IconsDataItem } from './uniicons_file' |
|||
|
|||
/** |
|||
* Icons 图标 |
|||
* @description 用于展示 icon 图标 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=28 |
|||
* @property {Number} size 图标大小 |
|||
* @property {String} type 图标图案,参考示例 |
|||
* @property {String} color 图标颜色 |
|||
* @property {String} customPrefix 自定义图标 |
|||
* @event {Function} click 点击 Icon 触发事件 |
|||
*/ |
|||
export default { |
|||
name: "uni-icons", |
|||
props: { |
|||
type: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
color: { |
|||
type: String, |
|||
default: '#333333' |
|||
}, |
|||
size: { |
|||
type: Object, |
|||
default: 16 |
|||
}, |
|||
fontFamily: { |
|||
type: String, |
|||
default: '' |
|||
} |
|||
}, |
|||
data() { |
|||
return {}; |
|||
}, |
|||
computed: { |
|||
unicode() : string { |
|||
let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type }) |
|||
if (codes !== null) { |
|||
return codes.unicode |
|||
} |
|||
return '' |
|||
}, |
|||
iconSize() : string { |
|||
const size = this.size |
|||
if (typeof size == 'string') { |
|||
const reg = /^[0-9]*$/g |
|||
return reg.test(size as string) ? '' + size + 'px' : '' + size; |
|||
// return '' + this.size |
|||
} |
|||
return this.getFontSize(size as number) |
|||
}, |
|||
styleObj() : UTSJSONObject { |
|||
if (this.fontFamily !== '') { |
|||
return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily } |
|||
} |
|||
return { color: this.color, fontSize: this.iconSize } |
|||
} |
|||
}, |
|||
created() { }, |
|||
methods: { |
|||
/** |
|||
* 字体大小 |
|||
*/ |
|||
getFontSize(size : number) : string { |
|||
return size + 'px'; |
|||
}, |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
@font-face { |
|||
font-family: UniIconsFontFamily; |
|||
src: url('./uniicons.ttf'); |
|||
} |
|||
|
|||
.uni-icons { |
|||
font-family: UniIconsFontFamily; |
|||
font-size: 18px; |
|||
font-style: normal; |
|||
color: #333; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,110 @@ |
|||
<template> |
|||
<!-- #ifdef APP-NVUE --> |
|||
<text :style="styleObj" class="uni-icons" @click="_onClick">{{unicode}}</text> |
|||
<!-- #endif --> |
|||
<!-- #ifndef APP-NVUE --> |
|||
<text :style="styleObj" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"> |
|||
<slot></slot> |
|||
</text> |
|||
<!-- #endif --> |
|||
</template> |
|||
|
|||
<script> |
|||
import { fontData } from './uniicons_file_vue.js'; |
|||
|
|||
const getVal = (val) => { |
|||
const reg = /^[0-9]*$/g |
|||
return (typeof val === 'number' || reg.test(val)) ? val + 'px' : val; |
|||
} |
|||
|
|||
// #ifdef APP-NVUE |
|||
var domModule = weex.requireModule('dom'); |
|||
import iconUrl from './uniicons.ttf' |
|||
domModule.addRule('fontFace', { |
|||
'fontFamily': "uniicons", |
|||
'src': "url('" + iconUrl + "')" |
|||
}); |
|||
// #endif |
|||
|
|||
/** |
|||
* Icons 图标 |
|||
* @description 用于展示 icons 图标 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=28 |
|||
* @property {Number} size 图标大小 |
|||
* @property {String} type 图标图案,参考示例 |
|||
* @property {String} color 图标颜色 |
|||
* @property {String} customPrefix 自定义图标 |
|||
* @event {Function} click 点击 Icon 触发事件 |
|||
*/ |
|||
export default { |
|||
name: 'UniIcons', |
|||
emits: ['click'], |
|||
props: { |
|||
type: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
color: { |
|||
type: String, |
|||
default: '#333333' |
|||
}, |
|||
size: { |
|||
type: [Number, String], |
|||
default: 16 |
|||
}, |
|||
customPrefix: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
fontFamily: { |
|||
type: String, |
|||
default: '' |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
icons: fontData |
|||
} |
|||
}, |
|||
computed: { |
|||
unicode() { |
|||
let code = this.icons.find(v => v.font_class === this.type) |
|||
if (code) { |
|||
return code.unicode |
|||
} |
|||
return '' |
|||
}, |
|||
iconSize() { |
|||
return getVal(this.size) |
|||
}, |
|||
styleObj() { |
|||
if (this.fontFamily !== '') { |
|||
return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};` |
|||
} |
|||
return `color: ${this.color}; font-size: ${this.iconSize};` |
|||
} |
|||
}, |
|||
methods: { |
|||
_onClick() { |
|||
this.$emit('click') |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
/* #ifndef APP-NVUE */ |
|||
@import './uniicons.css'; |
|||
|
|||
@font-face { |
|||
font-family: uniicons; |
|||
src: url('./uniicons.ttf'); |
|||
} |
|||
|
|||
/* #endif */ |
|||
.uni-icons { |
|||
font-family: uniicons; |
|||
text-decoration: none; |
|||
text-align: center; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,664 @@ |
|||
|
|||
.uniui-cart-filled:before { |
|||
content: "\e6d0"; |
|||
} |
|||
|
|||
.uniui-gift-filled:before { |
|||
content: "\e6c4"; |
|||
} |
|||
|
|||
.uniui-color:before { |
|||
content: "\e6cf"; |
|||
} |
|||
|
|||
.uniui-wallet:before { |
|||
content: "\e6b1"; |
|||
} |
|||
|
|||
.uniui-settings-filled:before { |
|||
content: "\e6ce"; |
|||
} |
|||
|
|||
.uniui-auth-filled:before { |
|||
content: "\e6cc"; |
|||
} |
|||
|
|||
.uniui-shop-filled:before { |
|||
content: "\e6cd"; |
|||
} |
|||
|
|||
.uniui-staff-filled:before { |
|||
content: "\e6cb"; |
|||
} |
|||
|
|||
.uniui-vip-filled:before { |
|||
content: "\e6c6"; |
|||
} |
|||
|
|||
.uniui-plus-filled:before { |
|||
content: "\e6c7"; |
|||
} |
|||
|
|||
.uniui-folder-add-filled:before { |
|||
content: "\e6c8"; |
|||
} |
|||
|
|||
.uniui-color-filled:before { |
|||
content: "\e6c9"; |
|||
} |
|||
|
|||
.uniui-tune-filled:before { |
|||
content: "\e6ca"; |
|||
} |
|||
|
|||
.uniui-calendar-filled:before { |
|||
content: "\e6c0"; |
|||
} |
|||
|
|||
.uniui-notification-filled:before { |
|||
content: "\e6c1"; |
|||
} |
|||
|
|||
.uniui-wallet-filled:before { |
|||
content: "\e6c2"; |
|||
} |
|||
|
|||
.uniui-medal-filled:before { |
|||
content: "\e6c3"; |
|||
} |
|||
|
|||
.uniui-fire-filled:before { |
|||
content: "\e6c5"; |
|||
} |
|||
|
|||
.uniui-refreshempty:before { |
|||
content: "\e6bf"; |
|||
} |
|||
|
|||
.uniui-location-filled:before { |
|||
content: "\e6af"; |
|||
} |
|||
|
|||
.uniui-person-filled:before { |
|||
content: "\e69d"; |
|||
} |
|||
|
|||
.uniui-personadd-filled:before { |
|||
content: "\e698"; |
|||
} |
|||
|
|||
.uniui-arrowthinleft:before { |
|||
content: "\e6d2"; |
|||
} |
|||
|
|||
.uniui-arrowthinup:before { |
|||
content: "\e6d3"; |
|||
} |
|||
|
|||
.uniui-arrowthindown:before { |
|||
content: "\e6d4"; |
|||
} |
|||
|
|||
.uniui-back:before { |
|||
content: "\e6b9"; |
|||
} |
|||
|
|||
.uniui-forward:before { |
|||
content: "\e6ba"; |
|||
} |
|||
|
|||
.uniui-arrow-right:before { |
|||
content: "\e6bb"; |
|||
} |
|||
|
|||
.uniui-arrow-left:before { |
|||
content: "\e6bc"; |
|||
} |
|||
|
|||
.uniui-arrow-up:before { |
|||
content: "\e6bd"; |
|||
} |
|||
|
|||
.uniui-arrow-down:before { |
|||
content: "\e6be"; |
|||
} |
|||
|
|||
.uniui-arrowthinright:before { |
|||
content: "\e6d1"; |
|||
} |
|||
|
|||
.uniui-down:before { |
|||
content: "\e6b8"; |
|||
} |
|||
|
|||
.uniui-bottom:before { |
|||
content: "\e6b8"; |
|||
} |
|||
|
|||
.uniui-arrowright:before { |
|||
content: "\e6d5"; |
|||
} |
|||
|
|||
.uniui-right:before { |
|||
content: "\e6b5"; |
|||
} |
|||
|
|||
.uniui-up:before { |
|||
content: "\e6b6"; |
|||
} |
|||
|
|||
.uniui-top:before { |
|||
content: "\e6b6"; |
|||
} |
|||
|
|||
.uniui-left:before { |
|||
content: "\e6b7"; |
|||
} |
|||
|
|||
.uniui-arrowup:before { |
|||
content: "\e6d6"; |
|||
} |
|||
|
|||
.uniui-eye:before { |
|||
content: "\e651"; |
|||
} |
|||
|
|||
.uniui-eye-filled:before { |
|||
content: "\e66a"; |
|||
} |
|||
|
|||
.uniui-eye-slash:before { |
|||
content: "\e6b3"; |
|||
} |
|||
|
|||
.uniui-eye-slash-filled:before { |
|||
content: "\e6b4"; |
|||
} |
|||
|
|||
.uniui-info-filled:before { |
|||
content: "\e649"; |
|||
} |
|||
|
|||
.uniui-reload:before { |
|||
content: "\e6b2"; |
|||
} |
|||
|
|||
.uniui-micoff-filled:before { |
|||
content: "\e6b0"; |
|||
} |
|||
|
|||
.uniui-map-pin-ellipse:before { |
|||
content: "\e6ac"; |
|||
} |
|||
|
|||
.uniui-map-pin:before { |
|||
content: "\e6ad"; |
|||
} |
|||
|
|||
.uniui-location:before { |
|||
content: "\e6ae"; |
|||
} |
|||
|
|||
.uniui-starhalf:before { |
|||
content: "\e683"; |
|||
} |
|||
|
|||
.uniui-star:before { |
|||
content: "\e688"; |
|||
} |
|||
|
|||
.uniui-star-filled:before { |
|||
content: "\e68f"; |
|||
} |
|||
|
|||
.uniui-calendar:before { |
|||
content: "\e6a0"; |
|||
} |
|||
|
|||
.uniui-fire:before { |
|||
content: "\e6a1"; |
|||
} |
|||
|
|||
.uniui-medal:before { |
|||
content: "\e6a2"; |
|||
} |
|||
|
|||
.uniui-font:before { |
|||
content: "\e6a3"; |
|||
} |
|||
|
|||
.uniui-gift:before { |
|||
content: "\e6a4"; |
|||
} |
|||
|
|||
.uniui-link:before { |
|||
content: "\e6a5"; |
|||
} |
|||
|
|||
.uniui-notification:before { |
|||
content: "\e6a6"; |
|||
} |
|||
|
|||
.uniui-staff:before { |
|||
content: "\e6a7"; |
|||
} |
|||
|
|||
.uniui-vip:before { |
|||
content: "\e6a8"; |
|||
} |
|||
|
|||
.uniui-folder-add:before { |
|||
content: "\e6a9"; |
|||
} |
|||
|
|||
.uniui-tune:before { |
|||
content: "\e6aa"; |
|||
} |
|||
|
|||
.uniui-auth:before { |
|||
content: "\e6ab"; |
|||
} |
|||
|
|||
.uniui-person:before { |
|||
content: "\e699"; |
|||
} |
|||
|
|||
.uniui-email-filled:before { |
|||
content: "\e69a"; |
|||
} |
|||
|
|||
.uniui-phone-filled:before { |
|||
content: "\e69b"; |
|||
} |
|||
|
|||
.uniui-phone:before { |
|||
content: "\e69c"; |
|||
} |
|||
|
|||
.uniui-email:before { |
|||
content: "\e69e"; |
|||
} |
|||
|
|||
.uniui-personadd:before { |
|||
content: "\e69f"; |
|||
} |
|||
|
|||
.uniui-chatboxes-filled:before { |
|||
content: "\e692"; |
|||
} |
|||
|
|||
.uniui-contact:before { |
|||
content: "\e693"; |
|||
} |
|||
|
|||
.uniui-chatbubble-filled:before { |
|||
content: "\e694"; |
|||
} |
|||
|
|||
.uniui-contact-filled:before { |
|||
content: "\e695"; |
|||
} |
|||
|
|||
.uniui-chatboxes:before { |
|||
content: "\e696"; |
|||
} |
|||
|
|||
.uniui-chatbubble:before { |
|||
content: "\e697"; |
|||
} |
|||
|
|||
.uniui-upload-filled:before { |
|||
content: "\e68e"; |
|||
} |
|||
|
|||
.uniui-upload:before { |
|||
content: "\e690"; |
|||
} |
|||
|
|||
.uniui-weixin:before { |
|||
content: "\e691"; |
|||
} |
|||
|
|||
.uniui-compose:before { |
|||
content: "\e67f"; |
|||
} |
|||
|
|||
.uniui-qq:before { |
|||
content: "\e680"; |
|||
} |
|||
|
|||
.uniui-download-filled:before { |
|||
content: "\e681"; |
|||
} |
|||
|
|||
.uniui-pyq:before { |
|||
content: "\e682"; |
|||
} |
|||
|
|||
.uniui-sound:before { |
|||
content: "\e684"; |
|||
} |
|||
|
|||
.uniui-trash-filled:before { |
|||
content: "\e685"; |
|||
} |
|||
|
|||
.uniui-sound-filled:before { |
|||
content: "\e686"; |
|||
} |
|||
|
|||
.uniui-trash:before { |
|||
content: "\e687"; |
|||
} |
|||
|
|||
.uniui-videocam-filled:before { |
|||
content: "\e689"; |
|||
} |
|||
|
|||
.uniui-spinner-cycle:before { |
|||
content: "\e68a"; |
|||
} |
|||
|
|||
.uniui-weibo:before { |
|||
content: "\e68b"; |
|||
} |
|||
|
|||
.uniui-videocam:before { |
|||
content: "\e68c"; |
|||
} |
|||
|
|||
.uniui-download:before { |
|||
content: "\e68d"; |
|||
} |
|||
|
|||
.uniui-help:before { |
|||
content: "\e679"; |
|||
} |
|||
|
|||
.uniui-navigate-filled:before { |
|||
content: "\e67a"; |
|||
} |
|||
|
|||
.uniui-plusempty:before { |
|||
content: "\e67b"; |
|||
} |
|||
|
|||
.uniui-smallcircle:before { |
|||
content: "\e67c"; |
|||
} |
|||
|
|||
.uniui-minus-filled:before { |
|||
content: "\e67d"; |
|||
} |
|||
|
|||
.uniui-micoff:before { |
|||
content: "\e67e"; |
|||
} |
|||
|
|||
.uniui-closeempty:before { |
|||
content: "\e66c"; |
|||
} |
|||
|
|||
.uniui-clear:before { |
|||
content: "\e66d"; |
|||
} |
|||
|
|||
.uniui-navigate:before { |
|||
content: "\e66e"; |
|||
} |
|||
|
|||
.uniui-minus:before { |
|||
content: "\e66f"; |
|||
} |
|||
|
|||
.uniui-image:before { |
|||
content: "\e670"; |
|||
} |
|||
|
|||
.uniui-mic:before { |
|||
content: "\e671"; |
|||
} |
|||
|
|||
.uniui-paperplane:before { |
|||
content: "\e672"; |
|||
} |
|||
|
|||
.uniui-close:before { |
|||
content: "\e673"; |
|||
} |
|||
|
|||
.uniui-help-filled:before { |
|||
content: "\e674"; |
|||
} |
|||
|
|||
.uniui-paperplane-filled:before { |
|||
content: "\e675"; |
|||
} |
|||
|
|||
.uniui-plus:before { |
|||
content: "\e676"; |
|||
} |
|||
|
|||
.uniui-mic-filled:before { |
|||
content: "\e677"; |
|||
} |
|||
|
|||
.uniui-image-filled:before { |
|||
content: "\e678"; |
|||
} |
|||
|
|||
.uniui-locked-filled:before { |
|||
content: "\e668"; |
|||
} |
|||
|
|||
.uniui-info:before { |
|||
content: "\e669"; |
|||
} |
|||
|
|||
.uniui-locked:before { |
|||
content: "\e66b"; |
|||
} |
|||
|
|||
.uniui-camera-filled:before { |
|||
content: "\e658"; |
|||
} |
|||
|
|||
.uniui-chat-filled:before { |
|||
content: "\e659"; |
|||
} |
|||
|
|||
.uniui-camera:before { |
|||
content: "\e65a"; |
|||
} |
|||
|
|||
.uniui-circle:before { |
|||
content: "\e65b"; |
|||
} |
|||
|
|||
.uniui-checkmarkempty:before { |
|||
content: "\e65c"; |
|||
} |
|||
|
|||
.uniui-chat:before { |
|||
content: "\e65d"; |
|||
} |
|||
|
|||
.uniui-circle-filled:before { |
|||
content: "\e65e"; |
|||
} |
|||
|
|||
.uniui-flag:before { |
|||
content: "\e65f"; |
|||
} |
|||
|
|||
.uniui-flag-filled:before { |
|||
content: "\e660"; |
|||
} |
|||
|
|||
.uniui-gear-filled:before { |
|||
content: "\e661"; |
|||
} |
|||
|
|||
.uniui-home:before { |
|||
content: "\e662"; |
|||
} |
|||
|
|||
.uniui-home-filled:before { |
|||
content: "\e663"; |
|||
} |
|||
|
|||
.uniui-gear:before { |
|||
content: "\e664"; |
|||
} |
|||
|
|||
.uniui-smallcircle-filled:before { |
|||
content: "\e665"; |
|||
} |
|||
|
|||
.uniui-map-filled:before { |
|||
content: "\e666"; |
|||
} |
|||
|
|||
.uniui-map:before { |
|||
content: "\e667"; |
|||
} |
|||
|
|||
.uniui-refresh-filled:before { |
|||
content: "\e656"; |
|||
} |
|||
|
|||
.uniui-refresh:before { |
|||
content: "\e657"; |
|||
} |
|||
|
|||
.uniui-cloud-upload:before { |
|||
content: "\e645"; |
|||
} |
|||
|
|||
.uniui-cloud-download-filled:before { |
|||
content: "\e646"; |
|||
} |
|||
|
|||
.uniui-cloud-download:before { |
|||
content: "\e647"; |
|||
} |
|||
|
|||
.uniui-cloud-upload-filled:before { |
|||
content: "\e648"; |
|||
} |
|||
|
|||
.uniui-redo:before { |
|||
content: "\e64a"; |
|||
} |
|||
|
|||
.uniui-images-filled:before { |
|||
content: "\e64b"; |
|||
} |
|||
|
|||
.uniui-undo-filled:before { |
|||
content: "\e64c"; |
|||
} |
|||
|
|||
.uniui-more:before { |
|||
content: "\e64d"; |
|||
} |
|||
|
|||
.uniui-more-filled:before { |
|||
content: "\e64e"; |
|||
} |
|||
|
|||
.uniui-undo:before { |
|||
content: "\e64f"; |
|||
} |
|||
|
|||
.uniui-images:before { |
|||
content: "\e650"; |
|||
} |
|||
|
|||
.uniui-paperclip:before { |
|||
content: "\e652"; |
|||
} |
|||
|
|||
.uniui-settings:before { |
|||
content: "\e653"; |
|||
} |
|||
|
|||
.uniui-search:before { |
|||
content: "\e654"; |
|||
} |
|||
|
|||
.uniui-redo-filled:before { |
|||
content: "\e655"; |
|||
} |
|||
|
|||
.uniui-list:before { |
|||
content: "\e644"; |
|||
} |
|||
|
|||
.uniui-mail-open-filled:before { |
|||
content: "\e63a"; |
|||
} |
|||
|
|||
.uniui-hand-down-filled:before { |
|||
content: "\e63c"; |
|||
} |
|||
|
|||
.uniui-hand-down:before { |
|||
content: "\e63d"; |
|||
} |
|||
|
|||
.uniui-hand-up-filled:before { |
|||
content: "\e63e"; |
|||
} |
|||
|
|||
.uniui-hand-up:before { |
|||
content: "\e63f"; |
|||
} |
|||
|
|||
.uniui-heart-filled:before { |
|||
content: "\e641"; |
|||
} |
|||
|
|||
.uniui-mail-open:before { |
|||
content: "\e643"; |
|||
} |
|||
|
|||
.uniui-heart:before { |
|||
content: "\e639"; |
|||
} |
|||
|
|||
.uniui-loop:before { |
|||
content: "\e633"; |
|||
} |
|||
|
|||
.uniui-pulldown:before { |
|||
content: "\e632"; |
|||
} |
|||
|
|||
.uniui-scan:before { |
|||
content: "\e62a"; |
|||
} |
|||
|
|||
.uniui-bars:before { |
|||
content: "\e627"; |
|||
} |
|||
|
|||
.uniui-checkbox:before { |
|||
content: "\e62b"; |
|||
} |
|||
|
|||
.uniui-checkbox-filled:before { |
|||
content: "\e62c"; |
|||
} |
|||
|
|||
.uniui-shop:before { |
|||
content: "\e62f"; |
|||
} |
|||
|
|||
.uniui-headphones:before { |
|||
content: "\e630"; |
|||
} |
|||
|
|||
.uniui-cart:before { |
|||
content: "\e631"; |
|||
} |
|||
Binary file not shown.
@ -0,0 +1,664 @@ |
|||
|
|||
export type IconsData = { |
|||
id : string |
|||
name : string |
|||
font_family : string |
|||
css_prefix_text : string |
|||
description : string |
|||
glyphs : Array<IconsDataItem> |
|||
} |
|||
|
|||
export type IconsDataItem = { |
|||
font_class : string |
|||
unicode : string |
|||
} |
|||
|
|||
|
|||
export const fontData = [ |
|||
{ |
|||
"font_class": "arrow-down", |
|||
"unicode": "\ue6be" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-left", |
|||
"unicode": "\ue6bc" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-right", |
|||
"unicode": "\ue6bb" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-up", |
|||
"unicode": "\ue6bd" |
|||
}, |
|||
{ |
|||
"font_class": "auth", |
|||
"unicode": "\ue6ab" |
|||
}, |
|||
{ |
|||
"font_class": "auth-filled", |
|||
"unicode": "\ue6cc" |
|||
}, |
|||
{ |
|||
"font_class": "back", |
|||
"unicode": "\ue6b9" |
|||
}, |
|||
{ |
|||
"font_class": "bars", |
|||
"unicode": "\ue627" |
|||
}, |
|||
{ |
|||
"font_class": "calendar", |
|||
"unicode": "\ue6a0" |
|||
}, |
|||
{ |
|||
"font_class": "calendar-filled", |
|||
"unicode": "\ue6c0" |
|||
}, |
|||
{ |
|||
"font_class": "camera", |
|||
"unicode": "\ue65a" |
|||
}, |
|||
{ |
|||
"font_class": "camera-filled", |
|||
"unicode": "\ue658" |
|||
}, |
|||
{ |
|||
"font_class": "cart", |
|||
"unicode": "\ue631" |
|||
}, |
|||
{ |
|||
"font_class": "cart-filled", |
|||
"unicode": "\ue6d0" |
|||
}, |
|||
{ |
|||
"font_class": "chat", |
|||
"unicode": "\ue65d" |
|||
}, |
|||
{ |
|||
"font_class": "chat-filled", |
|||
"unicode": "\ue659" |
|||
}, |
|||
{ |
|||
"font_class": "chatboxes", |
|||
"unicode": "\ue696" |
|||
}, |
|||
{ |
|||
"font_class": "chatboxes-filled", |
|||
"unicode": "\ue692" |
|||
}, |
|||
{ |
|||
"font_class": "chatbubble", |
|||
"unicode": "\ue697" |
|||
}, |
|||
{ |
|||
"font_class": "chatbubble-filled", |
|||
"unicode": "\ue694" |
|||
}, |
|||
{ |
|||
"font_class": "checkbox", |
|||
"unicode": "\ue62b" |
|||
}, |
|||
{ |
|||
"font_class": "checkbox-filled", |
|||
"unicode": "\ue62c" |
|||
}, |
|||
{ |
|||
"font_class": "checkmarkempty", |
|||
"unicode": "\ue65c" |
|||
}, |
|||
{ |
|||
"font_class": "circle", |
|||
"unicode": "\ue65b" |
|||
}, |
|||
{ |
|||
"font_class": "circle-filled", |
|||
"unicode": "\ue65e" |
|||
}, |
|||
{ |
|||
"font_class": "clear", |
|||
"unicode": "\ue66d" |
|||
}, |
|||
{ |
|||
"font_class": "close", |
|||
"unicode": "\ue673" |
|||
}, |
|||
{ |
|||
"font_class": "closeempty", |
|||
"unicode": "\ue66c" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-download", |
|||
"unicode": "\ue647" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-download-filled", |
|||
"unicode": "\ue646" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-upload", |
|||
"unicode": "\ue645" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-upload-filled", |
|||
"unicode": "\ue648" |
|||
}, |
|||
{ |
|||
"font_class": "color", |
|||
"unicode": "\ue6cf" |
|||
}, |
|||
{ |
|||
"font_class": "color-filled", |
|||
"unicode": "\ue6c9" |
|||
}, |
|||
{ |
|||
"font_class": "compose", |
|||
"unicode": "\ue67f" |
|||
}, |
|||
{ |
|||
"font_class": "contact", |
|||
"unicode": "\ue693" |
|||
}, |
|||
{ |
|||
"font_class": "contact-filled", |
|||
"unicode": "\ue695" |
|||
}, |
|||
{ |
|||
"font_class": "down", |
|||
"unicode": "\ue6b8" |
|||
}, |
|||
{ |
|||
"font_class": "bottom", |
|||
"unicode": "\ue6b8" |
|||
}, |
|||
{ |
|||
"font_class": "download", |
|||
"unicode": "\ue68d" |
|||
}, |
|||
{ |
|||
"font_class": "download-filled", |
|||
"unicode": "\ue681" |
|||
}, |
|||
{ |
|||
"font_class": "email", |
|||
"unicode": "\ue69e" |
|||
}, |
|||
{ |
|||
"font_class": "email-filled", |
|||
"unicode": "\ue69a" |
|||
}, |
|||
{ |
|||
"font_class": "eye", |
|||
"unicode": "\ue651" |
|||
}, |
|||
{ |
|||
"font_class": "eye-filled", |
|||
"unicode": "\ue66a" |
|||
}, |
|||
{ |
|||
"font_class": "eye-slash", |
|||
"unicode": "\ue6b3" |
|||
}, |
|||
{ |
|||
"font_class": "eye-slash-filled", |
|||
"unicode": "\ue6b4" |
|||
}, |
|||
{ |
|||
"font_class": "fire", |
|||
"unicode": "\ue6a1" |
|||
}, |
|||
{ |
|||
"font_class": "fire-filled", |
|||
"unicode": "\ue6c5" |
|||
}, |
|||
{ |
|||
"font_class": "flag", |
|||
"unicode": "\ue65f" |
|||
}, |
|||
{ |
|||
"font_class": "flag-filled", |
|||
"unicode": "\ue660" |
|||
}, |
|||
{ |
|||
"font_class": "folder-add", |
|||
"unicode": "\ue6a9" |
|||
}, |
|||
{ |
|||
"font_class": "folder-add-filled", |
|||
"unicode": "\ue6c8" |
|||
}, |
|||
{ |
|||
"font_class": "font", |
|||
"unicode": "\ue6a3" |
|||
}, |
|||
{ |
|||
"font_class": "forward", |
|||
"unicode": "\ue6ba" |
|||
}, |
|||
{ |
|||
"font_class": "gear", |
|||
"unicode": "\ue664" |
|||
}, |
|||
{ |
|||
"font_class": "gear-filled", |
|||
"unicode": "\ue661" |
|||
}, |
|||
{ |
|||
"font_class": "gift", |
|||
"unicode": "\ue6a4" |
|||
}, |
|||
{ |
|||
"font_class": "gift-filled", |
|||
"unicode": "\ue6c4" |
|||
}, |
|||
{ |
|||
"font_class": "hand-down", |
|||
"unicode": "\ue63d" |
|||
}, |
|||
{ |
|||
"font_class": "hand-down-filled", |
|||
"unicode": "\ue63c" |
|||
}, |
|||
{ |
|||
"font_class": "hand-up", |
|||
"unicode": "\ue63f" |
|||
}, |
|||
{ |
|||
"font_class": "hand-up-filled", |
|||
"unicode": "\ue63e" |
|||
}, |
|||
{ |
|||
"font_class": "headphones", |
|||
"unicode": "\ue630" |
|||
}, |
|||
{ |
|||
"font_class": "heart", |
|||
"unicode": "\ue639" |
|||
}, |
|||
{ |
|||
"font_class": "heart-filled", |
|||
"unicode": "\ue641" |
|||
}, |
|||
{ |
|||
"font_class": "help", |
|||
"unicode": "\ue679" |
|||
}, |
|||
{ |
|||
"font_class": "help-filled", |
|||
"unicode": "\ue674" |
|||
}, |
|||
{ |
|||
"font_class": "home", |
|||
"unicode": "\ue662" |
|||
}, |
|||
{ |
|||
"font_class": "home-filled", |
|||
"unicode": "\ue663" |
|||
}, |
|||
{ |
|||
"font_class": "image", |
|||
"unicode": "\ue670" |
|||
}, |
|||
{ |
|||
"font_class": "image-filled", |
|||
"unicode": "\ue678" |
|||
}, |
|||
{ |
|||
"font_class": "images", |
|||
"unicode": "\ue650" |
|||
}, |
|||
{ |
|||
"font_class": "images-filled", |
|||
"unicode": "\ue64b" |
|||
}, |
|||
{ |
|||
"font_class": "info", |
|||
"unicode": "\ue669" |
|||
}, |
|||
{ |
|||
"font_class": "info-filled", |
|||
"unicode": "\ue649" |
|||
}, |
|||
{ |
|||
"font_class": "left", |
|||
"unicode": "\ue6b7" |
|||
}, |
|||
{ |
|||
"font_class": "link", |
|||
"unicode": "\ue6a5" |
|||
}, |
|||
{ |
|||
"font_class": "list", |
|||
"unicode": "\ue644" |
|||
}, |
|||
{ |
|||
"font_class": "location", |
|||
"unicode": "\ue6ae" |
|||
}, |
|||
{ |
|||
"font_class": "location-filled", |
|||
"unicode": "\ue6af" |
|||
}, |
|||
{ |
|||
"font_class": "locked", |
|||
"unicode": "\ue66b" |
|||
}, |
|||
{ |
|||
"font_class": "locked-filled", |
|||
"unicode": "\ue668" |
|||
}, |
|||
{ |
|||
"font_class": "loop", |
|||
"unicode": "\ue633" |
|||
}, |
|||
{ |
|||
"font_class": "mail-open", |
|||
"unicode": "\ue643" |
|||
}, |
|||
{ |
|||
"font_class": "mail-open-filled", |
|||
"unicode": "\ue63a" |
|||
}, |
|||
{ |
|||
"font_class": "map", |
|||
"unicode": "\ue667" |
|||
}, |
|||
{ |
|||
"font_class": "map-filled", |
|||
"unicode": "\ue666" |
|||
}, |
|||
{ |
|||
"font_class": "map-pin", |
|||
"unicode": "\ue6ad" |
|||
}, |
|||
{ |
|||
"font_class": "map-pin-ellipse", |
|||
"unicode": "\ue6ac" |
|||
}, |
|||
{ |
|||
"font_class": "medal", |
|||
"unicode": "\ue6a2" |
|||
}, |
|||
{ |
|||
"font_class": "medal-filled", |
|||
"unicode": "\ue6c3" |
|||
}, |
|||
{ |
|||
"font_class": "mic", |
|||
"unicode": "\ue671" |
|||
}, |
|||
{ |
|||
"font_class": "mic-filled", |
|||
"unicode": "\ue677" |
|||
}, |
|||
{ |
|||
"font_class": "micoff", |
|||
"unicode": "\ue67e" |
|||
}, |
|||
{ |
|||
"font_class": "micoff-filled", |
|||
"unicode": "\ue6b0" |
|||
}, |
|||
{ |
|||
"font_class": "minus", |
|||
"unicode": "\ue66f" |
|||
}, |
|||
{ |
|||
"font_class": "minus-filled", |
|||
"unicode": "\ue67d" |
|||
}, |
|||
{ |
|||
"font_class": "more", |
|||
"unicode": "\ue64d" |
|||
}, |
|||
{ |
|||
"font_class": "more-filled", |
|||
"unicode": "\ue64e" |
|||
}, |
|||
{ |
|||
"font_class": "navigate", |
|||
"unicode": "\ue66e" |
|||
}, |
|||
{ |
|||
"font_class": "navigate-filled", |
|||
"unicode": "\ue67a" |
|||
}, |
|||
{ |
|||
"font_class": "notification", |
|||
"unicode": "\ue6a6" |
|||
}, |
|||
{ |
|||
"font_class": "notification-filled", |
|||
"unicode": "\ue6c1" |
|||
}, |
|||
{ |
|||
"font_class": "paperclip", |
|||
"unicode": "\ue652" |
|||
}, |
|||
{ |
|||
"font_class": "paperplane", |
|||
"unicode": "\ue672" |
|||
}, |
|||
{ |
|||
"font_class": "paperplane-filled", |
|||
"unicode": "\ue675" |
|||
}, |
|||
{ |
|||
"font_class": "person", |
|||
"unicode": "\ue699" |
|||
}, |
|||
{ |
|||
"font_class": "person-filled", |
|||
"unicode": "\ue69d" |
|||
}, |
|||
{ |
|||
"font_class": "personadd", |
|||
"unicode": "\ue69f" |
|||
}, |
|||
{ |
|||
"font_class": "personadd-filled", |
|||
"unicode": "\ue698" |
|||
}, |
|||
{ |
|||
"font_class": "personadd-filled-copy", |
|||
"unicode": "\ue6d1" |
|||
}, |
|||
{ |
|||
"font_class": "phone", |
|||
"unicode": "\ue69c" |
|||
}, |
|||
{ |
|||
"font_class": "phone-filled", |
|||
"unicode": "\ue69b" |
|||
}, |
|||
{ |
|||
"font_class": "plus", |
|||
"unicode": "\ue676" |
|||
}, |
|||
{ |
|||
"font_class": "plus-filled", |
|||
"unicode": "\ue6c7" |
|||
}, |
|||
{ |
|||
"font_class": "plusempty", |
|||
"unicode": "\ue67b" |
|||
}, |
|||
{ |
|||
"font_class": "pulldown", |
|||
"unicode": "\ue632" |
|||
}, |
|||
{ |
|||
"font_class": "pyq", |
|||
"unicode": "\ue682" |
|||
}, |
|||
{ |
|||
"font_class": "qq", |
|||
"unicode": "\ue680" |
|||
}, |
|||
{ |
|||
"font_class": "redo", |
|||
"unicode": "\ue64a" |
|||
}, |
|||
{ |
|||
"font_class": "redo-filled", |
|||
"unicode": "\ue655" |
|||
}, |
|||
{ |
|||
"font_class": "refresh", |
|||
"unicode": "\ue657" |
|||
}, |
|||
{ |
|||
"font_class": "refresh-filled", |
|||
"unicode": "\ue656" |
|||
}, |
|||
{ |
|||
"font_class": "refreshempty", |
|||
"unicode": "\ue6bf" |
|||
}, |
|||
{ |
|||
"font_class": "reload", |
|||
"unicode": "\ue6b2" |
|||
}, |
|||
{ |
|||
"font_class": "right", |
|||
"unicode": "\ue6b5" |
|||
}, |
|||
{ |
|||
"font_class": "scan", |
|||
"unicode": "\ue62a" |
|||
}, |
|||
{ |
|||
"font_class": "search", |
|||
"unicode": "\ue654" |
|||
}, |
|||
{ |
|||
"font_class": "settings", |
|||
"unicode": "\ue653" |
|||
}, |
|||
{ |
|||
"font_class": "settings-filled", |
|||
"unicode": "\ue6ce" |
|||
}, |
|||
{ |
|||
"font_class": "shop", |
|||
"unicode": "\ue62f" |
|||
}, |
|||
{ |
|||
"font_class": "shop-filled", |
|||
"unicode": "\ue6cd" |
|||
}, |
|||
{ |
|||
"font_class": "smallcircle", |
|||
"unicode": "\ue67c" |
|||
}, |
|||
{ |
|||
"font_class": "smallcircle-filled", |
|||
"unicode": "\ue665" |
|||
}, |
|||
{ |
|||
"font_class": "sound", |
|||
"unicode": "\ue684" |
|||
}, |
|||
{ |
|||
"font_class": "sound-filled", |
|||
"unicode": "\ue686" |
|||
}, |
|||
{ |
|||
"font_class": "spinner-cycle", |
|||
"unicode": "\ue68a" |
|||
}, |
|||
{ |
|||
"font_class": "staff", |
|||
"unicode": "\ue6a7" |
|||
}, |
|||
{ |
|||
"font_class": "staff-filled", |
|||
"unicode": "\ue6cb" |
|||
}, |
|||
{ |
|||
"font_class": "star", |
|||
"unicode": "\ue688" |
|||
}, |
|||
{ |
|||
"font_class": "star-filled", |
|||
"unicode": "\ue68f" |
|||
}, |
|||
{ |
|||
"font_class": "starhalf", |
|||
"unicode": "\ue683" |
|||
}, |
|||
{ |
|||
"font_class": "trash", |
|||
"unicode": "\ue687" |
|||
}, |
|||
{ |
|||
"font_class": "trash-filled", |
|||
"unicode": "\ue685" |
|||
}, |
|||
{ |
|||
"font_class": "tune", |
|||
"unicode": "\ue6aa" |
|||
}, |
|||
{ |
|||
"font_class": "tune-filled", |
|||
"unicode": "\ue6ca" |
|||
}, |
|||
{ |
|||
"font_class": "undo", |
|||
"unicode": "\ue64f" |
|||
}, |
|||
{ |
|||
"font_class": "undo-filled", |
|||
"unicode": "\ue64c" |
|||
}, |
|||
{ |
|||
"font_class": "up", |
|||
"unicode": "\ue6b6" |
|||
}, |
|||
{ |
|||
"font_class": "top", |
|||
"unicode": "\ue6b6" |
|||
}, |
|||
{ |
|||
"font_class": "upload", |
|||
"unicode": "\ue690" |
|||
}, |
|||
{ |
|||
"font_class": "upload-filled", |
|||
"unicode": "\ue68e" |
|||
}, |
|||
{ |
|||
"font_class": "videocam", |
|||
"unicode": "\ue68c" |
|||
}, |
|||
{ |
|||
"font_class": "videocam-filled", |
|||
"unicode": "\ue689" |
|||
}, |
|||
{ |
|||
"font_class": "vip", |
|||
"unicode": "\ue6a8" |
|||
}, |
|||
{ |
|||
"font_class": "vip-filled", |
|||
"unicode": "\ue6c6" |
|||
}, |
|||
{ |
|||
"font_class": "wallet", |
|||
"unicode": "\ue6b1" |
|||
}, |
|||
{ |
|||
"font_class": "wallet-filled", |
|||
"unicode": "\ue6c2" |
|||
}, |
|||
{ |
|||
"font_class": "weibo", |
|||
"unicode": "\ue68b" |
|||
}, |
|||
{ |
|||
"font_class": "weixin", |
|||
"unicode": "\ue691" |
|||
} |
|||
] as IconsDataItem[] |
|||
|
|||
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
|
|||
@ -0,0 +1,649 @@ |
|||
|
|||
export const fontData = [ |
|||
{ |
|||
"font_class": "arrow-down", |
|||
"unicode": "\ue6be" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-left", |
|||
"unicode": "\ue6bc" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-right", |
|||
"unicode": "\ue6bb" |
|||
}, |
|||
{ |
|||
"font_class": "arrow-up", |
|||
"unicode": "\ue6bd" |
|||
}, |
|||
{ |
|||
"font_class": "auth", |
|||
"unicode": "\ue6ab" |
|||
}, |
|||
{ |
|||
"font_class": "auth-filled", |
|||
"unicode": "\ue6cc" |
|||
}, |
|||
{ |
|||
"font_class": "back", |
|||
"unicode": "\ue6b9" |
|||
}, |
|||
{ |
|||
"font_class": "bars", |
|||
"unicode": "\ue627" |
|||
}, |
|||
{ |
|||
"font_class": "calendar", |
|||
"unicode": "\ue6a0" |
|||
}, |
|||
{ |
|||
"font_class": "calendar-filled", |
|||
"unicode": "\ue6c0" |
|||
}, |
|||
{ |
|||
"font_class": "camera", |
|||
"unicode": "\ue65a" |
|||
}, |
|||
{ |
|||
"font_class": "camera-filled", |
|||
"unicode": "\ue658" |
|||
}, |
|||
{ |
|||
"font_class": "cart", |
|||
"unicode": "\ue631" |
|||
}, |
|||
{ |
|||
"font_class": "cart-filled", |
|||
"unicode": "\ue6d0" |
|||
}, |
|||
{ |
|||
"font_class": "chat", |
|||
"unicode": "\ue65d" |
|||
}, |
|||
{ |
|||
"font_class": "chat-filled", |
|||
"unicode": "\ue659" |
|||
}, |
|||
{ |
|||
"font_class": "chatboxes", |
|||
"unicode": "\ue696" |
|||
}, |
|||
{ |
|||
"font_class": "chatboxes-filled", |
|||
"unicode": "\ue692" |
|||
}, |
|||
{ |
|||
"font_class": "chatbubble", |
|||
"unicode": "\ue697" |
|||
}, |
|||
{ |
|||
"font_class": "chatbubble-filled", |
|||
"unicode": "\ue694" |
|||
}, |
|||
{ |
|||
"font_class": "checkbox", |
|||
"unicode": "\ue62b" |
|||
}, |
|||
{ |
|||
"font_class": "checkbox-filled", |
|||
"unicode": "\ue62c" |
|||
}, |
|||
{ |
|||
"font_class": "checkmarkempty", |
|||
"unicode": "\ue65c" |
|||
}, |
|||
{ |
|||
"font_class": "circle", |
|||
"unicode": "\ue65b" |
|||
}, |
|||
{ |
|||
"font_class": "circle-filled", |
|||
"unicode": "\ue65e" |
|||
}, |
|||
{ |
|||
"font_class": "clear", |
|||
"unicode": "\ue66d" |
|||
}, |
|||
{ |
|||
"font_class": "close", |
|||
"unicode": "\ue673" |
|||
}, |
|||
{ |
|||
"font_class": "closeempty", |
|||
"unicode": "\ue66c" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-download", |
|||
"unicode": "\ue647" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-download-filled", |
|||
"unicode": "\ue646" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-upload", |
|||
"unicode": "\ue645" |
|||
}, |
|||
{ |
|||
"font_class": "cloud-upload-filled", |
|||
"unicode": "\ue648" |
|||
}, |
|||
{ |
|||
"font_class": "color", |
|||
"unicode": "\ue6cf" |
|||
}, |
|||
{ |
|||
"font_class": "color-filled", |
|||
"unicode": "\ue6c9" |
|||
}, |
|||
{ |
|||
"font_class": "compose", |
|||
"unicode": "\ue67f" |
|||
}, |
|||
{ |
|||
"font_class": "contact", |
|||
"unicode": "\ue693" |
|||
}, |
|||
{ |
|||
"font_class": "contact-filled", |
|||
"unicode": "\ue695" |
|||
}, |
|||
{ |
|||
"font_class": "down", |
|||
"unicode": "\ue6b8" |
|||
}, |
|||
{ |
|||
"font_class": "bottom", |
|||
"unicode": "\ue6b8" |
|||
}, |
|||
{ |
|||
"font_class": "download", |
|||
"unicode": "\ue68d" |
|||
}, |
|||
{ |
|||
"font_class": "download-filled", |
|||
"unicode": "\ue681" |
|||
}, |
|||
{ |
|||
"font_class": "email", |
|||
"unicode": "\ue69e" |
|||
}, |
|||
{ |
|||
"font_class": "email-filled", |
|||
"unicode": "\ue69a" |
|||
}, |
|||
{ |
|||
"font_class": "eye", |
|||
"unicode": "\ue651" |
|||
}, |
|||
{ |
|||
"font_class": "eye-filled", |
|||
"unicode": "\ue66a" |
|||
}, |
|||
{ |
|||
"font_class": "eye-slash", |
|||
"unicode": "\ue6b3" |
|||
}, |
|||
{ |
|||
"font_class": "eye-slash-filled", |
|||
"unicode": "\ue6b4" |
|||
}, |
|||
{ |
|||
"font_class": "fire", |
|||
"unicode": "\ue6a1" |
|||
}, |
|||
{ |
|||
"font_class": "fire-filled", |
|||
"unicode": "\ue6c5" |
|||
}, |
|||
{ |
|||
"font_class": "flag", |
|||
"unicode": "\ue65f" |
|||
}, |
|||
{ |
|||
"font_class": "flag-filled", |
|||
"unicode": "\ue660" |
|||
}, |
|||
{ |
|||
"font_class": "folder-add", |
|||
"unicode": "\ue6a9" |
|||
}, |
|||
{ |
|||
"font_class": "folder-add-filled", |
|||
"unicode": "\ue6c8" |
|||
}, |
|||
{ |
|||
"font_class": "font", |
|||
"unicode": "\ue6a3" |
|||
}, |
|||
{ |
|||
"font_class": "forward", |
|||
"unicode": "\ue6ba" |
|||
}, |
|||
{ |
|||
"font_class": "gear", |
|||
"unicode": "\ue664" |
|||
}, |
|||
{ |
|||
"font_class": "gear-filled", |
|||
"unicode": "\ue661" |
|||
}, |
|||
{ |
|||
"font_class": "gift", |
|||
"unicode": "\ue6a4" |
|||
}, |
|||
{ |
|||
"font_class": "gift-filled", |
|||
"unicode": "\ue6c4" |
|||
}, |
|||
{ |
|||
"font_class": "hand-down", |
|||
"unicode": "\ue63d" |
|||
}, |
|||
{ |
|||
"font_class": "hand-down-filled", |
|||
"unicode": "\ue63c" |
|||
}, |
|||
{ |
|||
"font_class": "hand-up", |
|||
"unicode": "\ue63f" |
|||
}, |
|||
{ |
|||
"font_class": "hand-up-filled", |
|||
"unicode": "\ue63e" |
|||
}, |
|||
{ |
|||
"font_class": "headphones", |
|||
"unicode": "\ue630" |
|||
}, |
|||
{ |
|||
"font_class": "heart", |
|||
"unicode": "\ue639" |
|||
}, |
|||
{ |
|||
"font_class": "heart-filled", |
|||
"unicode": "\ue641" |
|||
}, |
|||
{ |
|||
"font_class": "help", |
|||
"unicode": "\ue679" |
|||
}, |
|||
{ |
|||
"font_class": "help-filled", |
|||
"unicode": "\ue674" |
|||
}, |
|||
{ |
|||
"font_class": "home", |
|||
"unicode": "\ue662" |
|||
}, |
|||
{ |
|||
"font_class": "home-filled", |
|||
"unicode": "\ue663" |
|||
}, |
|||
{ |
|||
"font_class": "image", |
|||
"unicode": "\ue670" |
|||
}, |
|||
{ |
|||
"font_class": "image-filled", |
|||
"unicode": "\ue678" |
|||
}, |
|||
{ |
|||
"font_class": "images", |
|||
"unicode": "\ue650" |
|||
}, |
|||
{ |
|||
"font_class": "images-filled", |
|||
"unicode": "\ue64b" |
|||
}, |
|||
{ |
|||
"font_class": "info", |
|||
"unicode": "\ue669" |
|||
}, |
|||
{ |
|||
"font_class": "info-filled", |
|||
"unicode": "\ue649" |
|||
}, |
|||
{ |
|||
"font_class": "left", |
|||
"unicode": "\ue6b7" |
|||
}, |
|||
{ |
|||
"font_class": "link", |
|||
"unicode": "\ue6a5" |
|||
}, |
|||
{ |
|||
"font_class": "list", |
|||
"unicode": "\ue644" |
|||
}, |
|||
{ |
|||
"font_class": "location", |
|||
"unicode": "\ue6ae" |
|||
}, |
|||
{ |
|||
"font_class": "location-filled", |
|||
"unicode": "\ue6af" |
|||
}, |
|||
{ |
|||
"font_class": "locked", |
|||
"unicode": "\ue66b" |
|||
}, |
|||
{ |
|||
"font_class": "locked-filled", |
|||
"unicode": "\ue668" |
|||
}, |
|||
{ |
|||
"font_class": "loop", |
|||
"unicode": "\ue633" |
|||
}, |
|||
{ |
|||
"font_class": "mail-open", |
|||
"unicode": "\ue643" |
|||
}, |
|||
{ |
|||
"font_class": "mail-open-filled", |
|||
"unicode": "\ue63a" |
|||
}, |
|||
{ |
|||
"font_class": "map", |
|||
"unicode": "\ue667" |
|||
}, |
|||
{ |
|||
"font_class": "map-filled", |
|||
"unicode": "\ue666" |
|||
}, |
|||
{ |
|||
"font_class": "map-pin", |
|||
"unicode": "\ue6ad" |
|||
}, |
|||
{ |
|||
"font_class": "map-pin-ellipse", |
|||
"unicode": "\ue6ac" |
|||
}, |
|||
{ |
|||
"font_class": "medal", |
|||
"unicode": "\ue6a2" |
|||
}, |
|||
{ |
|||
"font_class": "medal-filled", |
|||
"unicode": "\ue6c3" |
|||
}, |
|||
{ |
|||
"font_class": "mic", |
|||
"unicode": "\ue671" |
|||
}, |
|||
{ |
|||
"font_class": "mic-filled", |
|||
"unicode": "\ue677" |
|||
}, |
|||
{ |
|||
"font_class": "micoff", |
|||
"unicode": "\ue67e" |
|||
}, |
|||
{ |
|||
"font_class": "micoff-filled", |
|||
"unicode": "\ue6b0" |
|||
}, |
|||
{ |
|||
"font_class": "minus", |
|||
"unicode": "\ue66f" |
|||
}, |
|||
{ |
|||
"font_class": "minus-filled", |
|||
"unicode": "\ue67d" |
|||
}, |
|||
{ |
|||
"font_class": "more", |
|||
"unicode": "\ue64d" |
|||
}, |
|||
{ |
|||
"font_class": "more-filled", |
|||
"unicode": "\ue64e" |
|||
}, |
|||
{ |
|||
"font_class": "navigate", |
|||
"unicode": "\ue66e" |
|||
}, |
|||
{ |
|||
"font_class": "navigate-filled", |
|||
"unicode": "\ue67a" |
|||
}, |
|||
{ |
|||
"font_class": "notification", |
|||
"unicode": "\ue6a6" |
|||
}, |
|||
{ |
|||
"font_class": "notification-filled", |
|||
"unicode": "\ue6c1" |
|||
}, |
|||
{ |
|||
"font_class": "paperclip", |
|||
"unicode": "\ue652" |
|||
}, |
|||
{ |
|||
"font_class": "paperplane", |
|||
"unicode": "\ue672" |
|||
}, |
|||
{ |
|||
"font_class": "paperplane-filled", |
|||
"unicode": "\ue675" |
|||
}, |
|||
{ |
|||
"font_class": "person", |
|||
"unicode": "\ue699" |
|||
}, |
|||
{ |
|||
"font_class": "person-filled", |
|||
"unicode": "\ue69d" |
|||
}, |
|||
{ |
|||
"font_class": "personadd", |
|||
"unicode": "\ue69f" |
|||
}, |
|||
{ |
|||
"font_class": "personadd-filled", |
|||
"unicode": "\ue698" |
|||
}, |
|||
{ |
|||
"font_class": "personadd-filled-copy", |
|||
"unicode": "\ue6d1" |
|||
}, |
|||
{ |
|||
"font_class": "phone", |
|||
"unicode": "\ue69c" |
|||
}, |
|||
{ |
|||
"font_class": "phone-filled", |
|||
"unicode": "\ue69b" |
|||
}, |
|||
{ |
|||
"font_class": "plus", |
|||
"unicode": "\ue676" |
|||
}, |
|||
{ |
|||
"font_class": "plus-filled", |
|||
"unicode": "\ue6c7" |
|||
}, |
|||
{ |
|||
"font_class": "plusempty", |
|||
"unicode": "\ue67b" |
|||
}, |
|||
{ |
|||
"font_class": "pulldown", |
|||
"unicode": "\ue632" |
|||
}, |
|||
{ |
|||
"font_class": "pyq", |
|||
"unicode": "\ue682" |
|||
}, |
|||
{ |
|||
"font_class": "qq", |
|||
"unicode": "\ue680" |
|||
}, |
|||
{ |
|||
"font_class": "redo", |
|||
"unicode": "\ue64a" |
|||
}, |
|||
{ |
|||
"font_class": "redo-filled", |
|||
"unicode": "\ue655" |
|||
}, |
|||
{ |
|||
"font_class": "refresh", |
|||
"unicode": "\ue657" |
|||
}, |
|||
{ |
|||
"font_class": "refresh-filled", |
|||
"unicode": "\ue656" |
|||
}, |
|||
{ |
|||
"font_class": "refreshempty", |
|||
"unicode": "\ue6bf" |
|||
}, |
|||
{ |
|||
"font_class": "reload", |
|||
"unicode": "\ue6b2" |
|||
}, |
|||
{ |
|||
"font_class": "right", |
|||
"unicode": "\ue6b5" |
|||
}, |
|||
{ |
|||
"font_class": "scan", |
|||
"unicode": "\ue62a" |
|||
}, |
|||
{ |
|||
"font_class": "search", |
|||
"unicode": "\ue654" |
|||
}, |
|||
{ |
|||
"font_class": "settings", |
|||
"unicode": "\ue653" |
|||
}, |
|||
{ |
|||
"font_class": "settings-filled", |
|||
"unicode": "\ue6ce" |
|||
}, |
|||
{ |
|||
"font_class": "shop", |
|||
"unicode": "\ue62f" |
|||
}, |
|||
{ |
|||
"font_class": "shop-filled", |
|||
"unicode": "\ue6cd" |
|||
}, |
|||
{ |
|||
"font_class": "smallcircle", |
|||
"unicode": "\ue67c" |
|||
}, |
|||
{ |
|||
"font_class": "smallcircle-filled", |
|||
"unicode": "\ue665" |
|||
}, |
|||
{ |
|||
"font_class": "sound", |
|||
"unicode": "\ue684" |
|||
}, |
|||
{ |
|||
"font_class": "sound-filled", |
|||
"unicode": "\ue686" |
|||
}, |
|||
{ |
|||
"font_class": "spinner-cycle", |
|||
"unicode": "\ue68a" |
|||
}, |
|||
{ |
|||
"font_class": "staff", |
|||
"unicode": "\ue6a7" |
|||
}, |
|||
{ |
|||
"font_class": "staff-filled", |
|||
"unicode": "\ue6cb" |
|||
}, |
|||
{ |
|||
"font_class": "star", |
|||
"unicode": "\ue688" |
|||
}, |
|||
{ |
|||
"font_class": "star-filled", |
|||
"unicode": "\ue68f" |
|||
}, |
|||
{ |
|||
"font_class": "starhalf", |
|||
"unicode": "\ue683" |
|||
}, |
|||
{ |
|||
"font_class": "trash", |
|||
"unicode": "\ue687" |
|||
}, |
|||
{ |
|||
"font_class": "trash-filled", |
|||
"unicode": "\ue685" |
|||
}, |
|||
{ |
|||
"font_class": "tune", |
|||
"unicode": "\ue6aa" |
|||
}, |
|||
{ |
|||
"font_class": "tune-filled", |
|||
"unicode": "\ue6ca" |
|||
}, |
|||
{ |
|||
"font_class": "undo", |
|||
"unicode": "\ue64f" |
|||
}, |
|||
{ |
|||
"font_class": "undo-filled", |
|||
"unicode": "\ue64c" |
|||
}, |
|||
{ |
|||
"font_class": "up", |
|||
"unicode": "\ue6b6" |
|||
}, |
|||
{ |
|||
"font_class": "top", |
|||
"unicode": "\ue6b6" |
|||
}, |
|||
{ |
|||
"font_class": "upload", |
|||
"unicode": "\ue690" |
|||
}, |
|||
{ |
|||
"font_class": "upload-filled", |
|||
"unicode": "\ue68e" |
|||
}, |
|||
{ |
|||
"font_class": "videocam", |
|||
"unicode": "\ue68c" |
|||
}, |
|||
{ |
|||
"font_class": "videocam-filled", |
|||
"unicode": "\ue689" |
|||
}, |
|||
{ |
|||
"font_class": "vip", |
|||
"unicode": "\ue6a8" |
|||
}, |
|||
{ |
|||
"font_class": "vip-filled", |
|||
"unicode": "\ue6c6" |
|||
}, |
|||
{ |
|||
"font_class": "wallet", |
|||
"unicode": "\ue6b1" |
|||
}, |
|||
{ |
|||
"font_class": "wallet-filled", |
|||
"unicode": "\ue6c2" |
|||
}, |
|||
{ |
|||
"font_class": "weibo", |
|||
"unicode": "\ue68b" |
|||
}, |
|||
{ |
|||
"font_class": "weixin", |
|||
"unicode": "\ue691" |
|||
} |
|||
] |
|||
|
|||
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
|
|||
@ -0,0 +1,88 @@ |
|||
{ |
|||
"id": "uni-icons", |
|||
"displayName": "uni-icons 图标", |
|||
"version": "2.0.9", |
|||
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。", |
|||
"keywords": [ |
|||
"uni-ui", |
|||
"uniui", |
|||
"icon", |
|||
"图标" |
|||
], |
|||
"repository": "https://github.com/dcloudio/uni-ui", |
|||
"engines": { |
|||
"HBuilderX": "^3.2.14" |
|||
}, |
|||
"directories": { |
|||
"example": "../../temps/example_temps" |
|||
}, |
|||
"dcloudext": { |
|||
"sale": { |
|||
"regular": { |
|||
"price": "0.00" |
|||
}, |
|||
"sourcecode": { |
|||
"price": "0.00" |
|||
} |
|||
}, |
|||
"contact": { |
|||
"qq": "" |
|||
}, |
|||
"declaration": { |
|||
"ads": "无", |
|||
"data": "无", |
|||
"permissions": "无" |
|||
}, |
|||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", |
|||
"type": "component-vue" |
|||
}, |
|||
"uni_modules": { |
|||
"dependencies": ["uni-scss"], |
|||
"encrypt": [], |
|||
"platforms": { |
|||
"cloud": { |
|||
"tcb": "y", |
|||
"aliyun": "y" |
|||
}, |
|||
"client": { |
|||
"App": { |
|||
"app-vue": "y", |
|||
"app-nvue": "y", |
|||
"app-uvue": "y" |
|||
}, |
|||
"H5-mobile": { |
|||
"Safari": "y", |
|||
"Android Browser": "y", |
|||
"微信浏览器(Android)": "y", |
|||
"QQ浏览器(Android)": "y" |
|||
}, |
|||
"H5-pc": { |
|||
"Chrome": "y", |
|||
"IE": "y", |
|||
"Edge": "y", |
|||
"Firefox": "y", |
|||
"Safari": "y" |
|||
}, |
|||
"小程序": { |
|||
"微信": "y", |
|||
"阿里": "y", |
|||
"百度": "y", |
|||
"字节跳动": "y", |
|||
"QQ": "y", |
|||
"钉钉": "y", |
|||
"快手": "y", |
|||
"飞书": "y", |
|||
"京东": "y" |
|||
}, |
|||
"快应用": { |
|||
"华为": "y", |
|||
"联盟": "y" |
|||
}, |
|||
"Vue": { |
|||
"vue2": "y", |
|||
"vue3": "y" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
## Icons 图标 |
|||
> **组件名:uni-icons** |
|||
> 代码块: `uIcons` |
|||
|
|||
用于展示 icons 图标 。 |
|||
|
|||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons) |
|||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |
|||
Loading…
Reference in new issue