Commit c1c3e009 authored by wlxuqu's avatar wlxuqu

1.【新增】readMore组件新增index参数和close,open事件

2.【新增】新增man,woman,level三个图标
3.【新增】新增"注意事项"专题,记录一些踩坑知识点,让同学们少走弯路,详见[注意事项](https://uviewui.com/components/feature.html)
4.【新增】alertTips组件新增icon、title-style、desc-style、icon-style参数
5.【新增】新增节流和防抖方法,通过this.$u.debounce()和this.$u.throttle()调用,详见[节流防抖](https://uviewui.com/js/debounce.html)
6.【新增】button组件新增节流功能,以及配置间隔时间的throttle-time参数
7.【新增】field和input组件新增trim参数,默认为true,可以去除输入内容两端的空格
8.【优化】优化form-item组件的label设置为空内容时,依然显示左边的占位的问题
9.【优化】优化lazy-load组件修改图片路径后,无法再次加载的问题
10.【优化】优化navbar,upload,tabbar等组件由于各小程序props参数类型为Function,组件内执行父组件方法时this上下文丢失的问题
11.【优化】优化numberbox组件无法阻止事件冒泡的问题
12.【优化】优化timeFormat组件由于使用es7的padStart方法,导致在电脑版微信小程序无法识别的问题
13.【调整】调整this.$u.sys和this.$u.os,通过this.$u.sys()和this.$u.os()调用,详见[升级指南](https://uviewui.com/components/changeGuide.html)
14.【修复】修复无法通过手动设置popup的v-model为false来关闭popup的问题
15.【修复】修复骨架屏组件在微信小程序平台的组件中使用无效的问题。
parent 582557e5
......@@ -9,7 +9,7 @@
uView UI,是[uni-app](https://uniapp.dcloud.io/)生态优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
### **欢迎加群交流反馈:249718512**
### **欢迎加群交流反馈:1129077272**
## 特性
......
......@@ -2,7 +2,7 @@
"name" : "uView",
"appid" : "__UNI__60F4B81",
"description" : "多平台快速开发的UI框架",
"versionName" : "1.5.7",
"versionName" : "1.5.8",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
......@@ -126,6 +126,7 @@
"treeShaking" : {
"enable" : true
}
}
},
"title" : "uView UI"
}
}
......@@ -2,14 +2,14 @@
"easycom": {
"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
},
"condition": { //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [{
"name": "test", //模式名称
"path": "pages/componentsA/avatar/index", //启动页面,必选
"query": "id=1&name=2" //启动参数,在页面的onLoad函数里面得到
}]
},
// "condition": { //模式配置,仅开发期间生效
// "current": 0, //当前激活的模式(list 的索引项)
// "list": [{
// "name": "test", //模式名称
// "path": "pages/componentsC/test/index", //启动页面,必选
// "query": "id=1&name=2" //启动参数,在页面的onLoad函数里面得到
// }]
// },
"pages": [
// 演示-组件
{
......@@ -328,6 +328,13 @@
{
"root": "pages/library",
"pages": [
// debounce-节流防抖
{
"path": "debounce/index",
"style": {
"navigationBarTitleText": "throttle | debounce-节流防抖"
}
},
// deepClone-对象深度克隆
{
"path": "deepClone/index",
......
<template>
<view class="">
<u-navbar title-color="#fff" back-icon-color="#ffffff" :is-fixed="isFixed" :is-back="isBack" :background="background" :back-text-style="{color: '#fff'}" :title="title" :back-icon-name="backIconName" :back-text="backText">
<u-navbar title-color="#fff" back-icon-color="#ffffff"
:is-fixed="isFixed" :is-back="isBack"
:background="background"
:back-text-style="{color: '#fff'}" :title="title"
:back-icon-name="backIconName" :back-text="backText"
>
<view class="slot-wrap" v-if="useSlot">
<view class="search-wrap" v-if="search">
<!-- 如果使用u-search组件,必须要给v-model绑定一个变量 -->
......
......@@ -3,7 +3,7 @@
<view class="u-demo-wrap">
<view class="u-demo-title">演示效果</view>
<view class="u-demo-area">
<u-read-more :toggle="toggle" :show-height="showHeight" ref="uReadMore">
<u-read-more @open="open" @close="close" :toggle="toggle" :show-height="showHeight" ref="uReadMore">
<!-- u-parse组件在微信小程序渲染慢,支付宝小程序rich-text不支持nodes属性 -->
<!-- #ifdef MP-ALIPAY -->
<u-parse :html="content"></u-parse>
......@@ -48,6 +48,12 @@
},
toggleChange(index) {
this.toggle = index == 0 ? true : false;
},
open() {
// console.log('open');
},
close() {
// console.log('close');
}
}
}
......
......@@ -3,7 +3,7 @@
<view class="u-demo-wrap">
<view class="u-demo-title">演示效果</view>
<view class="u-demo-area">
<u-section :title="title" :right="right" :bold="bold" :color="color" :show-line="false"></u-section>
<u-section :title="title" :right="right" :bold="bold" :color="color" :show-line="showLine"></u-section>
</view>
</view>
<view class="u-config-wrap">
......@@ -14,6 +14,10 @@
<view class="u-item-title">更换主标题</view>
<u-subsection vibrateShort :current="1" :list="['是', '否']" @change="titleChange"></u-subsection>
</view>
<view class="u-config-item">
<view class="u-item-title">竖条状态</view>
<u-subsection vibrateShort :list="['显示', '隐藏']" @change="showLineChange"></u-subsection>
</view>
<view class="u-config-item">
<view class="u-item-title">是否显示右边部分</view>
<u-subsection vibrateShort :list="['是', '否']" @change="rightChange"></u-subsection>
......@@ -37,7 +41,8 @@
title: '红豆生南国',
bold: true,
right: true,
color: this.$u.color['mainColor']
color: this.$u.color['mainColor'],
showLine: true
}
},
methods: {
......@@ -53,6 +58,9 @@
},
colorChange(index) {
this.color = index == 0 ? this.$u.color['mainColor'] : this.$u.color['primary'];
},
showLineChange(index) {
this.showLine = !index;
}
}
}
......
<template>
<view>
<u-popup v-model="show" @close="close">
<view>出淤泥而不染,濯清涟而不妖</view>
</u-popup>
<u-button @click="show = true">打开</u-button>
<view style="padding-top: 200px;">
<u-button @click="show = true" :custom-style="{
color: 'red',
borderColor: 'blue'
}">打开</u-button>
</view>
</template>
......@@ -11,13 +11,29 @@
export default {
data() {
return {
show: false
show: true,
list: [{
name: '待收货'
}, {
name: '待付款'
}, {
name: '待评价'
}],
current: 0
}
},
onLoad() {
// setTimeout(() => {
// this.show = false;
// }, 2000)
},
methods: {
close() {
console.log('close');
//console.log('close');
},
change(index) {
this.current = index;
}
}
}
</script>
\ No newline at end of file
</script>
......@@ -22,6 +22,11 @@ export default [
{
groupName: '工具库',
list: [
{
path: 'debounce',
icon: 'debounce',
title: 'throttle | debounce 节流防抖',
},
{
path: 'deepMerge',
icon: 'deepMerge',
......
<template>
<view class="u-demo">
<view class="u-demo-wrap">
<view class="u-demo-title">演示效果</view>
<view class="u-demo-area">
<view class="no-mode-here">
选择节流或者防抖模式,点击按钮,将会执行回调并显示在下方:
</view>
<view class="u-demo-result-line" v-if="result.length">
<view v-for="(item, index) in result" :key="index">{{(index >= 1) ? '-' : ''}}回调</view>
</view>
</view>
</view>
<view class="u-config-wrap">
<view class="u-button" hover-class="u-button--hover" hover-stay-time="150" @tap="btnClick">
点击触发
</view>
<view class="u-config-title u-border-bottom">
参数配置
</view>
<view class="u-config-item">
<view class="u-item-title">模式</view>
<u-subsection vibrateShort :list="['节流', '防抖']" @change="modeChange"></u-subsection>
</view>
<view class="u-config-item">
<view class="u-item-title">时间间隔</view>
<u-subsection vibrateShort current="1" :list="['500ms', '1000ms', '2000ms']" @change="timeoutChange"></u-subsection>
</view>
<view class="u-config-item">
<view class="u-item-title">执行时机</view>
<u-subsection vibrateShort :list="['开始处', '结束处']" @change="immediateChange"></u-subsection>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
result: [],
timeout: 1000,
immediate: true,
mode: 'throttle'
}
},
methods: {
modeChange(index) {
this.mode = index ? 'debouncd' : 'throttle';
},
timeoutChange(index) {
this.timeout = [500, 1000, 2000][index];
},
immediateChange(index) {
this.immediate = !index;
},
getResult() {
if(this.result.length >= 6) this.result = [];
this.result.push(0);
},
btnClick() {
if(this.mode == 'throttle') {
this.$u.throttle(this.getResult, this.timeout, this.immediate);
} else {
this.$u.debounce(this.getResult, this.timeout, this.immediate);
}
}
}
}
</script>
<style lang="scss" scoped>
.u-button {
margin-top: 50rpx;
margin-bottom: 50rpx;
display: flex;
justify-content: center;
align-items: center;
height: 80rpx;
border-radius: 6rpx;
border: 1px solid $u-type-primary;
color: $u-type-primary;
}
.u-button--hover {
color: #fff;
background-color: $u-type-primary;
}
.u-demo-result-line {
display: flex;
justify-content: center;
}
</style>
......@@ -8,13 +8,13 @@
borderColor: borderColor
}">
<view class="u-icon-wrap">
<u-icon v-if="showIcon" :name="$u.type2icon(type)" :size="description ? 40 : 32" class="u-icon" :color="type"></u-icon>
<u-icon v-if="showIcon" :name="uIcon" :size="description ? 40 : 32" class="u-icon" :color="uIconType" :custom-style="iconStyle"></u-icon>
</view>
<view class="u-alert-content" @tap.stop="click">
<view class="u-alert-title" :style="{fontWeight: description ? 500 : 'normal'}">
<view class="u-alert-title" :style="[uTitleStyle]">
{{title}}
</view>
<view v-if="description" class="u-alert-desc">
<view v-if="description" class="u-alert-desc" :style="[descStyle]">
{{description}}
</view>
</view>
......@@ -38,6 +38,10 @@
* @property {String} title 显示的标题文字
* @property {String} description 辅助性文字,颜色比title浅一点,字号也小一点,可选
* @property {String} type 关闭按钮(默认为叉号icon图标)
* @property {String} icon 图标名称
* @property {Object} icon-style 图标的样式,对象形式
* @property {Object} title-style 标题的样式,对象形式
* @property {Object} desc-style 描述的样式,对象形式
* @property {String} close-able 用文字替代关闭图标,close-able为true时有效
* @property {Boolean} show-icon 是否显示左边的辅助图标
* @property {Boolean} show 显示或隐藏组件
......@@ -96,12 +100,55 @@
show: {
type: Boolean,
default: true
}
},
// 左边显示的icon
icon: {
type: String,
default: ''
},
// icon的样式
iconStyle: {
type: Object,
default() {
return {}
}
},
// 标题的样式
titleStyle: {
type: Object,
default() {
return {}
}
},
// 描述文字的样式
descStyle: {
type: Object,
default() {
return {}
}
},
},
data() {
return {
}
},
computed: {
uTitleStyle() {
let style = {};
// 如果有描述文字的话,标题进行加粗
style.fontWeight = this.description ? 500 : 'normal';
// 将用户传入样式对象和style合并,传入的优先级比style高,同属性会被覆盖
return this.$u.deepMerge(style, this.titleStyle);
},
uIcon() {
// 如果有设置icon名称就使用,否则根据type主题,推定一个默认的图标
return this.icon ? this.icon : this.$u.type2icon(type);
},
uIconType() {
// 如果有设置图标的样式,优先使用,没有的话,则用type的样式
return Object.keys(this.iconStyle).length ? '' : this.type;
}
},
methods: {
// 点击内容
click() {
......@@ -173,16 +220,6 @@
visibility: hidden;
}
@keyframes myfirst {
from {
height: 100%;
}
to {
height: 0
}
}
.u-icon {
margin-right: 16rpx;
}
......
......@@ -205,6 +205,11 @@ export default {
dataName: {
type: String,
default: ''
},
// 节流,一定时间内只能触发一次
throttleTime: {
type: [String, Number],
default: 1000
}
},
computed: {
......@@ -236,17 +241,20 @@ export default {
methods: {
// 按钮点击
click(e) {
// 如果按钮时disabled和loading状态,不触发水波纹效果
if (this.loading === true || this.disabled === true) return;
// 是否开启水波纹效果
if (this.ripple) {
// 每次点击时,移除上一次的类,再次添加,才能触发动画效果
this.waveActive = false;
this.$nextTick(function() {
this.getWaveQuery(e);
});
}
this.$emit('click', e);
// 进行节流控制,每this.throttle毫秒内,只在开始处执行
this.$u.throttle(() => {
// 如果按钮时disabled和loading状态,不触发水波纹效果
if (this.loading === true || this.disabled === true) return;
// 是否开启水波纹效果
if (this.ripple) {
// 每次点击时,移除上一次的类,再次添加,才能触发动画效果
this.waveActive = false;
this.$nextTick(function() {
this.getWaveQuery(e);
});
}
this.$emit('click', e);
}, this.throttleTime);
},
// 查询按钮的节点信息
getWaveQuery(e) {
......
......@@ -183,6 +183,11 @@ export default {
type: Boolean,
default: true
},
// 是否自动去除两端的空格
trim: {
type: Boolean,
default: true
}
},
data() {
return {
......@@ -241,7 +246,10 @@ export default {
},
methods: {
onInput(event) {
this.$emit('input', event.target.value);
let value = event.detail.value;
// 判断是否去除空格
if(this.trim) value = this.$u.trim(value);
this.$emit('input', value);
},
onFocus(event) {
this.focused = true;
......
......@@ -3,11 +3,11 @@
<view class="u-form-item__body" :style="{
flexDirection: elLabelPosition == 'left' ? 'row' : 'column'
}">
<view class="u-form-item--left" :style="{
<!-- 微信小程序中,将一个参数设置空字符串,结果会变成字符串"true" -->
<view class="u-form-item--left" v-if="label !== '' && label !== 'true'" :style="{
width: elLabelPosition == 'left' ? $u.addUnit(elLabelWidth) : '100%',
flex: `0 0 ${elLabelPosition == 'left' ? $u.addUnit(elLabelWidth) : '100%'}`,
marginBottom: elLabelPosition == 'left' ? 0 : '10rpx',
}">
<!-- 为了块对齐 -->
<view class="u-form-item--left__content">
......@@ -182,8 +182,8 @@ export default {
},
// label的宽度
elLabelWidth() {
// label默认宽度为90,优先使用本组件的值,如果没有,则用u-form的值
return this.labelWidth ? this.labelWidth : (this.parent ? this.parent.labelWidth : 90);
// label默认宽度为90,优先使用本组件的值,如果没有(如果设置为0,也算是配置了值,依然起效),则用u-form的值
return (this.labelWidth != 0 || this.labelWidth != '') ? this.labelWidth : (this.parent ? this.parent.labelWidth : 90);
},
// label的样式
elLabelStyle() {
......
......@@ -143,7 +143,7 @@ export default {
// 用于解决某些情况下,让图标垂直居中的用途
top: {
type: [String, Number],
default: ''
default: 0
}
},
computed: {
......@@ -167,8 +167,8 @@ export default {
style = {
fontSize: this.size == 'inherit' ? 'inherit' : this.$u.addUnit(this.size),
fontWeight: this.bold ? 'bold' : 'normal',
// 安卓和iOS各需要设置一个到顶部的距离,才能更好的垂直居中
top: this.top === '' ? (this.$u.os == 'ios' ? '2rpx' : '4rpx') : this.$u.addUnit(this.top)
// 某些特殊情况需要设置一个到顶部的距离,才能更好的垂直居中
top: this.$u.addUnit(this.top)
};
// 非主题色值时,才当作颜色值
if (this.color && !this.$u.config.type.includes(this.color)) style.color = this.color;
......
......@@ -200,6 +200,11 @@ export default {
selectionEnd: {
type: [Number, String],
default: -1
},
// 是否自动去除两端的空格
trim: {
type: Boolean,
default: true
}
},
data() {
......@@ -259,15 +264,18 @@ export default {
* @param event
*/
handleInput(event) {
let value = event.detail.value;
// 判断是否去除空格
if(this.trim) value = this.$u.trim(value);
// 当前model 赋值
this.defaultValue = event.detail.value;
this.defaultValue = value;
// vue 原生的方法 return 出去
this.$emit('input', event.detail.value);
this.$emit('input', value);
// 过一个生命周期再发送事件给u-form-item,否则this.$emit('input')更新了父组件的值,但是微信小程序上
// 尚未更新到u-form-item,导致获取的值为空,从而校验混论
this.$nextTick(() => {
// 将当前的值发送到 u-form-item 进行校验
this.dispatch('u-form-item', 'on-form-change', event.detail.value);
this.dispatch('u-form-item', 'on-form-change', value);
});
},
/**
......
......@@ -114,7 +114,7 @@
},
// 计算图片的高度,可能为auto,带%,或者直接数值
imgHeight() {
return this.height == 'auto' ? 'auto' : String(this.height).indexOf('%') != -1 ? this.height : this.height + 'rpx';
return this.$u.addUnit(this.height);
}
},
created() {
......@@ -133,9 +133,18 @@
this.time = this.duration;
this.opacity = 1;
}, 30)
},
// 图片路径发生变化时,需要重新标记一些变量,否则会一直卡在某一个状态,比如isError
image(n) {
this.init();
}
},
methods: {
// 用于重新初始化
init() {
this.isError = false;
this.loadStatus = '';
},
// 点击图片触发的事件,loadlazy-还是懒加载中状态,loading-图片正在加载,loaded-图片加加载完成
clickImg() {
let whichImg = '';
......
<template>
<view class="u-loading-page">
</view>
</template>
<script>
export default {
props: {
},
data() {
return {
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
</style>
......@@ -221,7 +221,9 @@
goBack() {
// 如果自定义了点击返回按钮的函数,则执行,否则执行返回逻辑
if (typeof this.customBack === 'function') {
this.customBack();
// 在微信,支付宝等环境(H5正常),会导致父组件定义的customBack()函数体中的this变成子组件的this
// 通过bind()方法,绑定父组件的this,让this.customBack()的this为父组件的上下文
this.customBack.bind(this.$u.$parent.call(this))();
} else {
uni.navigateBack();
}
......
<template>
<view class="u-numberbox">
<view class="u-icon-minus" @touchstart.stop="btnTouchStart('minus')" @touchend.stop="clearTimer" :class="{ 'u-icon-disabled': disabled || inputVal <= min }"
<view class="u-icon-minus" @touchstart.stop.prevent="btnTouchStart('minus')" @touchend.stop.prevent="clearTimer" :class="{ 'u-icon-disabled': disabled || inputVal <= min }"
:style="{
background: bgColor,
height: inputHeight + 'rpx',
......@@ -17,7 +17,7 @@
height: inputHeight + 'rpx',
width: inputWidth + 'rpx'
}" />
<view class="u-icon-plus" @touchstart.stop="btnTouchStart('plus')" @touchend.stop="clearTimer" :class="{ 'u-icon-disabled': disabled || inputVal >= max }"
<view class="u-icon-plus" @touchstart.stop.prevent="btnTouchStart('plus')" @touchend.stop.prevent="clearTimer" :class="{ 'u-icon-disabled': disabled || inputVal >= max }"
:style="{
background: bgColor,
height: inputHeight + 'rpx',
......
......@@ -284,6 +284,9 @@ export default {
this.close();
},
close() {
// 标记关闭是内部发生的,否则修改了value值,导致watch中对value检测,导致再执行一遍close
// 造成@close事件触发两次
this.closeFromInner = true;
this.change('showDrawer', 'visibleSync', false);
},
// 中部弹出时,需要.u-drawer-content将居中内容,此元素会铺满屏幕,点击需要关闭弹窗
......@@ -300,9 +303,6 @@ export default {
change(param1, param2, status) {
// 如果this.popup为false,意味着为picker,actionsheet等组件调用了popup组件
if (this.popup == true) {
// 标记关闭是内部发生的,否则修改了value值,导致watch中对value检测,导致再执行一遍close
// 造成@close事件触发两次
this.closeFromInner = true;
this.$emit('input', status);
}
this[param1] = status;
......
......@@ -84,6 +84,11 @@
textIndent: {
type: String,
default: '2em'
},
// open和close事件时,将此参数返回在回调参数中
index: {
type: [Number, String],
default: ''
}
},
watch: {
......@@ -128,6 +133,8 @@
this.showMore = !this.showMore;
// 如果toggle为false,隐藏"收起"部分的内容
if (this.toggle == false) this.isLongContent = false;
// 发出打开或者收齐的事件
this.$emit(this.showMore ? 'open' : 'close', this.index);
}
}
};
......
......@@ -15,7 +15,7 @@
</view>
<view class="u-section__right-info" v-if="right" :style="{
color: subColor
}" @tap="rightClick">
}" @tap="rightClick">
{{subTitle}}
<view class="u-section__right-info__icon-arrow u-flex">
<u-icon name="arrow-right" size="24" :color="subColor"></u-icon>
......
......@@ -94,8 +94,16 @@
methods: {
// 查询各节点的信息
selecterQueryInfo() {
// 获取整个父组件容器的高度,当做骨架屏的高度
uni.createSelectorQuery().selectAll('.u-skeleton').boundingClientRect().exec((res) => {
// 获取整个父组件容器的高度,当做骨架屏的高度
// 在微信小程序中,如果把骨架屏放入组件中使用的话,需要调in(this)上下文为父组件才有效
let query = '';
// #ifdef MP-WEIXIN
query = uni.createSelectorQuery().in(this.$parent);
// #endif
// #ifndef MP-WEIXIN
query = uni.createSelectorQuery()
// #endif
query.selectAll('.u-skeleton').boundingClientRect().exec((res) => {
this.windowHeight = res[0][0].height;
this.windowWinth = res[0][0].width;
this.top = res[0][0].bottom - res[0][0].height;
......@@ -110,19 +118,43 @@
},
// 矩形元素列表
getRectEls() {
uni.createSelectorQuery().selectAll('.u-skeleton-rect').boundingClientRect().exec((res) => {
let query = '';
// 在微信小程序中,如果把骨架屏放入组件中使用的话,需要调in(this)上下文为父组件才有效
// #ifdef MP-WEIXIN
query = uni.createSelectorQuery().in(this.$parent);
// #endif
// #ifndef MP-WEIXIN
query = uni.createSelectorQuery()
// #endif
query.selectAll('.u-skeleton-rect').boundingClientRect().exec((res) => {
this.RectNodes = res[0];
});
},
// 圆角元素列表
getFilletEls() {
uni.createSelectorQuery().selectAll('.u-skeleton-fillet').boundingClientRect().exec((res) => {
let query = '';
// 在微信小程序中,如果把骨架屏放入组件中使用的话,需要调in(this)上下文为父组件才有效
// #ifdef MP-WEIXIN
query = uni.createSelectorQuery().in(this.$parent);
// #endif
// #ifndef MP-WEIXIN
query = uni.createSelectorQuery()
// #endif
query.selectAll('.u-skeleton-fillet').boundingClientRect().exec((res) => {
this.filletNodes = res[0];
});
},
// 圆形元素列表
getCircleEls() {
uni.createSelectorQuery().selectAll('.u-skeleton-circle').boundingClientRect().exec((res) => {
let query = '';
// 在微信小程序中,如果把骨架屏放入组件中使用的话,需要调in(this)上下文为父组件才有效
// #ifdef MP-WEIXIN
query = uni.createSelectorQuery().in(this.$parent);
// #endif
// #ifndef MP-WEIXIN
query = uni.createSelectorQuery()
// #endif
query.selectAll('.u-skeleton-circle').boundingClientRect().exec((res) => {
this.circleNodes = res[0];
});
}
......
......@@ -141,6 +141,9 @@
const observer = this[observerName];
observer && observer.disconnect();
},
},
beforeDestroy() {
this.disconnectObserver('contentObserver');
}
};
</script>
......
......@@ -174,7 +174,9 @@
async clickHandler(index) {
if(this.beforeSwitch && typeof(this.beforeSwitch) === 'function') {
// 执行回调,同时传入索引当作参数
let beforeSwitch = this.beforeSwitch(index);
// 在微信,支付宝等环境(H5正常),会导致父组件定义的customBack()函数体中的this变成子组件的this
// 通过bind()方法,绑定父组件的this,让this.customBack()的this为父组件的上下文
let beforeSwitch = this.beforeSwitch.bind(this.$u.$parent.call(this))(index);
// 判断是否返回了promise
if (!!beforeSwitch && typeof beforeSwitch.then === 'function') {
await beforeSwitch.then(res => {
......
......@@ -359,11 +359,6 @@ export default {
this.$emit('on-uploaded', this.lists);
return;
}
// 检查上传地址
if (!this.action) {
this.showToast('请配置上传地址', true);
return;
}
// 检查是否是已上传或者正在上传中
if (this.lists[index].progress == 100) {
if (this.autoUpload == false) this.uploadFile(index + 1);
......@@ -372,7 +367,12 @@ export default {
// 执行before-upload钩子
if(this.beforeUpload && typeof(this.beforeUpload) === 'function') {
// 执行回调,同时传入索引和文件列表当作参数
let beforeResponse = this.beforeUpload(index, this.lists);
// 在微信,支付宝等环境(H5正常),会导致父组件定义的customBack()函数体中的this变成子组件的this
// 通过bind()方法,绑定父组件的this,让this.customBack()的this为父组件的上下文
// 因为upload组件可能会被嵌套在其他组件内,比如u-form,这时this.$parent其实为u-form的this,
// 非页面的this,所以这里需要往上历遍,一直寻找到最顶端的$parent,这里用了this.$u.$parent.call(this)
// 明白意思即可,无需纠结this.$u.$parent.call(this)的细节
let beforeResponse = this.beforeUpload.bind(this.$u.$parent.call(this))(index, this.lists);
// 判断是否返回了promise
if (!!beforeResponse && typeof beforeResponse.then === 'function') {
await beforeResponse.then(res => {
......@@ -386,6 +386,11 @@ export default {
return this.uploadFile(index + 1);
}
}
// 检查上传地址
if (!this.action) {
this.showToast('请配置上传地址', true);
return;
}
this.lists[index].error = false;
this.uploading = true;
// 创建上传对象
......@@ -398,7 +403,7 @@ export default {
success: res => {
// 判断是否json字符串,将其转为json格式
let data = this.toJson && this.$u.test.jsonString(res.data) ? JSON.parse(res.data) : res.data;
if (![200, 201].includes(res.statusCode)) {
if (![200, 201, 204].includes(res.statusCode)) {
this.uploadError(index, data);
} else {
// 上传成功
......
This diff is collapsed.
......@@ -60,6 +60,14 @@ import toast from './libs/function/toast.js'
import getParent from './libs/function/getParent.js'
// 获取整个父组件
import $parent from './libs/function/$parent.js'
// 获取sys()和os()工具方法
// 获取设备信息,挂载到$u的sys()(system的缩写)属性中,
// 同时把安卓和ios平台的名称"ios"和"android"挂到$u.os()中,方便取用
import {sys, os} from './libs/function/sys.js'
// 防抖方法
import debounce from './libs/function/debounce.js'
// 节流方法
import throttle from './libs/function/throttle.js'
// 配置信息
......@@ -76,6 +84,8 @@ const $u = {
colorGradient: colorGradient.colorGradient,
guid,
color,
sys,
os,
type2icon,
randomArray,
wranning,
......@@ -97,7 +107,9 @@ const $u = {
http,
toast,
config, // uView配置信息相关,比如版本号
zIndex
zIndex,
debounce,
throttle,
}
const install = Vue => {
......@@ -117,10 +129,6 @@ const install = Vue => {
Vue.filter('timeFrom', (timestamp, format) => {
return timeFrom(timestamp, format)
})
// 获取设备信息,挂载到$u的sys(system的缩写)属性中,
// 同时把安卓和ios平台的名称"ios"和"android"挂到$u.os中,方便取用
$u.sys = uni.getSystemInfoSync();
$u.os = $u.sys.platform;
Vue.prototype.$u = $u
}
......
// 此版本发布于2020-07-29
let version = '1.5.7';
// 此版本发布于2020-08-04
let version = '1.5.8';
export default {
v: version,
......
......@@ -12,8 +12,6 @@
/* #ifndef APP-NVUE */
image {
display: inline-block;
// 解决图片加载时可能会瞬间变形的问题
will-change: transform;
}
// 在weex,也即nvue中,所有元素默认为border-box
......
// 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法
// this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx
export default function $parent(name, keys) {
// 这里默认值等于undefined有它的含义,因为最顶层元素(组件)的$parent就是undefined,意味着不传name
// 值(默认为undefined),就是查找最顶层的$parent
export default function $parent(name = undefined) {
let parent = this.$parent;
// 通过while历遍,这里主要是为了H5需要多层解析的问题
while (parent) {
// 父组件
if (parent.$options.name !== name) {
if (parent.$options && parent.$options.name !== name) {
// 如果组件的name不相等,继续上一级寻找
parent = parent.$parent;
} else {
......
let timeout = null;
/**
* 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
*
* @param {Function} func 要执行的回调函数
* @param {Number} wait 延时的时间
* @param {Boolean} immediate 是否立即执行
* @return null
*/
function debounce(func, wait = 500, immediate = false) {
// 清除定时器
if (timeout !== null) clearTimeout(timeout);
// 立即执行,此类情况一般用不到
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(function() {
timeout = null;
}, wait);
if (callNow) typeof func === 'function' && func();
} else {
// 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
timeout = setTimeout(function() {
typeof func === 'function' && func();
}, wait);
}
}
export default debounce
export function os() {
return uni.getSystemInfoSync().platform;
};
export function sys() {
return uni.getSystemInfoSync();
}
let timer, flag;
/**
* 节流原理:在一定时间内,只能触发一次
*
* @param {Function} func 要执行的回调函数
* @param {Number} wait 延时的时间
* @param {Boolean} immediate 是否立即执行
* @return null
*/
function throttle(func, wait = 500, immediate = true) {
if (immediate) {
if (!flag) {
flag = true;
// 如果是立即执行,则在wait毫秒内开始时执行
typeof func === 'function' && func();
timer = setTimeout(() => {
flag = false;
}, wait);
}
} else {
if (!flag) {
flag = true
// 如果是非立即执行,则在wait毫秒内的结束处执行
timer = setTimeout(() => {
flag = false
typeof func === 'function' && func();
}, wait);
}
}
};
export default throttle
// padStart 的 polyfill,因为某些机型或情况,还无法支持es7的padStart,比如电脑版的微信小程序
// 所以这里做一个兼容polyfill的兼容处理
if (!String.prototype.padStart){
String.prototype.padStart =
// 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解
function(maxLength, fillString = ' ') {
if (Object.prototype.toString.call(fillString) !== "[object String]") throw new TypeError('fillString must be String')
let str = this
// 返回 String(str) 这里是为了使返回的值是字符串字面量,在控制台中更符合直觉
if (str.length >= maxLength) return String(str)
let fillLength = maxLength - str.length,
times = Math.ceil(fillLength / fillString.length)
while (times >>= 1) {
fillString += fillString
if (times === 1) {
fillString += fillString
}
}
return fillString.slice(0, fillLength) + str;
}
}
function timeFormat(timestamp = null, fmt = 'yyyy-mm-dd') {
// 其他更多是格式化有如下:
// yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合
......@@ -20,6 +43,7 @@ function timeFormat(timestamp = null, fmt = 'yyyy-mm-dd') {
for (let k in opt) {
ret = new RegExp("(" + k + ")").exec(fmt);
if (ret) {
console.log(k, ret, opt[k]);
fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
};
};
......
{
"name": "uview-ui",
"version": "1.5.7",
"version": "1.5.8",
"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