提交 d714295f 编写于 作者: VK1688's avatar VK1688

更新uni_modules

上级 16a3e0a8
## 2.6.0(2021-11-19)
* 1、【重要】移除了内置的 `npm` 方式安装的 `uView` 组件库,开发者可以选择自己喜欢的组件库进行开发。[点击查看](https://vkdoc.fsq.pub/client/quickstart.html#%E8%87%AA-client%E7%AB%AF%E6%A1%86%E6%9E%B6-2-6-0-%E8%B5%B7-%E4%B8%8D%E5%86%8D%E5%86%85%E7%BD%AE%E4%BB%BB%E4%BD%95-ui-%E6%A1%86%E6%9E%B6-%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%89%E6%8B%A9%E8%87%AA%E5%B7%B1%E5%96%9C%E6%AC%A2%E7%9A%84-ui-%E7%BB%84%E4%BB%B6%E5%BA%93%E8%BF%9B%E8%A1%8C%E5%BC%80%E5%8F%91%E3%80%82)
* 2、【重要】移除内置组件 `vk-u-goods-sku-popup`(推荐 `vk-data-goods-sku-popup` 代替)[点击查看](https://ext.dcloud.net.cn/plugin?id=2848)
* 3、【重要】移除内置组件 `vk-u-number-box`(推荐 `u-number-box` 代替)
* 4、【重要】移除内置组件 `vk-u-grid-button`
* 5、【重要】移除内置组件 `vk-u-swiper`
* 6、【重要】重构内置组件 `vk-u-verification-code` 并改名为 `vk-data-verification-code`
* 如想要继续使用这些组件,可以把这些组件复制到项目根目录的 `components` 目录(没有则新建)(目录名和组件名需一致,如 `vk-u-grid-button/vk-u-grid-button`
* 完整框架项目地址:`https://ext.dcloud.net.cn/plugin?id=2204`[点击查看](https://ext.dcloud.net.cn/plugin?id=2204)
## 2.5.6(2021-11-13)
* 1、【优化】一些细节
* 完整框架项目地址:`https://ext.dcloud.net.cn/plugin?id=2204`[点击查看](https://ext.dcloud.net.cn/plugin?id=2204)
......
<template>
<view class="vk-data-verification-code">
<view @click="sendSmsCode" :style="customStyle">
<slot :tips="tips" :sec-num="secNum">{{ tips }}</slot>
</view>
</view>
</template>
<script>
/**
* verificationCode 验证码输入框
* @property {String} mobile 接收短信的手机号
* @property {String} type 短信类型,如 register、login
* @property {Number String} seconds 倒计时所需的秒数(默认60)
* @property {Object String} customStyle 自定义样式
* @property {String} start-text 开始前的提示语,见官网说明(默认获取验证码)
* @property {String} change-text 倒计时期间的提示语,必须带有字母"x",见官网说明(默认X秒重新获取)
* @property {String} end-text 倒计结束的提示语,见官网说明(默认重新获取)
* @property {Boolean} keep-running 是否在H5刷新或各端返回再进入时继续倒计时(默认false)
* @event {Function} change 倒计时期间,每秒触发一次
* @event {Function} start 开始倒计时触发
* @event {Function} end 结束倒计时触发
* @example <vk-data-verification-code seconds="60" :mobile="form1.mobile" type="register" custom-style="font-size: 28rpx;"></vk-data-verification-code>
*/
export default {
name: 'vk-data-verification-code',
emits: ['start', 'end', 'change'],
props: {
// 接收短信的手机号
mobile: {
type: String
},
// 短信类型,如 register、login
type: {
type: String,
default: 'login'
},
customStyle: {
type: [String,Object]
},
// 倒计时总秒数
seconds: {
type: [String, Number],
default: 60
},
// 尚未开始时提示
startText: {
type: String,
default: '获取验证码'
},
// 正在倒计时中的提示
changeText: {
type: String,
default: 'X秒重新获取'
},
// 倒计时结束时的提示
endText: {
type: String,
default: '重新获取'
},
// 是否在H5刷新或各端返回再进入时继续倒计时
keepRunning: {
type: Boolean,
default: false
},
// 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
uniqueKey: {
type: String,
default: ''
}
},
data() {
return {
secNum: this.seconds,
timer: null,
canGetCode: true, // 是否可以执行验证码操作
tips: ''
};
},
mounted() {
this.checkKeepRunning();
},
watch: {
seconds: {
immediate: true,
handler(n) {
this.secNum = n;
}
}
},
methods: {
checkKeepRunning() {
// 获取上一次退出页面(H5还包括刷新)时的时间戳,如果没有上次的保存,此值可能为空
let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$uCountDownTimestamp'));
if (!lastTimestamp) return this.changeEvent(this.startText);
// 当前秒的时间戳
let nowTimestamp = Math.floor(+new Date() / 1000);
// 判断当前的时间戳,是否小于上一次的本该按设定结束,却提前结束的时间戳
if (this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {
// 剩余尚未执行完的倒计秒数
this.secNum = lastTimestamp - nowTimestamp;
// 清除本地保存的变量
uni.removeStorageSync(this.uniqueKey + '_$uCountDownTimestamp');
// 开始倒计时
this.start();
} else {
// 如果不存在需要继续上一次的倒计时,执行正常的逻辑
this.changeEvent(this.startText);
}
},
// 开始倒计时
start() {
// 防止快速点击获取验证码的按钮而导致内部产生多个定时器导致混乱
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
this.$emit('start');
this.canGetCode = false;
// 这里放这句,是为了一开始时就提示,否则要等setInterval的1秒后才会有提示
this.changeEvent(this.changeText.replace(/x|X/, this.secNum));
this.setTimeToStorage();
this.timer = setInterval(() => {
if (--this.secNum) {
// 用当前倒计时的秒数替换提示字符串中的"x"字母
this.changeEvent(this.changeText.replace(/x|X/, this.secNum));
} else {
clearInterval(this.timer);
this.timer = null;
this.changeEvent(this.endText);
this.secNum = this.seconds;
this.$emit('end');
this.canGetCode = true;
}
}, 1000);
},
// 重置,可以让用户再次获取验证码
reset() {
this.canGetCode = true;
clearInterval(this.timer);
this.secNum = this.seconds;
this.changeEvent(this.endText);
},
changeEvent(text) {
this.codeChange(text);
this.$emit('change', text);
},
// 保存时间戳,为了防止倒计时尚未结束,H5刷新或者各端的右上角返回上一页再进来
setTimeToStorage() {
if (!this.keepRunning || !this.timer) return;
// 记录当前的时间戳,为了下次进入页面,如果还在倒计时内的话,继续倒计时
// 倒计时尚未结束,结果大于0;倒计时已经开始,就会小于初始值,如果等于初始值,说明没有开始倒计时,无需处理
if (this.secNum > 0 && this.secNum <= this.seconds) {
// 获取当前时间戳(+ new Date()为特殊写法),除以1000变成秒,再去除小数部分
let nowTimestamp = Math.floor(+new Date() / 1000);
// 将本该结束时候的时间戳保存起来 => 当前时间戳 + 剩余的秒数
uni.setStorage({
key: this.uniqueKey + '_$uCountDownTimestamp',
data: nowTimestamp + Number(this.secNum)
});
}
},
// 倒计时进行时
codeChange(text) {
this.tips = text;
this.$emit('codeChange', text);
},
// 发送短信验证码
sendSmsCode() {
let that = this;
let vk = uni.vk;
let mobile = that.mobile;
let type = that.type;
if (!vk.pubfn.checkStr(mobile, 'mobile')) {
vk.toast('请输入正确的手机号码', 'none');
return;
}
if (that.canGetCode) {
that.tips = "发送中...";
vk.userCenter.sendSmsCode({
needAlert: false,
data: {
mobile,
type
},
success: function(data) {
vk.toast('验证码已发送');
that.start();
},
fail: function(err) {
that.tips = that.startText;
if (err.errMsg && err.errMsg.indexOf('触发天级流控') > -1) {
vk.alert('短信发送频繁,请明日再试!');
} else if (err.errMsg && err.errMsg.indexOf('触发小时级流控') > -1) {
vk.alert('短信发送频繁,请过1小时后再试!');
} else if (err.errMsg && err.errMsg.indexOf('触发分钟级流控') > -1) {
vk.alert('短信发送频繁,请稍后再试!');
} else if (err.msg) {
vk.alert(err.msg);
} else {
vk.alert('短信发送频繁,请稍后再试!');
}
}
});
} else {
vk.toast(`${that.secNum}秒后再重试`, 'none');
}
}
},
// 组件销毁的时候,清除定时器,否则定时器会继续存在,系统不会自动清除
// #ifndef VUE3
beforeDestroy() {
this.setTimeToStorage();
clearTimeout(this.timer);
this.timer = null;
},
// #endif
// #ifdef VUE3
beforeUnmount() {
this.setTimeToStorage();
clearTimeout(this.timer);
this.timer = null;
}
// #endif
};
</script>
<style lang="scss" scoped></style>
<template>
<view class="vk-u-grid-button" v-if="getValue('show', true)">
<view v-if="datas && datas.list && datas.list.length > 0">
<view class="grid-view">
<u-grid
:col="getValue('col', 4)"
:border="getValue('border', false)"
:hover-class="getValue('hover-class', 'vk-hover-class')"
>
<u-grid-item v-for="(item,index) in datas.list" :key="index" @click="onClick(item)">
<u-badge v-if="item.badge" :count="item.badge" :offset="[20, 20]"></u-badge>
<u-image v-if="item['icon'] && item['icon'].indexOf('http') == 0"
mode="scaleToFill"
:src="item['icon']"
:height="getValue('icon-size', 46)"
:width="getValue('icon-size', 46)"
:lazy-load="false"
:fade="false"
></u-image>
<u-icon v-else
:name="item['icon'] || 'photo'"
:size="getValue('icon-size', 46)"
:color="item['icon-color'] || getValue('icon-color', 'inherit')"
>
</u-icon>
<view class="grid-text"
:style="{
fontSize:getValue('text-size', 24) + 'rpx',
color:item['text-color'] || getValue('text-color', '#000000'),
marginTop:getValue('text-margin-top', 10) + 'rpx'
}"
>{{item.text}}</view>
<button
v-if="item.openType"
:open-type="item.openType"
plain="true"
style="width: 100rpx;height: 140rpx;position: absolute;border: 0;"
></button>
</u-grid-item>
</u-grid>
</view>
</view>
</view>
</template>
<script>
export default {
name: "vk-u-grid-button",
emits: ["click"],
props: {
dataId:{
type: String,
default () {
return "";
}
},
datas: {
type: Object,
default () {
return {};
}
},
customDatas: {
type: Object,
default () {
return {};
}
}
},
data: function () {
// 组件创建时,进行数据初始化
return {
}
},
mounted() {
},
methods: {
pageTo(url){
this.vk.navigateTo(url);
},
onClick(item){
let that = this;
let { vk } = that;
if(item.miniProgram){
vk.navigateToMiniProgram(item.miniProgram);
}else if(item.page){
that.pageTo(item.page);
}else{
that.$emit("click",item);
}
},
getValue(key, defaultValue){
let { customDatas, datas } = this;
if(!customDatas) customDatas = {};
if(!datas) datas = {};
let value = customDatas[key];
if(typeof value === "undefined"){
value = datas[key];
if(typeof value === "undefined"){
value = defaultValue;
}
}
return value;
}
},
// 计算属性
computed: {
}
}
</script>
<style lang="scss" scoped>
.grid-text{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
</style>
<template>
<view class="vk-u-notice-bar">
<view v-if="datas && datas.list && datas.list.length > 0">
<u-notice-bar
:list="getValue('list')"
:mode="getValue('mode','horizontal')"
:type="getValue('type','warning')"
:volume-icon="getValue('volume-icon', true)"
:more-icon="getValue('more-icon')"
:close-icon="getValue('close-icon')"
:autoplay="getValue('autoplay', true)"
:color="getValue('color')"
:bg-color="getValue('bg-color')"
:show="getValue('show', true)"
:volume-size="getValue('volume-size')"
:font-size="getValue('font-size')"
:duration="getValue('duration', 2000)"
:speed="getValue('speed', 160)"
:is-circular="getValue('is-circular', true)"
:play-state="getValue('play-state', 'play')"
:disable-touch="getValue('disable-touch', true)"
:padding="getValue('padding')"
:border-radius="getValue('border-radius')"
:no-list-hidden="getValue('no-list-hidden', true)"
@click="onClick"
@close="onClose"
@getMore="onGetMore"
@end="onEnd"
></u-notice-bar>
</view>
</view>
</template>
<script>
export default {
name: "vk-u-notice-bar",
props: {
dataId:{
type: String,
default () {
return "";
}
},
datas: {
type: Object,
default () {
return {};
}
},
customDatas: {
type: Object,
default () {
return {};
}
}
},
data: function () {
// 组件创建时,进行数据初始化
return {
}
},
mounted() {
},
methods: {
// 点击通告文字触发,只有mode = vertical,或者mode = horizontal且is-circular = false时有效
onClick(index){
this.$emit("click",index);
},
// 点击右侧关闭图标触发
onClose(){
this.$emit("close");
},
// 点击右侧向右图标触发
onGetMore(){
this.$emit("getMore");
},
// 列表的消息每次被播放一个周期时触发,只有mode = vertical,或者mode = horizontal且is-circular = false时有效
onEnd(){
this.$emit("end");
},
getValue(key, defaultValue){
let { customDatas, datas } = this;
if(!customDatas) customDatas = {};
if(!datas) datas = {};
let value = customDatas[key];
if(typeof value === "undefined"){
value = datas[key];
if(typeof value === "undefined"){
value = defaultValue;
}
}
return value;
}
}
}
</script>
<style lang="scss" scoped>
</style>
<!-- 步进器 -->
<template>
<view class="vk-u-number-box">
<view class="u-icon-minus" @touchstart.prevent="btnTouchStart('minus')" @touchend.stop.prevent="clearTimer" :class="{ 'u-icon-disabled': disabled || inputVal <= min }"
:style="{
background: bgColor,
height: inputHeight + 'rpx',
color: color,
fontSize: size + 'rpx',
minHeight: '1.4em'
}">
<view :style="'font-size:'+(Number(size)+10)+'rpx'" class="num-btn"></view>
</view>
<input :disabled="disabledInput || disabled" :cursor-spacing="getCursorSpacing" :class="{ 'u-input-disabled': disabled }"
v-model="inputVal" class="u-number-input" @blur="onBlur"
type="number" :style="{
color: color,
fontSize: size + 'rpx',
background: bgColor,
height: inputHeight + 'rpx',
width: inputWidth + 'rpx',
}" />
<view class="u-icon-plus" @touchstart.prevent="btnTouchStart('plus')" @touchend.stop.prevent="clearTimer" :class="{ 'u-icon-disabled': disabled || inputVal >= max }"
:style="{
background: bgColor,
height: inputHeight + 'rpx',
color: color,
fontSize: size + 'rpx',
minHeight: '1.4em',
}">
<view :style="'font-size:'+(Number(size)+10)+'rpx'" class="num-btn"></view>
</view>
</view>
</template>
<script>
/**
* numberBox 步进器
* @description 该组件一般用于商城购物选择物品数量的场景。注意:该输入框只能输入大于或等于0的整数,不支持小数输入
* @tutorial https://www.uviewui.com/components/numberBox.html
* @property {Number} value 输入框初始值(默认1)
* @property {String} bg-color 输入框和按钮的背景颜色(默认#F2F3F5)
* @property {Number} min 用户可输入的最小值(默认0)
* @property {Number} max 用户可输入的最大值(默认99999)
* @property {Number} step 步长,每次加或减的值(默认1)
* @property {Number} stepFirst 步进值,首次增加或最后减的值(默认step值和一致)
* @property {Boolean} disabled 是否禁用操作,禁用后无法加减或手动修改输入框的值(默认false)
* @property {Boolean} disabled-input 是否禁止输入框手动输入值(默认false)
* @property {Boolean} positive-integer 是否只能输入正整数(默认true)
* @property {String | Number} size 输入框文字和按钮字体大小,单位rpx(默认26)
* @property {String} color 输入框文字和加减按钮图标的颜色(默认#323233)
* @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 点击增加按钮时触发(按钮可点击情况下),对象形式
* @example <vk-u-number-box :min="1" :max="100"></vk-u-number-box>
*/
export default {
name: "vk-u-number-box",
emits: ["update:modelValue", "input", "change", "blur", "plus", "minus"],
props: {
// 预显示的数字
value: {
type: Number,
default: 1
},
modelValue: {
type: Number,
default: 1
},
// 背景颜色
bgColor: {
type: String,
default: '#F2F3F5'
},
// 最小值
min: {
type: Number,
default: 0
},
// 最大值
max: {
type: Number,
default: 99999
},
// 步进值,每次加或减的值
step: {
type: Number,
default: 1
},
// 步进值,首次增加或最后减的值
stepFirst: {
type: Number,
default: 0
},
// 是否只能输入 step 的倍数
stepStrictly: {
type: Boolean,
default: false
},
// 是否禁用加减操作
disabled: {
type: Boolean,
default: false
},
// input的字体大小,单位rpx
size: {
type: [Number, String],
default: 26
},
// 加减图标的颜色
color: {
type: String,
default: '#323233'
},
// input宽度,单位rpx
inputWidth: {
type: [Number, String],
default: 80
},
// input高度,单位rpx
inputHeight: {
type: [Number, String],
default: 50
},
// index索引,用于列表中使用,让用户知道是哪个numberbox发生了变化,一般使用for循环出来的index值即可
index: {
type: [Number, String],
default: ''
},
// 是否禁用输入框,与disabled作用于输入框时,为OR的关系,即想要禁用输入框,又可以加减的话
// 设置disabled为false,disabledInput为true即可
disabledInput: {
type: Boolean,
default: false
},
// 输入框于键盘之间的距离
cursorSpacing: {
type: [Number, String],
default: 100
},
// 是否开启长按连续递增或递减
longPress: {
type: Boolean,
default: true
},
// 开启长按触发后,每触发一次需要多久
pressTime: {
type: [Number, String],
default: 250
},
// 是否只能输入大于或等于0的整数(正整数)
positiveInteger: {
type: Boolean,
default: true
}
},
watch: {
value(v1, v2) {
// 只有value的改变是来自外部的时候,才去同步inputVal的值,否则会造成循环错误
if(!this.changeFromInner) {
this.inputVal = v1;
// 因为inputVal变化后,会触发this.handleChange(),在其中changeFromInner会再次被设置为true,
// 造成外面修改值,也导致被认为是内部修改的混乱,这里进行this.$nextTick延时,保证在运行周期的最后处
// 将changeFromInner设置为false
this.$nextTick(function(){
this.changeFromInner = false;
})
}
},
modelValue(v1, v2) {
// 只有value的改变是来自外部的时候,才去同步inputVal的值,否则会造成循环错误
if(!this.changeFromInner) {
this.inputVal = v1;
// 因为inputVal变化后,会触发this.handleChange(),在其中changeFromInner会再次被设置为true,
// 造成外面修改值,也导致被认为是内部修改的混乱,这里进行this.$nextTick延时,保证在运行周期的最后处
// 将changeFromInner设置为false
this.$nextTick(function(){
this.changeFromInner = false;
})
}
},
inputVal(v1, v2) {
// 为了让用户能够删除所有输入值,重新输入内容,删除所有值后,内容为空字符串
if (v1 == '') return;
let value = 0;
// 首先判断是否数值,并且在min和max之间,如果不是,使用原来值
let tmp = this.isNumber(v1);
if (tmp && v1 >= this.min && v1 <= this.max) value = v1;
else value = v2;
// 判断是否只能输入大于等于0的整数
if(this.positiveInteger) {
// 小于0,或者带有小数点,
if(v1 < 0 || String(v1).indexOf('.') !== -1) {
value = v2;
// 双向绑定input的值,必须要使用$nextTick修改显示的值
this.$nextTick(() => {
this.inputVal = v2;
})
}
}
// 发出change事件
this.handleChange(value, 'change');
},
min(v1){
if(v1 !== undefined && v1!="" && this.getValue() < v1){
this.$emit("input",v1);
}
},
max(v1){
if(v1 !== undefined && v1!="" && this.getValue() > v1){
this.$emit("input",v1);
}
}
},
data() {
return {
inputVal: 1, // 输入框中的值,不能直接使用props中的value,因为应该改变props的状态
timer: null, // 用作长按的定时器
changeFromInner: false, // 值发生变化,是来自内部还是外部
innerChangeTimer: null, // 内部定时器
};
},
created() {
this.inputVal = Number(this.getValue());
},
computed: {
getCursorSpacing() {
// 先将值转为px单位,再转为数值
return Number(uni.upx2px(this.cursorSpacing));
}
},
methods: {
getValue(){
// #ifndef VUE3
return this.value;
// #endif
// #ifdef VUE3
return this.modelValue;
// #endif
},
// 点击退格键
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');
},
plus() {
this.computeVal('plus');
},
// 为了保证小数相加减出现精度溢出的问题
calcPlus(num1, num2) {
let baseNum, baseNum1, baseNum2;
try {
baseNum1 = num1.toString().split('.')[1].length;
} catch (e) {
baseNum1 = 0;
}
try {
baseNum2 = num2.toString().split('.')[1].length;
} catch (e) {
baseNum2 = 0;
}
baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
let precision = baseNum1 >= baseNum2 ? baseNum1 : baseNum2; //精度
return ((num1 * baseNum + num2 * baseNum) / baseNum).toFixed(precision);
},
// 为了保证小数相加减出现精度溢出的问题
calcMinus(num1, num2) {
let baseNum, baseNum1, baseNum2;
try {
baseNum1 = num1.toString().split('.')[1].length;
} catch (e) {
baseNum1 = 0;
}
try {
baseNum2 = num2.toString().split('.')[1].length;
} catch (e) {
baseNum2 = 0;
}
baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
let precision = baseNum1 >= baseNum2 ? baseNum1 : baseNum2;
return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision);
},
computeVal(type) {
uni.hideKeyboard();
if (this.disabled) return;
let value = 0;
// 新增stepFirst开始
// 减
if (type === 'minus') {
if(this.stepFirst > 0 && this.inputVal == this.stepFirst){
value = this.min;
}else{
value = this.calcMinus(this.inputVal, this.step);
}
} else if (type === 'plus') {
if(this.stepFirst > 0 && this.inputVal < this.stepFirst){
value = this.stepFirst;
}else{
value = this.calcPlus(this.inputVal, this.step);
}
}
if(this.stepStrictly){
let strictly = value % this.step;
if(strictly > 0){
value -= strictly;
}
}
if (value > this.max ) {
value = this.max;
}else if (value < this.min) {
value = this.min;
}
// 新增stepFirst结束
this.inputVal = value;
this.handleChange(value, type);
},
// 处理用户手动输入的情况
onBlur(event) {
let val = 0;
let value = event.detail.value;
// 如果为非0-9数字组成,或者其第一位数值为0,直接让其等于min值
// 这里不直接判断是否正整数,是因为用户传递的props min值可能为0
if (!/(^\d+$)/.test(value) || value[0] == 0) val = this.min;
val = +value;
// 新增stepFirst开始
if(this.stepFirst > 0 && this.inputVal < this.stepFirst && this.inputVal>0){
val = this.stepFirst;
}
// 新增stepFirst结束
if(this.stepStrictly){
let strictly = val % this.step;
if(strictly > 0){
val -= strictly;
}
}
if (val > this.max) {
val = this.max;
} else if (val < this.min) {
val = this.min;
}
this.$nextTick(() => {
this.inputVal = val;
})
this.handleChange(val, 'blur');
},
handleChange(value, type) {
if (this.disabled) return;
// 清除定时器,避免造成混乱
if(this.innerChangeTimer) {
clearTimeout(this.innerChangeTimer);
this.innerChangeTimer = null;
}
// 发出input事件,修改通过v-model绑定的值,达到双向绑定的效果
this.changeFromInner = true;
// 一定时间内,清除changeFromInner标记,否则内部值改变后
// 外部通过程序修改value值,将会无效
this.innerChangeTimer = setTimeout(() => {
this.changeFromInner = false;
}, 150);
this.$emit('input', Number(value));
this.$emit("update:modelValue", Number(value));
this.$emit(type, {
// 转为Number类型
value: Number(value),
index: this.index
})
},
/**
* 验证十进制数字
*/
isNumber(value) {
return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value)
}
}
};
</script>
<style lang="scss" scoped>
.vk-u-number-box {
display: inline-flex;
align-items: center;
}
.u-number-input {
position: relative;
text-align: center;
padding: 0;
margin: 0 6rpx;
display: flex;
align-items: center;
justify-content: center;
}
.u-icon-plus,
.u-icon-minus {
width: 60rpx;
display: flex;
justify-content: center;
align-items: center;
}
.u-icon-plus {
border-radius: 0 8rpx 8rpx 0;
}
.u-icon-minus {
border-radius: 8rpx 0 0 8rpx;
}
.u-icon-disabled {
color: #c8c9cc !important;
background: #f7f8fa !important;
}
.u-input-disabled {
color: #c8c9cc !important;
background-color: #f2f3f5 !important;
}
.num-btn{
font-weight:550;
position: relative;
top:-4rpx;
}
</style>
<template>
<view class="vk-u-swiper">
<view v-if="datas && datas.list && datas.list.length > 0">
<u-swiper
:list="getValue('list')"
:title="getValue('title')"
:mode="getValue('mode','round')"
:height="getValue('height',300)"
:indicator-pos="getValue('indicator-pos','bottomCenter')"
:autoplay="getValue('autoplay',true)"
:interval="getValue('interval',2500)"
:circular="getValue('circular',true)"
:duration="getValue('duration',500)"
:border-radius="getValue('border-radius',8)"
:title-style="getValue('title-style')"
:img-mode="getValue('img-mode','aspectFill')"
:name="getValue('name','image')"
:bg-color="getValue('bg-color','#f3f4f6')"
:current ="getValue('current',0)"
:effect3d="getValue('effect3d')"
:effect3d-previous-margin="getValue('effect3d-previous-margin',50)"
@click="onClick"
@change="onChange"
></u-swiper>
</view>
<view v-else
:style="'height: '+getValue('height',300)+'rpx;'"
style="display: block;"
>
<u-image width="100%" height="100%" mode="scaleToFill"></u-image>
</view>
</view>
</template>
<script>
export default {
name: "vk-u-swiper",
props: {
dataId:{
type: String,
default () {
return "";
}
},
datas: {
type: Object,
default () {
return {};
}
},
customDatas: {
type: Object,
default () {
return {};
}
}
},
data: function () {
// 组件创建时,进行数据初始化
return {
}
},
mounted() {
},
methods: {
// 点击轮播图时触发 index:点击了第几张图片,从0开始
onClick(index){
this.$emit("click",index);
},
// 轮播图切换时触发(自动或者手动切换) index:切换到了第几张图片,从0开始
onChange(index){
this.$emit("change",index);
},
getValue(key, defaultValue){
let { customDatas, datas } = this;
if(!customDatas) customDatas = {};
if(!datas) datas = {};
let value = customDatas[key];
if(typeof value === "undefined"){
value = datas[key];
if(typeof value === "undefined"){
value = defaultValue;
}
}
return value;
},
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<view class="vk-u-verification-code">
<!-- 验证码倒计时开始 -->
<u-verification-code
ref="uCode"
:seconds="seconds"
@end="end"
@start="start"
@change="codeChange"
:start-text="startText"
:change-text="changeText"
:end-text="endText"
:keep-running="keepRunning"
:unique-key="uniqueKey"
></u-verification-code>
<view @click="sendSmsCode">{{ tips }}</view>
<!-- 验证码倒计时结束 -->
</view>
</template>
<script>
export default {
name: "vk-u-verification-code",
emits: ["start", "end", "codeChange"],
props: {
seconds: {
type: [Number,String],
default () {
return 10;
}
},
mobile: {
type: String
},
type: {
type: String,
default () {
return "login";
}
},
startText:{
type: String,
default () {
return "获取验证码";
}
},
changeText:{
type: String,
default () {
return "X秒重新获取";
}
},
endText:{
type: String,
default () {
return "重新获取";
}
},
keepRunning:{
type: Boolean,
default () {
return false;
}
},
uniqueKey:{
type: String
},
},
data:function () {
// 组件创建时,进行数据初始化
return {
tips:"",
}
},
//组件创建时,进行数据初始化
created:function(){
},
computed: {
},
methods: {
// 倒计时开始
start() {
this.$emit("start",{
isStart : true
});
},
// 倒计时结束
end() {
this.$emit("end",{
isEnd : true
});
},
// 倒计时进行时
codeChange(text) {
this.tips = text;
this.$emit("codeChange",text);
},
// 发送短信验证码
sendSmsCode() {
var that = this;
var vk = getApp().globalData.vk;
var mobile = that.mobile;
var type = that.type;
if(!vk.pubfn.checkStr(mobile, 'mobile')){
vk.toast('请输入正确的手机号码',"none");
return;
}
if(that.$refs.uCode.canGetCode) {
vk.userCenter.sendSmsCode({
needAlert:false,
data:{
mobile: mobile,
type: type,
},
success:function(data){
vk.toast('验证码已发送');
that.$refs.uCode.start();
},
fail:function(err){
if(err.errMsg && err.errMsg.indexOf("触发天级流控") > -1){
vk.alert("短信发送频繁,请明日再试!");
}else if(err.errMsg && err.errMsg.indexOf("触发小时级流控") > -1){
vk.alert("短信发送频繁,请过1小时后再试!");
}else if(err.errMsg && err.errMsg.indexOf("触发分钟级流控") > -1){
vk.alert("短信发送频繁,请稍后再试!");
}else if(err.msg){
vk.alert(err.msg);
}else{
vk.alert("短信发送频繁,请稍后再试!");
}
}
});
} else {
vk.toast('倒计时结束后再发送',"none");
}
}
}
}
</script>
<style lang="scss" scoped>
</style>
{
"id": "vk-unicloud",
"displayName": "vk-unicloud-router开发框架核心库 - 已集成uni-id 框架内置了众多API。",
"version": "2.5.6",
"version": "2.6.0",
"description": "此为vk-unicloud-router框架核心库(新手建议下载完整框架项目)已集成uni-id支持云函数url化。众多现成API,内置小白也能轻松上手的数据库API。使你项目刚起步进度就是百分之50",
"keywords": [
"vk-unicloud-router",
......
......@@ -34,7 +34,7 @@
#### 5、全面支持`url化`的云函数请求,您无需关心url化后参数的获取问题
#### 6、已集成`uni-id` 当前版本:`3.3.8`(已支持真实发送邮箱验证码和阿里云短信验证码)
#### 6、已集成`uni-id` 当前版本:`3.3.9`(已支持真实发送邮箱验证码和阿里云短信验证码)
```
6.1、由于每个应用基本都会用上用户系统,官方建议所有`uniCloud`应用均使用`uni-id`作为用户体系,
有了统一的账户规范,并且围绕这套账户规范,有各种各样插件,那么开发者可以随意整合这些插件,让数据连同。
......@@ -51,37 +51,35 @@
#### 10、`vk.baseDao.selects` 数据库万能连表查询API [点击查看](https://vkdoc.fsq.pub/client/uniCloud/db/selects.html)
#### 11、集成`uview-ui` UI框架(感谢`uview-ui`作者)。
#### 11、集成 `uview-ui` UI框架(感谢`uview-ui`作者)。
#### 12、前后端一体动态数据组件
#### 12、`商品SKU选择器组件`(打造uni插件市场功能最全的SKU选择器组件)
#### 13、`商品SKU选择器组件`(打造uni插件市场功能最全的SKU选择器组件)
#### 13、对 `Vuex` 进行了深度封装(支持持久化),现在可以很方便的使用Vuex进行读取和储存。[点击查看](https://vkdoc.fsq.pub/client/pages/vuex.html)
#### 14、对 `Vuex` 进行了深度封装(支持持久化),现在可以很方便的使用Vuex进行读取和储存。[点击查看](https://vkdoc.fsq.pub/client/pages/vuex.html)
#### 14、自定义过滤器(在业务云函数执行之前(或之后),统一拦截,进行过滤后再放行,支持设置多个过滤器,并按指定顺序执行)
#### 15、自定义过滤器(在业务云函数执行之前(或之后),统一拦截,进行过滤后再放行,支持设置多个过滤器,并按指定顺序执行
#### 15、支持设置需要登录的页面列表或不需要登录的页面列表(通过本地token检测,无网络请求,支持通配符写法
#### 16、支持设置需要登录的页面列表或不需要登录的页面列表(通过本地token检测,无网络请求,支持通配符写法)
#### 16、支持设置可以被分享的页面列表或禁止分享的页面列表(支持通配符写法)
#### 17、支持设置可以被分享的页面列表或禁止分享的页面列表(支持通配符写法)
#### 17、`vk.localStorage` 封装本地缓存的curd,同时具有监听缓存被更新和被删除的功能。[点击查看用法](https://vkdoc.fsq.pub/client/pages/localStorage.html)
#### 18、`vk.localStorage` 封装本地缓存的curd,同时具有监听缓存被更新和被删除的功能。[点击查看用法](https://vkdoc.fsq.pub/client/pages/localStorage.html)
#### 18、美化云函数请求过程中的日志排版,使请求日志一目了然。
#### 19、美化云函数请求过程中的日志排版,使请求日志一目了然。
#### 19、可以`强制关闭`云端服务(适用于需要临时关闭后端服务的情况,如腾讯云迁移数据到阿里云时需要先关闭服务,否则迁移过程中会有新数据产生)
#### 20、可以`强制关闭`云端服务(适用于需要临时关闭后端服务的情况,如腾讯云迁移数据到阿里云时需要先关闭服务,否则迁移过程中会有新数据产生)
#### 20、全局数据缓存API,现在可以很方便的在云函数中使用缓存。 [点击查看详情](https://vkdoc.fsq.pub/client/uniCloud/cache/cache.html)
#### 21、全局数据缓存API,现在可以很方便的在云函数中使用缓存。 [点击查看详情](https://vkdoc.fsq.pub/client/uniCloud/cache/cache.html)
#### 21、【1.8.0 新增】微信小程序服务端API [点击查看文档](https://vkdoc.fsq.pub/client/uniCloud/plus/weixin.html)
#### 22、【1.8.0 新增】微信小程序服务端API [点击查看文档](https://vkdoc.fsq.pub/client/uniCloud/plus/weixin.html)
#### 22、【1.8.12 新增】百度开放平台服务端API [点击查看文档](https://vkdoc.fsq.pub/client/uniCloud/plus/baidu.html)
#### 23、【1.8.12 新增】百度开放平台服务端API [点击查看文档](https://vkdoc.fsq.pub/client/uniCloud/plus/baidu.html)
#### 23、【1.9.1 新增】【全网首家】云函数URL化之URL重写 [点击查看文档](https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/urlrewrite.html)
#### 24、【1.9.1 新增】【全网首家】云函数URL化之URL重写 [点击查看文档](https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/urlrewrite.html)
#### 24、作者亲自在群内解答框架使用问题,让你轻松上手`uniCloud云开发`。
#### 25、作者亲自在群内解答框架使用问题,让你轻松上手`uniCloud云开发`。
#### 26、其他好处…
#### 25、其他好处…
##### 插件首页体验地址
......@@ -281,7 +279,7 @@ this.vk.callFunction({
[点击查看如何『切换正式环境和开发环境』](https://vkdoc.fsq.pub/client/question/q1.html)
## 本插件更新步骤
[点击查看本插件『更新步骤』](https://vkdoc.fsq.pub/client/question/q5.html)
[点击查看本插件『更新步骤』](https://vkdoc.fsq.pub/client/changeGuide.html)
## uniCloud云函数路由框架研究Q群:`22466457` 如有问题或建议可以在群内讨论。
......
{
"name": "vk-unicloud",
"version": "2.5.6",
"version": "2.6.0",
"description": "【云函数端SDK】VK云函数路由模式uniCloud开发框架,在router目录下执行 npm i vk-unicloud 进行安装和升级",
"main": "index.js",
"homepage": "https://gitee.com/vk-uni/vk-uni-cloud-router.git",
......
......@@ -1384,7 +1384,8 @@ pubfn.getListData2 = function(obj = {}) {
* 2.0使用的queryForm1作为查询,而1.0是form1
* 2.0云函数端是getTableData,而1.0是selects
*/
let { vk, queryForm1 } = that;
let { vk } = that;
let queryForm1 = that.queryForm1 || that.queryForm;
// 标记为请求中
that.loading = true;
let hasMore = true;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册