Commit cae3f55a authored by wlxuqu's avatar wlxuqu

1. 【新增】modal和popup的中部弹出模式新增negative-top参数,可以将弹出区域往上移,避免与弹出的键盘重合。

2. 【新增】countdown组件新增hide-zero-day参数,当"天"为0时自动隐藏该字段
3. 【新增】input组件添加cursor-spacing参数
4. 【优化】image组件允许事件冒泡到外层
5. 【优化】优化cell组件的label数字不会换行的问题
6. 【优化】优化navbar的title为英文时,可能会发生部分字母被竖向截断的问题
7. 【优化】优化picker和select滑动顶部区域,可能会产生报错的问题
8. 【优化】row组件允许flex换行
9. 【优化】优化upload组件的on-list-change事件逻辑
10. 【优化】优化avatar-cropper组件没有选择图片也能点击确定进行裁剪的问题
11. 【修复】修正image组件的border-radius无法接受带单位的值的问题
12. 【新增rate评分组件新增v-model双向绑定的形式
13. 【新增numberBox步进器组件新增step支持小数加减,另外新增long-press和press-time用于长按连续加减
parent 6f963099
......@@ -2,7 +2,7 @@
"name" : "uView",
"appid" : "__UNI__60F4B81",
"description" : "多平台快速开发的UI框架",
"versionName" : "1.4.4",
"versionName" : "1.4.5",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
......
......@@ -6,16 +6,16 @@
// "current": 0, //当前激活的模式(list 的索引项)
// "list": [{
// "name": "test", //模式名称
// "path": "pages/componentsC/test/index", //启动页面,必选
// "path": "pages/componentsB/checkbox/index", //启动页面,必选
// "query": "id=1&name=2" //启动参数,在页面的onLoad函数里面得到
// }]
// }]
// },
"pages": [
// 演示-组件
// 演示-组件
{
"path": "pages/example/components",
"style": {
"navigationBarTitleText": "组件"
"navigationBarTitleText": "组件"
}
},
// avatarCropper-头像裁剪
......@@ -143,7 +143,7 @@
"navigationBarTitleText": "badge-徽标数"
}
},
// button按钮
// button按钮
{
"path": "button/index",
"style": {
......@@ -583,7 +583,7 @@
"style": {
"navigationBarTitleText": "icon-字体图标"
}
}, // avatar-用户头像展示
}, // avatar-用户头像展示
{
"path": "avatar/index",
"style": {
......
......@@ -60,7 +60,7 @@
<u-verification-code seconds="60" ref="uCode" @change="codeChange"></u-verification-code>
<view class="u-config-wrap">
<view class="u-config-title u-border-bottom">
参数配置
参数配置
</view>
<view class="u-config-item">
<view class="u-item-title">label对齐方式</view>
......@@ -119,15 +119,15 @@ export default {
],
rules: {
name: [
{
required: true,
message: '请输入姓名',
{
required: true,
message: '请输入姓名',
trigger: 'blur' ,
},
{
min: 3,
max: 5,
message: '姓名长度在3到5个字符',
},
{
min: 3,
max: 5,
message: '姓名长度在3到5个字符',
trigger: ['change','blur'],
},
{
......@@ -160,19 +160,19 @@ export default {
],
sex: [
{
required: true,
required: true,
message: '请选择性别',
trigger: 'change'
},
},
],
intro: [
{
required: true,
required: true,
message: '请填写简介'
},
},
{
min: 5,
message: '简介不能少于5个字',
min: 5,
message: '简介不能少于5个字',
trigger: 'change' ,
},
// 正则校验示例,此处用正则校验是否中文,此处仅为示例,因为uView有this.$u.test.chinese可以判断是否中文
......@@ -184,7 +184,7 @@ export default {
],
likeFruit: [
{
required: true,
required: true,
message: '请选择您喜欢的水果',
trigger: 'change',
type: 'array',
......@@ -192,28 +192,28 @@ export default {
],
payType: [
{
required: true,
required: true,
message: '请选择任意一种支付方式',
trigger: 'change',
}
],
region: [
{
required: true,
required: true,
message: '请选择地区',
trigger: 'change',
}
],
goodsType: [
{
required: true,
required: true,
message: '请选择商品类型',
trigger: 'change',
}
],
phone: [
{
required: true,
required: true,
message: '请输入手机号',
trigger: ['change','blur'],
},
......@@ -229,7 +229,7 @@ export default {
],
code: [
{
required: true,
required: true,
message: '请输入验证码',
trigger: ['change','blur'],
},
......@@ -241,7 +241,7 @@ export default {
],
password: [
{
required: true,
required: true,
message: '请输入密码',
trigger: ['change','blur'],
},
......@@ -254,7 +254,7 @@ export default {
],
rePassword: [
{
required: true,
required: true,
message: '请重新输入密码',
trigger: ['change','blur'],
},
......@@ -337,7 +337,7 @@ export default {
};
},
onLoad() {
},
computed: {
borderCurrent() {
......@@ -445,7 +445,7 @@ export default {
display: flex;
align-items: center;
margin: 40rpx 0;
.agreement-text {
padding-left: 8rpx;
color: $u-tips-color;
......
......@@ -91,7 +91,7 @@
activeColor: '#2979ff',
size: 34,
wrap: false,
width: ''
width: 'auto'
}
},
computed: {
......
......@@ -3,7 +3,7 @@
<view class="u-demo-wrap">
<view class="u-demo-title">演示效果</view>
<view class="u-demo-area u-flex u-row-center">
<u-image :shape="shape" ref="uImage" :width="width" :height="height" :src="src" mode="aspectFill">
<u-image border-radius="100%" :shape="shape" ref="uImage" :width="width" :height="height" :src="src" mode="aspectFill">
<u-loading size="44" mode="flower" slot="loading" v-if="loadingSlot"></u-loading>
<view v-if="errorSlot" slot="error" style="font-size: 24rpx;">加载失败</view>
</u-image>
......
......@@ -85,7 +85,7 @@
activeColor: '#2979ff',
size: 34,
wrap: false,
width: ''
width: 'auto'
}
},
methods: {
......
......@@ -3,9 +3,9 @@
<view class="u-demo-wrap">
<view class="u-demo-title">演示效果</view>
<view class="u-demo-area">
<u-rate :count="count" :current="current" @change="change"
:active-color="activeColor" :inaction-color="inactiveColor"
:active-icon="activeIcon" :inactive-icon="inactiveIcon"
<u-rate v-model="value" :count="count" @change="change"
:active-color="activeColor" :inaction-color="inactiveColor"
:active-icon="activeIcon" :inactive-icon="inactiveIcon"
:disabled="disabled"></u-rate>
</view>
</view>
......@@ -45,13 +45,20 @@
export default {
data() {
return {
current: 1,
// 1.4.5后推荐使用v-model双向绑定,弃用current
// current: 1,
activeColor: '#FA3534',
inactiveColor: '#b2b2b2',
disabled: false,
count: 5,
customIcon: false,
plain: false,
value: 0
}
},
watch: {
value(n) {
// console.log(n);
}
},
computed: {
......
<template>
<view class="container">
<view class="search-box">
<u-search @focus="getKeys" @blur="hideKey" bg-color='#ffffff' border-color='rgba(242, 242, 242, 1)' placeholder="日照香炉生紫烟" :clearabled="true" v-model="keyword"></u-search>
</view>
<view class="search-word">
<view class="search-hot" v-if="keys.length!==0">
热门搜索
</view>
<view class="search-key" v-if="keys.length!==0">
<view class="key-font" :key="" v-for="item in keys">
{{item.brand_name}}
</view>
</view>
</view>
<view class="search-end" v-if="keys.length==0">
<view class="">
全部
</view>
<view class="">
销量
</view>
<view class="" @click="showChoice = true">
筛选
</view>
</view>
<view class="guess-section">
<view v-for="(item, index) in mainData" :key="index" class="guess-item" @click="navToDetailPage(item)">
<view class="image-wrapper">
<image :src="item.goods_img"></image>
<text class="goods-tip" v-if="item.is_new==1">新品</text>
</view>
<view class="goods-info">
<text class="title clamp">{{item.goods_name}}</text>
<p><text class="price">{{item.promote_price}}</text><text class="price sell">¥{{item.market_price}}</text></p>
<view class="">
<u-rate count="count" gutter="6" size=3 inactive-icon="star-fill" :plain="true" active-color="#FBD14F" inactive-color="RGBA(251, 209, 79, 0.3)" current="2"></u-rate>
<text style="font-size:16upx;margin-left: 8upx; color: #363636;">4.5</text>
</view>
</view>
</view>
</view>
<u-popup v-model="showChoice" mode="right" width="404rpx" @close="closePopup">
<view class="choice">筛选</view>
<view class="choice-main">
<view class="choice-price">
价格区间(元)
</view>
<view class="choice-between">
<input type="text" v-model="higtPrice" placeholder="最低价"/>
<view class="line">
</view>
<input type="text" v-model="lowPrice" placeholder="最高价"/>
</view>
<view class="choice-price">
品牌
</view>
<view class="choice-brand">
<view class="choice-item" v-for="i in 5">
富安娜
</view>
</view>
<view class="choice-submit">
<view class="sub" @click="closePopup">
取消
</view>
<view class="sub confirm" @click="GetData">
确定
</view>
</view>
</view>
</u-popup>
</view>
<u-checkbox-group>
<u-checkbox v-model="checked">xxxx</u-checkbox>
</u-checkbox-group>
</template>
<script>
export default {
data() {
return {
keyword: '',
keys:[],
page:1,
pageSize:10,
mainData:[],
showChoice:false,
higtPrice:'',
lowPrice:''
};
},
created() {
this.GetData()
},
methods:{
GetData() {
this.$request.get(`/v1/goods/getGoodsByType?page=${this.page}&pageSize=${this.pageSize}&type=1&higtPrice=${this.higtPrice}&lowPrice=${this.lowPrice}`).then((res) => {
this.mainData = res.data.list
console.log(3435333, this.mainData)
this.closePopup()
})
},
getKeys(){
this.$request.get(`/v1/brand/getBrandList`).then((res) => {
this.keys = res.data.list
console.log(3333, this.keys)
})
},
hideKey(){
this.keys = []
},
closePopup(){
this.higtPrice = ''
this.lowPrice = ''
this.showChoice = false
checked: true,
}
}
}
</script>
<style scoped>
page{
background-color: #ffffff;
}
.container{
background-color: #ffffff;
.search-box{
padding: 34upx 32upx;
/deep/ .u-action-active{
background:rgba(255,105,105,1);
border-radius:32upx;
border:2upx solid rgba(254,156,143,1);
padding: 10upx 22upx;
width: 108upx;
margin-left: 32upx;
color: #ffffff;
}
}
.search-word{
padding: 0 34upx;
margin-top: 12upx;
.search-hot{
font-size:32upx;
line-height:44upx;
margin-bottom: 24upx;
}
.search-key{
display: flex;
flex-wrap: wrap;
.key-font{
background-color: rgba(242, 242, 242, 1);
border-radius:24upx;
padding: 6upx 30upx;
font-size:28upx;
line-height:40upx;
color: #252A33;
margin-right: 32upx;
margin-bottom: 36upx;
}
}
}
.search-end{
display: flex;
padding: 0 65upx;
justify-content: space-between;
font-size:28upx;
line-height:80upx;
}
/* 精品推荐 */
.guess-section{
display:flex;
flex-wrap:wrap;
padding: 0 32upx;
padding-top: 24upx;
background: $page-color-base;
.guess-item{
display:flex;
flex-direction: column;
width: 47.5%;
margin-bottom: 40upx;
border-radius:8upx;
background-color: #ffffff;
&:nth-child(2n+1){
margin-right: 4.5%;
}
}
.image-wrapper{
width: 100%;
height: 330upx;
overflow: hidden;
position: relative;
image{
width: 100%;
height: 100%;
opacity: 1;
}
.goods-tip{
display: block;
position: absolute;
top: 20upx;
right: 32upx;
width: 56upx;
height: 56upx;
background-color: #000000;
line-height: 56upx;
text-align: center;
border-radius: 50%;
font-size:18upx!important;
color: #ffffff;
}
}
.goods-info{
padding: 8upx 20upx 22upx;
position: relative;
.title{
font-size: 24upx;
color: #202020;
line-height: 34upx;
}
.price{
font-size: 24upx;
color: $text-color-red;
line-height:28upx;
}
.sell{
flex-basis: 16upx;
color: #B1ADAD;
margin-left: 4upx;
}
.icon-buy{
position: absolute;
width: 44upx;
height: 44upx;
bottom: 24upx;
right: 24upx;
}
}
}
}
.choice{
width: 100%;
height: 88upx;
padding-left: 40upx;
background-color: #F2F2F2;
font-size:24upx;
color: #8E9299;
margin-bottom: 20upx;
}
.choice-main{
padding: 0upx 32upx;
.choice-price{
font-size:24upx;
line-height:34upx;
color: #252A33;
margin-bottom: 24upx;
}
.line{
width:24upx;
height:2upx;
background-color: #DADEE6;
margin: 0 12upx;
vertical-align: middle;
margin-top: 30upx;
}
.choice-between{
display: flex;
margin-bottom: 36upx;
input{
width: 136upx;
height: 64upx;
border: 2upx solid #DADEE6;
padding-left: 16upx;
}
}
.choice-brand{
display: flex;
flex-wrap: wrap;
.choice-item{
margin-right:32upx;
font-size:28upx;
line-height:40upx;
padding: 4upx 32upx;
background:linear-gradient(180deg,rgba(255,162,162,1) 0%,rgba(255,105,105,1) 100%);
border-radius:24upx;
margin-bottom: 44upx;
color: #ffffff;
&:nth-of-type(2n){
margin-right:0upx;
}
}
}
.choice-submit{
display: flex;
position: absolute;
bottom: 72upx;
.sub{
font-size:30upx;
height: 68upx;
line-height: 60upx;
color: #FF6969;
padding: 0upx 24upx;
border:2px solid #DADEE6;
border-radius:34upx;
color: #DADEE6;
}
.confirm{
border-color: #FF6969;
color: #FF6969;
margin-left: 32upx;
}
}
}
</style>
......@@ -209,6 +209,10 @@ export default [{
}, {
groupName: '导航组件',
list: [{
path: '/pages/componentsB/tabbar/index',
icon: 'tabbar',
title: 'Tabbar 底部导航栏',
},{
path: '/pages/componentsA/backTop/index',
icon: 'backTop',
title: 'BackTop 返回顶部',
......
......@@ -153,12 +153,14 @@
backspaceClick() {
this.$emit('backspace');
clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
this.timer = null;
this.timer = setInterval(() => {
this.$emit('backspace');
}, 250);
},
clearTimer() {
clearInterval(this.timer);
this.timer = null;
},
}
};
......@@ -166,7 +168,7 @@
<style lang="scss" scoped>
@import "../../libs/css/style.components.scss";
.u-keyboard-grids {
background: rgb(215, 215, 217);
padding: 24rpx 0;
......
......@@ -98,7 +98,7 @@
<style lang="scss" scoped>
@import "../../libs/css/style.components.scss";
.u-checkbox-group {
/* #ifndef MP */
display: inline-flex;
......
......@@ -86,7 +86,7 @@
activeColor: '#2979ff',
max: 999999,
emitEvent: () => {},
width: '',
width: 'auto',
wrap: false
}
}
......@@ -199,7 +199,7 @@
<style lang="scss" scoped>
@import "../../libs/css/style.components.scss";
.u-checkbox {
display: -webkit-flex;
display: flex;
......@@ -210,7 +210,7 @@
user-select: none;
line-height: 1.8;
}
.u-checkbox__icon-wrap,
.u-checkbox__label {
color: $u-content-color;
......
<template>
<view class="u-form-item" :class="{'u-border-bottom': borderBottom, 'u-form-item__border-bottom--error': validateState === 'error' && showError('border-bottom')}">
<view class="u-form-item" :class="{'u-border-bottom': parentParam.borderBottom, 'u-form-item__border-bottom--error': validateState === 'error' && showError('border-bottom')}">
<view class="u-form-item__body" :style="{
flexDirection: labelPosition == 'left' ? 'row' : 'column'
flexDirection: parentParam.labelPosition == 'left' ? 'row' : 'column'
}">
<view class="u-form-item--left" :style="{
width: labelPosition == 'left' ? getLabelWidth : '100%',
flex: `0 0 ${labelPosition == 'left' ? getLabelWidth : '100%'}`,
marginBottom: labelPosition == 'left' ? 0 : '10rpx',
width: parentParam.labelPosition == 'left' ? $u.addUnit(parentParam.labelWidth) : '100%',
flex: `0 0 ${parentParam.labelPosition == 'left' ? $u.addUnit(parentParam.labelWidth) : '100%'}`,
marginBottom: parentParam.labelPosition == 'left' ? 0 : '10rpx',
}">
<!-- 为了块对齐 -->
<view class="u-form-item--left__content">
......@@ -16,8 +16,8 @@
<view class="u-form-item--left__content__icon" v-if="leftIcon">
<u-icon :name="leftIcon" :custom-style="leftIconStyle"></u-icon>
</view>
<view class="u-form-item--left__content__label" :style="[labelStyle, {
'justify-content': labelAlign == 'left' ? 'flex-star' : labelAlign == 'center' ? 'center' : 'flex-end'
<view class="u-form-item--left__content__label" :style="[parentParam.labelStyle, {
'justify-content': parentParam.labelAlign == 'left' ? 'flex-star' : parentParam.labelAlign == 'center' ? 'center' : 'flex-end'
}]">
{{label}}
</view>
......@@ -36,7 +36,7 @@
</view>
</view>
<view class="u-form-item__message" v-if="validateState === 'error' && showError('message')" :style="{
paddingLeft: labelPosition == 'left' ? getLabelWidth : '0',
paddingLeft: parentParam.labelPosition == 'left' ? $u.addUnit(parentParam.labelWidth) : '0',
}">{{validateMessage}}</view>
</view>
</template>
......@@ -65,7 +65,7 @@ schema.warning = function(){};
* @property {Boolean} required 是否显示左边的"*"号,这里仅起展示作用,如需校验必填,请通过rules配置必填规则(默认false)
* @example <u-form-item label="姓名"><u-input v-model="form.name" /></u-form-item>
*/
export default {
name: 'u-form-item',
mixins: [Emitter],
......@@ -89,13 +89,13 @@ export default {
},
// 是否显示表单域的下划线边框
borderBottom: {
type: Boolean,
default: true
type: [Boolean, String],
default: ''
},
// label的位置,left-左边,top-上边
labelPosition: {
type: String,
default: 'left'
default: ''
},
// label的宽度,单位rpx
labelWidth: {
......@@ -112,7 +112,7 @@ export default {
// lable字体的对齐方式
labelAlign: {
type: String,
default: 'left'
default: ''
},
// 右侧图标
rightIcon: {
......@@ -152,9 +152,26 @@ export default {
validateMessage: '' ,// 校验失败的提示语
// 有错误时的提示方式,message-提示信息,border-如果input设置了边框,变成呈红色,
// border-bottom-下边框呈现红色,none-无提示
errorType: ['message']
errorType: ['message'],
parentParam: {
labelStyle: {}, // lable的样式,对象形式
labelAlign: '', // lable的对齐方式
labelWidth: '', // 提示文字的宽度,单位rpx
labelPosition: '', // 表单域提示文字的位置
borderBottom: '', // 是否显示表单域的下划线边框
}
};
},
created() {
// 如果子组件有值,优先使用子组件的,否则使用u-from提供的值
this.parentParam = this.$u.getParent.call(this, 'u-form', {
labelStyle: this.labelStyle,
labelWidth: this.labelWidth,
labelPosition: this.labelPosition,
borderBottom: this.borderBottom,
labelAlign: this.labelAlign
});
},
watch: {
validateState(val) {
this.broadcastInputError();
......@@ -177,10 +194,6 @@ export default {
else return false;
}
},
// 获取labelWidth的值
getLabelWidth() {
return this.labelWidth == 'auto' ? 'auto' : this.labelWidth + 'rpx';
}
},
methods: {
broadcastInputError() {
......@@ -291,7 +304,7 @@ export default {
<style lang="scss" scoped>
@import "../../libs/css/style.components.scss";
.u-form-item {
display: flex;
// align-items: flex-start;
......@@ -301,30 +314,30 @@ export default {
box-sizing: border-box;
line-height: $u-form-item-height;
flex-direction: column;
&__border-bottom--error:after {
border-color: $u-type-error;
}
&__body {
display: flex;
}
&--left {
display: flex;
align-items: center;
&__content {
position: relative;
display: flex;
align-items: center;
padding-right: 10rpx;
flex: 1;
&__icon {
margin-right: 8rpx;
}
&--required {
position: absolute;
left: -16rpx;
......@@ -332,7 +345,7 @@ export default {
color: $u-type-error;
padding-top: 6rpx;
}
&__label {
display: flex;
align-items: center;
......@@ -340,15 +353,15 @@ export default {
}
}
}
&--right {
flex: 1;
&__content {
display: flex;
align-items: center;
flex: 1;
&__slot {
flex: 1;
/* #ifndef MP */
......@@ -356,13 +369,13 @@ export default {
align-items: center;
/* #endif */
}
&__icon {
margin-left: 10rpx;
}
}
}
&__message {
font-size: 24rpx;
line-height: 24rpx;
......
......@@ -12,7 +12,7 @@
* @property {Array} errorType 错误的提示方式,数组形式,见上方说明(默认['message'])
* @example <u-form :model="form" ref="uForm"></u-form>
*/
export default {
name: 'u-form',
props: {
......@@ -37,7 +37,34 @@ export default {
default() {
return ['message', 'toast']
}
}
},
// 是否显示表单域的下划线边框
borderBottom: {
type: Boolean,
default: true
},
// label的位置,left-左边,top-上边
labelPosition: {
type: String,
default: 'left'
},
// label的宽度,单位rpx
labelWidth: {
type: [String, Number],
default: 90
},
// lable字体的对齐方式
labelAlign: {
type: String,
default: 'left'
},
// lable的样式,对象形式
labelStyle: {
type: Object,
default() {
return {}
}
},
},
provide() {
return {
......
......@@ -13,17 +13,17 @@
:lazy-load="lazyLoad"
class="u-image__image"
:style="{
borderRadius: shape == 'circle' ? '50%' : borderRadius + 'rpx',
borderRadius: shape == 'circle' ? '50%' : $u.addUnit(borderRadius),
}"
></image>
<view v-if="showLoading && loading" class="u-image__loading" :style="{
borderRadius: shape == 'circle' ? '50%' : borderRadius + 'rpx',
borderRadius: shape == 'circle' ? '50%' : $u.addUnit(borderRadius),
}">
<slot v-if="$slots.loading" name="loading" />
<u-icon v-else :name="loadingIcon"></u-icon>
</view>
<view v-if="showError && isError && !loading" class="u-image__error" :style="{
borderRadius: shape == 'circle' ? '50%' : borderRadius + 'rpx',
borderRadius: shape == 'circle' ? '50%' : $u.addUnit(borderRadius),
}">
<slot v-if="$slots.error" name="error" />
<u-icon v-else :name="errorIcon"></u-icon>
......
<template>
<view class="u-numberbox">
<view class="u-icon-minus" @tap.stop="minus" :class="{ 'u-icon-disabled': disabled || inputVal <= min }" :style="{
<view class="u-icon-minus" @touchstart.stop="btnTouchStart('minus')" @touchend.stop="clearTimer" :class="{ 'u-icon-disabled': disabled || inputVal <= min }" :style="{
background: bgColor,
height: inputHeight + 'rpx',
color: color
......@@ -15,7 +15,7 @@
height: inputHeight + 'rpx',
width: inputWidth + 'rpx'
}" />
<view class="u-icon-plus" @tap.stop="plus" :class="{ 'u-icon-disabled': disabled || inputVal >= max }" :style="{
<view class="u-icon-plus" @touchstart.stop="btnTouchStart('plus')" @touchend.stop="clearTimer" :class="{ 'u-icon-disabled': disabled || inputVal >= max }" :style="{
background: bgColor,
height: inputHeight + 'rpx',
color: color
......@@ -42,11 +42,13 @@
* @property {String | Number} input-width 输入框宽度,单位rpx(默认80)
* @property {String | Number} input-height 输入框和按钮的高度,单位rpx(默认50)
* @property {String | Number} index 事件回调时用以区分当前发生变化的是哪个输入框
* @property {Boolean} long-press 是否开启长按连续递增或递减(默认true)
* @property {String | Number} press-time 开启长按触发后,每触发一次需要多久,单位ms(默认250)
* @property {String | Number} cursor-spacing 指定光标于键盘的距离,避免键盘遮挡输入框,单位rpx(默认200)
* @event {Function} change 输入框内容发生变化时触发,对象形式
* @event {Function} blur 输入框失去焦点时触发,对象形式
* @event {Function} minus 点击减少按钮时触发(按钮可点击情况下),对象形式
* @event {Function} plus 点击增加按钮时触发(按钮可点击情况下),对象形式
* @event {Function} plus 点击增加按钮时触发(按钮可点击情况下),对象形式
* @example <u-number-box :min="1" :max="100"></u-number-box>
*/
export default {
......@@ -117,6 +119,16 @@
cursorSpacing: {
type: [Number, String],
default: 100
},
// 是否开启长按连续递增或递减
longPress: {
type: Boolean,
default: true
},
// 开启长按触发后,每触发一次需要多久
pressTime: {
type: [Number, String],
default: 250
}
},
watch: {
......@@ -128,19 +140,20 @@
// 为了让用户能够删除所有输入值,重新输入内容,删除所有值后,内容为空字符串
if (v1 == '') return;
let value = 0;
// 首先判断是否正整数,并且在min和max之间,如果不是,使用原来值
let tmp = /(^\d+$)/.test(v1);
// 首先判断是否数值,并且在min和max之间,如果不是,使用原来值
let tmp = this.$u.test.number(v1);
if (tmp && v1 >= this.min && v1 <= this.max) value = v1;
else value = v2;
this.handleChange(value, 'change');
this.$nextTick(() => {
this.inputVal = value;
this.inputVal = v1;
})
}
},
data() {
return {
inputVal: 1 // 输入框中的值,不能直接使用props中的value,因为应该改变props的状态
inputVal: 1 , // 输入框中的值,不能直接使用props中的value,因为应该改变props的状态
timer: null, // 用作长按的定时器
};
},
created() {
......@@ -153,6 +166,25 @@
}
},
methods: {
// 点击退格键
btnTouchStart(callback) {
// 先执行一遍方法,否则会造成松开手时,就执行了clearTimer,导致无法实现功能
this[callback]();
// 如果没开启长按功能,直接返回
if(!this.longPress) return ;
clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
this.timer = null;
this.timer = setInterval(() => {
// 执行加或减函数
this[callback]();
}, this.pressTime);
},
clearTimer() {
this.$nextTick(() => {
clearInterval(this.timer);
this.timer = null;
})
},
minus() {
this.computeVal('minus');
},
......@@ -189,6 +221,7 @@
} catch (e) {
baseNum2 = 0;
}
console.log(num1, num2, baseNum1, baseNum2);
baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
let precision = baseNum1 >= baseNum2 ? baseNum1 : baseNum2;
return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision);
......@@ -244,7 +277,7 @@
<style lang="scss" scoped>
@import "../../libs/css/style.components.scss";
.u-numberbox {
display: inline-flex;
align-items: center;
......
......@@ -2,153 +2,157 @@
<view class="u-keyboard" @touchmove.stop.prevent>
<view class="u-keyboard-grids">
<view
class="u-keyboard-grids-item"
:class="[btnBgGray(index) ? 'u-bg-gray' : '', index <= 2 ? 'u-border-top' : '', index < 9 ? 'u-border-bottom' : '', (index + 1) % 3 != 0 ? 'u-border-right' : '']"
:style="[itemStyle(index)]"
v-for="(item, index) in numList"
:key="index"
:hover-class="hoverClass(index)"
:hover-stay-time="100"
@tap="keyboardClick(item)"
>
class="u-keyboard-grids-item"
:class="[btnBgGray(index) ? 'u-bg-gray' : '', index <= 2 ? 'u-border-top' : '', index < 9 ? 'u-border-bottom' : '', (index + 1) % 3 != 0 ? 'u-border-right' : '']"
:style="[itemStyle(index)]"
v-for="(item, index) in numList"
:key="index"
:hover-class="hoverClass(index)"
:hover-stay-time="100"
@tap="keyboardClick(item)">
<view class="u-keyboard-grids-btn">{{ item }}</view>
</view>
<view class="u-keyboard-grids-item u-bg-gray" hover-class="u-hover-class" :hover-stay-time="100" @touchstart.stop="backspaceClick" @touchend="clearTimer">
<view class="u-keyboard-back u-keyboard-grids-btn"><u-icon name="backspace" :size="38" :bold="true"></u-icon></view>
<view class="u-keyboard-grids-item u-bg-gray" hover-class="u-hover-class" :hover-stay-time="100" @touchstart.stop="backspaceClick"
@touchend="clearTimer">
<view class="u-keyboard-back u-keyboard-grids-btn">
<u-icon name="backspace" :size="38" :bold="true"></u-icon>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
// 键盘的类型,number-数字键盘,card-身份证键盘
mode: {
type: String,
default: 'number'
export default {
props: {
// 键盘的类型,number-数字键盘,card-身份证键盘
mode: {
type: String,
default: 'number'
},
// 是否显示键盘的"."符号
dotEnabled: {
type: Boolean,
default: true
},
// 是否打乱键盘按键的顺序
random: {
type: Boolean,
default: false
}
},
// 是否显示键盘的"."符号
dotEnabled: {
type: Boolean,
default: true
data() {
return {
backspace: 'backspace', // 退格键内容
dot: '.', // 点
timer: null, // 长按多次删除的事件监听
cardX: 'X' // 身份证的X符号
};
},
// 是否打乱键盘按键的顺序
random: {
type: Boolean,
default: false
}
},
data() {
return {
backspace: 'backspace', // 退格键内容
dot: '.', // 点
timer: null, // 长按多次删除的事件监听
cardX: 'X' // 身份证的X符号
};
},
computed: {
// 键盘需要显示的内容
numList() {
let tmp = [];
if (!this.dotEnabled && this.mode == 'number') {
if (!this.random) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
} else {
return this.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
computed: {
// 键盘需要显示的内容
numList() {
let tmp = [];
if (!this.dotEnabled && this.mode == 'number') {
if (!this.random) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
} else {
return this.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
}
} else if (this.dotEnabled && this.mode == 'number') {
if (!this.random) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, this.dot, 0];
} else {
return this.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, this.dot, 0]);
}
} else if (this.mode == 'card') {
if (!this.random) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, this.cardX, 0];
} else {
return this.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, this.cardX, 0]);
}
}
} else if (this.dotEnabled && this.mode == 'number') {
if (!this.random) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, this.dot, 0];
} else {
return this.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, this.dot, 0]);
}
} else if (this.mode == 'card') {
if (!this.random) {
return [1, 2, 3, 4, 5, 6, 7, 8, 9, this.cardX, 0];
} else {
return this.$u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, this.cardX, 0]);
},
// 按键的样式,在非乱序&&数字键盘&&不显示点按钮时,index为9时,按键占位两个空间
itemStyle() {
return index => {
let style = {};
if (this.mode == 'number' && !this.dotEnabled && index == 9) style.flex = '0 0 66.6666666666%';
return style;
};
},
// 是否让按键显示灰色,只在非乱序&&数字键盘&&且允许点按键的时候
btnBgGray() {
return index => {
if (!this.random && index == 9 && (this.mode != 'number' || (this.mode == 'number' && this.dotEnabled))) return true;
else return false;
};
},
hoverClass() {
return index => {
if (!this.random && index == 9 && (this.mode == 'number' && this.dotEnabled || this.mode == 'card')) return 'u-hover-class';
else return 'u-keyboard-hover';
}
}
},
// 按键的样式,在非乱序&&数字键盘&&不显示点按钮时,index为9时,按键占位两个空间
itemStyle() {
return index => {
let style = {};
if (this.mode == 'number' && !this.dotEnabled && index == 9) style.flex = '0 0 66.6666666666%';
return style;
};
},
// 是否让按键显示灰色,只在非乱序&&数字键盘&&且允许点按键的时候
btnBgGray() {
return index => {
if (!this.random && index == 9 && (this.mode != 'number' || (this.mode == 'number' && this.dotEnabled))) return true;
else return false;
};
},
hoverClass() {
return index => {
if(!this.random && index == 9 && (this.mode == 'number' && this.dotEnabled || this.mode == 'card')) return 'u-hover-class';
else return 'u-keyboard-hover';
methods: {
// 点击退格键
backspaceClick() {
this.$emit('backspace');
clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
this.timer = null;
this.timer = setInterval(() => {
this.$emit('backspace');
}, 250);
},
clearTimer() {
clearInterval(this.timer);
this.timer = null;
},
// 获取键盘显示的内容
keyboardClick(val) {
// 允许键盘显示点模式和触发非点按键时,将内容转为数字类型
if (this.dotEnabled && val != this.dot && val != this.cardX) val = Number(val);
this.$emit('change', val);
}
}
},
methods: {
// 点击退格键
backspaceClick() {
this.$emit('backspace');
 clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
      this.timer = setInterval(() => {
    this.$emit('backspace');
      }, 250);
},
clearTimer() {
clearInterval(this.timer);
},
// 获取键盘显示的内容
keyboardClick(val) {
// 允许键盘显示点模式和触发非点按键时,将内容转为数字类型
if (this.dotEnabled && val != this.dot && val != this.cardX) val = Number(val);
this.$emit('change', val);
}
}
};
};
</script>
<style lang="scss" scoped>
@import "../../libs/css/style.components.scss";
@import "../../libs/css/style.components.scss";
.u-keyboard {
position: relative;
z-index: 1003;
}
.u-keyboard {
position: relative;
z-index: 1003;
}
.u-keyboard-grids {
display: flex;
flex-wrap: wrap;
}
.u-keyboard-grids {
display: flex;
flex-wrap: wrap;
}
.u-keyboard-grids-item {
flex: 0 0 33.3333333333%;
text-align: center;
font-size: 50rpx;
color: #333;
display: flex;
align-items: center;
justify-content: center;
height: 110rpx;
font-weight: 500;
}
.u-keyboard-grids-item {
flex: 0 0 33.3333333333%;
text-align: center;
font-size: 50rpx;
color: #333;
display: flex;
align-items: center;
justify-content: center;
height: 110rpx;
font-weight: 500;
}
.u-bg-gray {
background-color: #e7e6eb;
}
.u-bg-gray {
background-color: #e7e6eb;
}
.u-keyboard-back {
font-size: 36rpx;
}
.u-keyboard-back {
font-size: 36rpx;
}
.u-keyboard-hover {
background-color: #e7e6eb;
}
.u-keyboard-hover {
background-color: #e7e6eb;
}
</style>
......@@ -36,12 +36,19 @@
export default {
name: 'u-rate',
props: {
// 用于v-model双向绑定选中的星星数量
// 1.4.5版新增
value: {
type: [Number, String],
default: -1
},
// 要显示的星星数量
count: {
type: [Number, String],
default: 5
},
// 当前需要默认选中的星星(选中的个数)
// 1.4.5后通过value双向绑定,不再建议使用此参数
current: {
type: [Number, String],
default: 0
......@@ -98,7 +105,8 @@ export default {
elId: this.$u.guid(),
elClass: this.$u.guid(),
starBoxLeft: 0, // 评分盒子左边到屏幕左边的距离,用于滑动选择时计算距离
activeIndex: this.current, // 当前激活的星星的index
// 当前激活的星星的index,如果存在value,优先使用value,因为它可以双向绑定(1.4.5新增)
activeIndex: this.value != -1 ? this.value : this.current,
starWidth: 0, // 每个星星的宽度
starWidthArr: [] //每个星星最右边到组件盒子最左边的距离
};
......@@ -106,6 +114,9 @@ export default {
watch: {
current(val) {
this.activeIndex = val;
},
value(val) {
this.activeIndex = val;
}
},
methods: {
......@@ -148,7 +159,7 @@ export default {
this.activeIndex = index > this.count ? this.count : index;
// 对最少颗星星的限制
if (this.activeIndex < this.minCount) this.activeIndex = this.minCount;
this.$emit('change', this.activeIndex);
this.emitEvent();
},
// 通过点击,直接选中
click(index, e) {
......@@ -167,7 +178,16 @@ export default {
}
// 对最少颗星星的限制
if (this.activeIndex < this.minCount) this.activeIndex = this.minCount;
this.emitEvent();
},
// 发出事件
emitEvent() {
// 发出change事件
this.$emit('change', this.activeIndex);
// 同时修改双向绑定的value的值
if(this.value != -1) {
this.$emit('input', this.activeIndex);
}
}
},
mounted() {
......@@ -179,7 +199,7 @@ export default {
<style scoped lang="scss">
@import "../../libs/css/style.components.scss";
.u-rate {
display: -webkit-inline-flex;
display: inline-flex;
......
// 此版本发布于2020-07-03
let version = '1.4.4';
// 此版本发布于2020-07-04
let version = '1.4.5';
export default {
v: version,
......
......@@ -10,10 +10,34 @@ export default function getParent(name, keys) {
parent = parent.$parent;
} else {
let data = {};
// 历遍传过来的对象参数
for(let i in keys) {
// 如果父组件有此值则用,无此值则用默认值
data[i] = parent[i] ? parent[i] : keys[i];
// 判断keys是否数组,如果传过来的是一个数组,那么直接使用数组元素值当做键值去父组件寻找
if(Array.isArray(keys)) {
keys.map(val => {
data[val] = parent[val] ? parent[val] : '';
})
} else {
// 历遍传过来的对象参数
for(let i in keys) {
// 如果子组件有此值则用,无此值则用父组件的值
// 判断是否空数组,如果是,则用父组件的值,否则用子组件的值
if(Array.isArray(keys[i])) {
if(keys[i].length) {
data[i] = keys[i];
} else {
data[i] = parent[i];
}
} else if(keys[i].constructor === Object) {
// 判断是否对象,如果是对象,且有属性,那么使用子组件的值,否则使用父组件的值
if(Object.keys(keys[i]).length) {
data[i] = keys[i];
} else {
data[i] = parent[i];
}
} else {
// 只要子组件有传值,即使是false值,也是“传值”了,也需要覆盖父组件的同名参数
data[i] = (keys[i] || keys[i] === false) ? keys[i] : parent[i];
}
}
}
return data;
}
......
{
"name": "uview-ui",
"version": "1.4.4",
"version": "1.4.5",
"description": "uView UI,是uni-app生态优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水",
"main": "index.js",
"keywords": ["uview", "uView", "uni-app", "uni-app ui", "uniapp", "uviewui", "uview ui", "uviewUI", "uViewui", "uViewUI", "uView UI", "uni ui", "uni UI", "uniapp ui", "ui", "UI框架", "uniapp ui框架", "uniapp UI"],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment