Browse Source

1、更换uview-ui至最新版本
2、首页轮播图,菜单(未从后台获取),资讯(未跳转详情)
3、登录&注册功能完善

qzyReal 1 year ago
parent
commit
939670b5a6
100 changed files with 1103 additions and 5499 deletions
  1. 3 2
      App.vue
  2. 21 11
      apis/api.js
  3. 71 23
      pages.json
  4. 171 5
      pages/index/index.vue
  5. 2 8
      pages/login/chooseRole.vue
  6. 35 46
      pages/login/login.vue
  7. 75 78
      pages/login/register.vue
  8. 8 0
      pages/message/MessageIndex.vue
  9. 30 0
      pages/order/OrderIndex.vue
  10. BIN
      static/home-icon-01.png
  11. BIN
      static/home-icon-02.png
  12. BIN
      static/home-icon-03.png
  13. BIN
      static/home-icon-04.png
  14. BIN
      static/home-icon-05.png
  15. BIN
      static/home-icon-06.jpg
  16. BIN
      static/home-icon-07.jpg
  17. BIN
      static/home-icon-charge.png
  18. BIN
      static/icon/home-icon-select.png
  19. BIN
      static/icon/home-icon.png
  20. 0 0
      static/icon/login-bg.png
  21. BIN
      static/icon/message-icon-select.png
  22. BIN
      static/icon/message-icon.png
  23. 0 0
      static/icon/noData.png
  24. BIN
      static/icon/order-icon-select.png
  25. BIN
      static/icon/order-icon.png
  26. BIN
      static/icon/person-icon-select.png
  27. BIN
      static/icon/person-icon.png
  28. 0 0
      static/icon/user.png
  29. BIN
      static/logo.png
  30. BIN
      static/qrcode.png
  31. BIN
      static/slider-verify/1.jpg
  32. BIN
      static/slider-verify/2.jpg
  33. BIN
      static/slider-verify/3.jpg
  34. BIN
      static/slider-verify/4.jpg
  35. BIN
      static/slider-verify/5.jpg
  36. BIN
      static/slider-verify/icon-button-normal.png
  37. 2 2
      utils/request.js
  38. 2 2
      uview-ui/LICENSE
  39. 36 74
      uview-ui/README.md
  40. 140 0
      uview-ui/changelog.md
  41. 2 1
      uview-ui/components/u--input/u--input.vue
  42. 1 0
      uview-ui/components/u--text/u--text.vue
  43. 1 0
      uview-ui/components/u--textarea/u--textarea.vue
  44. 8 5
      uview-ui/components/u-action-sheet/u-action-sheet.vue
  45. 0 256
      uview-ui/components/u-alert-tips/u-alert-tips.vue
  46. 0 290
      uview-ui/components/u-avatar-cropper/u-avatar-cropper.vue
  47. 0 1265
      uview-ui/components/u-avatar-cropper/weCropper.js
  48. 4 0
      uview-ui/components/u-avatar/u-avatar.vue
  49. 2 2
      uview-ui/components/u-button/u-button.vue
  50. 4 3
      uview-ui/components/u-calendar/u-calendar.vue
  51. 0 299
      uview-ui/components/u-card/u-card.vue
  52. 0 316
      uview-ui/components/u-cell-item/u-cell-item.vue
  53. 0 5
      uview-ui/components/u-cell/props.js
  54. 0 1
      uview-ui/components/u-cell/u-cell.vue
  55. 0 147
      uview-ui/components/u-circle-progress/u-line-progress/u-line-progress.vue
  56. 5 0
      uview-ui/components/u-code-input/props.js
  57. 40 1
      uview-ui/components/u-code-input/u-code-input.vue
  58. 4 4
      uview-ui/components/u-code/u-code.vue
  59. 5 2
      uview-ui/components/u-col/u-col.vue
  60. 28 9
      uview-ui/components/u-datetime-picker/u-datetime-picker.vue
  61. 120 139
      uview-ui/components/u-dropdown-item/u-dropdown-item.vue
  62. 116 116
      uview-ui/components/u-dropdown/u-dropdown.vue
  63. 0 384
      uview-ui/components/u-field/u-field.vue
  64. 9 0
      uview-ui/components/u-form-item/props.js
  65. 3 2
      uview-ui/components/u-form-item/u-form-item.vue
  66. 8 7
      uview-ui/components/u-form/u-form.vue
  67. 0 52
      uview-ui/components/u-full-screen/u-full-screen.vue
  68. 12 4
      uview-ui/components/u-image/u-image.vue
  69. 2 2
      uview-ui/components/u-index-list/u-index-list.vue
  70. 5 0
      uview-ui/components/u-input/props.js
  71. 3 4
      uview-ui/components/u-input/u-input.vue
  72. 0 57
      uview-ui/components/u-lazy-load/u-lazy-load.vue
  73. 1 1
      uview-ui/components/u-line/props.js
  74. 2 4
      uview-ui/components/u-list/u-list.vue
  75. 5 0
      uview-ui/components/u-loading-page/props.js
  76. 6 1
      uview-ui/components/u-loading-page/u-loading-page.vue
  77. 0 103
      uview-ui/components/u-loading/u-loading.vue
  78. 15 1
      uview-ui/components/u-loadmore/props.js
  79. 9 4
      uview-ui/components/u-loadmore/u-loadmore.vue
  80. 0 123
      uview-ui/components/u-mask/u-mask.vue
  81. 0 311
      uview-ui/components/u-message-input/u-message-input.vue
  82. 2 2
      uview-ui/components/u-modal/u-modal.vue
  83. 5 0
      uview-ui/components/u-navbar/props.js
  84. 6 5
      uview-ui/components/u-navbar/u-navbar.vue
  85. 1 0
      uview-ui/components/u-no-network/u-no-network.vue
  86. 0 100
      uview-ui/components/u-parse/libs/CssHandler.js
  87. 0 580
      uview-ui/components/u-parse/libs/MpHtmlParser.js
  88. 0 80
      uview-ui/components/u-parse/libs/config.js
  89. 0 22
      uview-ui/components/u-parse/libs/handler.wxs
  90. 0 505
      uview-ui/components/u-parse/libs/trees.vue
  91. 3 3
      uview-ui/components/u-parse/node/node.vue
  92. 6 6
      uview-ui/components/u-picker/props.js
  93. 3 2
      uview-ui/components/u-picker/u-picker.vue
  94. 6 3
      uview-ui/components/u-popup/u-popup.vue
  95. 11 9
      uview-ui/components/u-radio/u-radio.vue
  96. 5 0
      uview-ui/components/u-rate/props.js
  97. 6 3
      uview-ui/components/u-rate/u-rate.vue
  98. 29 5
      uview-ui/components/u-row-notice/u-row-notice.vue
  99. 0 2
      uview-ui/components/u-scroll-list/u-scroll-list.vue
  100. 4 0
      uview-ui/components/u-search/props.js

+ 3 - 2
App.vue

@@ -22,9 +22,10 @@
 	
 	//全局页面背景色
 	page{
-		// background-color: #f7f7f7;
+		background-color: #e2e2e2;
+		font-family: '宋体';
 	}
-	
+
 	// 点击时背景灰色
 	// .hover-class{
 	// 	background-color: #f7f7f7!important;

+ 21 - 11
apis/api.js

@@ -1,15 +1,25 @@
 import ajax from '../utils/request.js'
 
-const netServe =  {
-	doLogin(data) { return ajax.postForm('/api/doLogin', data)}, 
-	// doRefister(data) { return ajax.postJson('/sp-home/AppUser/register', data) }
-	// doRefister: (params = {}) => ajax.postJson('/sp-home/AppUser/register', params),
-}
-
 
 export default {
-    doLogin(data) {
-        return ajax.postForm('/sp-admin/app/AppUser/login', data)
-    },
-	// netServe
-}
+	//登录
+	doLogin(data) {
+		return ajax.postForm('/sp-admin/app/AppUser/login', data)
+	},
+	//获取注册手机验证码
+	getPhoneSmsCode() {
+		return ajax.get('/sp-admin/app/AppUser/getPhoneSmsCode')
+	},
+	//注册
+	doRefister(data) {
+		return ajax.postJson('/sp-admin/app/AppUser/register', data)
+	},
+	//获取轮播图
+	getBannerList() {
+		return ajax.get('/level-one-server/app/TbBanner/getList')
+	},
+	//获取最新资讯
+	getNewestList(data){
+		return ajax.get('/level-one-server/app/TbPortNews/getNewestList',data)
+	}
+}

+ 71 - 23
pages.json

@@ -26,22 +26,55 @@
 		}, {
 			"path": "pages/index/index",
 			"style": {
-				"navigationBarTitleText": "",
-				"enablePullDownRefresh": false
+				"navigationBarTitleText": "首页",
+				"app-plus": {
+					"titleNView": {
+						"backgroundColor": "#ff4200",
+						"titleColor": "#fff"
+					}
+				}
 			}
 
+		},
+		{
+			"path": "pages/order/OrderIndex",
+			"style": {
+				"navigationBarTitleText": "订单中心",
+				"app-plus": {
+					"titleNView": {
+						"backgroundColor": "#ff4200",
+						"titleColor": "#fff"
+					}
+				}
+			}
+		},
+		{
+			"path": "pages/message/MessageIndex",
+			"style": {
+				"navigationBarTitleText": "消息中心",
+				"app-plus": {
+					"titleNView": {
+						"backgroundColor": "#ff4200",
+						"titleColor": "#fff"
+					}
+				}
+			}
 		}
 
-	    ,{
-            "path" : "pages/personal/personal",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "",
-                "enablePullDownRefresh": false
-            }
-            
-        }
-    ],
+		, {
+			"path": "pages/personal/personal",
+			"style": {
+				"navigationBarTitleText": "个人中心",
+				"app-plus": {
+					"titleNView": {
+						"backgroundColor": "#ff4200",
+						"titleColor": "#fff"
+					}
+				}
+			}
+
+		}
+	],
 	"globalStyle": {
 		"navigationBarTextStyle": "white",
 		"navigationBarTitleText": "uni-app",
@@ -53,16 +86,31 @@
 		"selectedColor": "#3cc51f",
 		"borderStyle": "black",
 		"backgroundColor": "#ffffff",
-		"list": [{
-			"pagePath": "pages/index/index",
-			"iconPath": "static/image/icon_component.png",
-			"selectedIconPath": "static/image/icon_component_HL.png",
-			"text": "首页"
-		}, {
-			"pagePath": "pages/personal/personal",
-			"iconPath": "static/image/icon_API.png",
-			"selectedIconPath": "static/image/icon_API_HL.png",
-			"text": "我的"
-		}]
+		"list": [
+			{
+				"pagePath": "pages/index/index",
+				"iconPath": "static/icon/home-icon.png",
+				"selectedIconPath": "static/icon/home-icon-select.png",
+				"text": "首页"
+			},
+			{
+				"pagePath": "pages/order/OrderIndex",
+				"iconPath": "static/icon/order-icon.png",
+				"selectedIconPath": "static/icon/order-icon-select.png",
+				"text": "订单"
+			},
+			{
+				"pagePath": "pages/message/MessageIndex",
+				"iconPath": "static/icon/message-icon.png",
+				"selectedIconPath": "static/icon/message-icon-select.png",
+				"text": "消息"
+			},
+			{
+				"pagePath": "pages/personal/personal",
+				"iconPath": "static/icon/person-icon.png",
+				"selectedIconPath": "static/icon/person-icon-select.png",
+				"text": "个人中心"
+			}
+		]
 	}
 }

+ 171 - 5
pages/index/index.vue

@@ -1,6 +1,76 @@
 <template>
 	<view>
-		
+		<view class="wrap">
+			<u-swiper :list="bannerList" keyName="image" img-mode="scaleToFill" :effect3d="true"></u-swiper>
+		</view>
+		<view class="box menu-box">
+			<view class="menu-item">
+				<view class="menu-img">
+					<image src="../../static/icon/user.png"></image>
+				</view>
+				<view class="menu-text">购买确认</view>
+			</view>
+			<view class="menu-item">
+				<view class="menu-img">
+					<image src="../../static/icon/user.png"></image>
+				</view>
+				<view class="menu-text">购买确认确</view>
+			</view>
+			<view class="menu-item">
+				<view class="menu-img">
+					<image src="../../static/icon/user.png"></image>
+				</view>
+				<view class="menu-text">购买确认确</view>
+			</view>
+			<view class="menu-item">
+				<view class="menu-img">
+					<image src="../../static/icon/user.png"></image>
+				</view>
+				<view class="menu-text">购买确认确</view>
+			</view>
+			<view class="menu-item">
+				<view class="menu-img">
+					<image src="../../static/icon/user.png"></image>
+				</view>
+				<view class="menu-text">购买确认确</view>
+			</view>
+			<view class="menu-item">
+				<view class="menu-img">
+					<image src="../../static/icon/user.png"></image>
+				</view>
+				<view class="menu-text">购买确认确</view>
+			</view>
+			<view class="menu-item">
+				<view class="menu-img">
+					<image src="../../static/icon/user.png"></image>
+				</view>
+				<view class="menu-text">购买确认确</view>
+			</view>
+			<view class="menu-item">
+				<view class="menu-img">
+					<image src="../../static/icon/user.png"></image>
+				</view>
+				<view class="menu-text">购买确认确</view>
+			</view>
+		</view>
+		<view class="box msg-box">
+			<view class="title">
+				<u-icon name="calendar" color="#ff0000" size="28"></u-icon>
+				<text>最新资讯</text>
+			</view>
+			<view class="news-box" v-for="(item,index) in newsList">
+				<view class="news-img">
+					<image src="https://www.leezon.net/uploads/news/20200314160130384800.jpg"></image>
+				</view>
+				<view class="news-item">
+					<view class="new-title">{{item.title}}</view>
+					<view class="news-notice">
+						<view style="flex: 1;display: flex;"><u-icon name="eye-fill"></u-icon>12</view>
+						<view style="flex: 3;text-align: right;">2023-12-34 22:00:00</view>
+					</view>
+				</view>
+			</view>
+		</view>
 	</view>
 </template>
 
@@ -8,15 +78,111 @@
 	export default {
 		data() {
 			return {
-				
+				bannerList: [],
+				newsList: []
 			}
 		},
+		onLoad() {
+			this.getBannerList();
+			this.getNewsList();
+		},
 		methods: {
-			
+			getBannerList() {
+				this.$api.getBannerList().then(resp => {
+					this.bannerList = resp.data;
+				})
+			},
+			getNewsList() {
+				this.$api.getNewestList({
+					limit: 4
+				}).then(resp => {
+					this.newsList = resp.data;
+				})
+			}
+
 		}
 	}
 </script>
 
-<style>
+<style scoped lang="scss">
+	.wrap {
+		padding: 10rpx;
+	}
+
+	.menu-box {
+		height: 300rpx;
+		display: flex;
+		flex-wrap: wrap;
+		gap: 20rpx 40rpx;
+
+		.menu-item {
+			width: 128rpx;
+			height: 128rpx;
+			position: relative;
+			text-align: center;
+
+			.menu-img {
+				image {
+					height: 64rpx;
+					width: 64rpx;
+				}
+			}
+
+			.menu-text {
+				font-size: 16rpx;
+			}
+		}
+	}
+
+	.box {
+		padding: 20rpx 40rpx;
+		width: 90%;
+		margin: auto;
+		background: #fff;
+		border-radius: 30rpx;
+	}
 
-</style>
+	.msg-box {
+		height: 600rpx;
+		margin-top: 10rpx;
+
+		.title {
+			font-size: 30rpx;
+			line-height: 60rpx;
+			display: flex;
+			width: 30%;
+			border-bottom: 1px solid #e2e2e2;
+
+		}
+	}
+
+	.news-box {
+		margin-top: 20rpx;
+		display: flex;
+		height: 140rpx;
+		widows: 100vw;
+		padding-bottom: 20rpx;
+		border-bottom: 1px solid #e2e2e2;
+		.news-img image {
+			width: 140rpx;
+			height: 100%;
+		}
+
+		.news-item {
+			width: 100vw;
+			word-break: break-all;
+			.new-title {
+				font-size: 28rpx;
+				padding: 10rpx 20rpx;
+			}
+
+			.news-notice {
+				display: flex;
+				font-size: 28rpx;
+				color: #9e9b9b;
+				padding: 20rpx 20rpx 0 20rpx;
+			}
+		}
+
+	}
+</style>

+ 2 - 8
pages/login/chooseRole.vue

@@ -19,7 +19,7 @@
 				</u-row>
 			</u-list-item>
 		</u-list>
-		<u-button type="error" shape="circle" text="下一步" @click="next()"></u-button>
+		<!-- <u-button type="error" shape="circle" text="下一步" @click="next()"></u-button> -->
 	</view>
 </template>
 
@@ -58,13 +58,7 @@
 		},
 		methods: {
 			choose(data) {
-				console.log("选择角色");
-				console.log(data);
-				for (let i = 0; i < this.roles.length; i++) {
-					if (this.roles[i].name === data.name) {
-						this.current = i;
-					}
-				}
+				this.$common.to('/pages/login/register?type='+data.id);
 			},
 			next(){
 				uni.navigateTo({

+ 35 - 46
pages/login/login.vue

@@ -1,8 +1,7 @@
 <template>
 	<view>
 		<view class="remain">
-			<h1>欢迎回来</h1>
-			<view class="wel">请登录您的账号</view>
+			<h1>账号登录</h1>
 		</view>
 		<view class="form">
 			<u-form :model="form" ref="uForm" label-width="100px" label-position="top">
@@ -20,15 +19,16 @@
 			</u-form>
 			<view style="font-size: 13px;">忘记密码?</view>
 			<view class="btn">
-				<view style="margin-bottom: 10px;">
-					<u-radio-group v-model="value" :wrap="true">
-						<u-radio :label="radioLabel"></u-radio>
-					</u-radio-group>
+				<view style="margin-bottom: 20rpx;font-size: 28rpx;">
+					<u-checkbox-group v-model="value" :wrap="true">
+						<u-checkbox name="1"></u-checkbox>登录同意<text class="blue-class">《用户协议》</text>和<text
+							class="blue-class">《隐私政策》</text>
+					</u-checkbox-group>
 				</view>
 				<view>
 					<u-button type="error" shape="circle" text="登录" @click="submit()"></u-button>
 				</view>
-				<view class="tip" @click="toRegister()">还没有账号?马上注册</view>
+				<view class="tip" @click="toRegister()">还没有账号?马上<text class="register_btn blue-class">注册</text></view>
 			</view>
 
 		</view>
@@ -68,58 +68,35 @@
 						trigger: 'blur,change'
 					}]
 				},
-				radioLabel: "登录同意《用户协议》和《隐私政策》",
-				value: '',
+				radioLabel: "",
+				value: ["1"],
 			}
 		},
 		onReady() {
 			this.$refs.uForm.setRules(this.rules);
 		},
 		methods: {
-			loginFn() {
-				if (!this.form.key) {
-					this.$common.toast('请输入登录名');
-					return;
-				}
-				if (!this.form.password) {
-					this.$common.toast('请输入密码');
-					return;
-				}
-				let openid = uni.getStorageSync('openid');
-				if (!openid) {
-					openid = uni.getStorageSync('login_openid');
-				}
-				this.form.openid = openid
-				this.$api.doLogin(this.form).then(resp => {
-					let data = resp.data;
-				})
-			},
 			submit() {
-				
 				this.$refs.uForm.validate().then(res => {
+					let value = this.value;
+					if (value.length == 0) {
+						this.$common.toast('请先同意协议');
+						return;
+					}
 					this.$api.doLogin(this.form).then(resp => {
-						console.log(resp)
-						let data = resp.data;
-						if(resp.code==200){
+						if (resp.code == 200) {
 							let data = resp.data;
-							uni.$u.toast('登录成功,欢迎你'+data.appUser.name)
-							localStorage.setItem('token',data.tokenInfo.tokenValue)
-							uni.navigateTo({
-								url: '/pages/login/chooseRole'
-							});
+							uni.setStorageSync('token', data.tokenInfo.tokenValue);
+							uni.setStorageSync('info',data.appUser)
+							this.$common.toBar('/pages/index/index')
 						}
 					})
 				}).catch(errors => {
 					uni.$u.toast('校验失败')
 				})
 			},
-			radioChange() {
-				console.log("1111")
-			},
 			toRegister() {
-				uni.navigateTo({
-					url: '/pages/login/register'
-				});
+				this.$common.to('/pages/login/chooseRole')
 			}
 		}
 	}
@@ -132,7 +109,7 @@
 	}
 
 	.remain {
-		margin: 40px 50px 0;
+		margin: 30rpx 150rpx 0;
 		text-align: center;
 	}
 
@@ -150,9 +127,10 @@
 
 	.form-input {
 		width: 100%;
-		background-color: #E8E8E8;
-		border-radius: 5px;
-		margin-top: 5px;
+		background-color: #f5f5f5;
+		margin-top: 10rpx;
+		border-radius: 20rpx;
+		border: none;
 	}
 
 	.btn {
@@ -164,4 +142,15 @@
 		text-align: center;
 		font-size: 14px;
 	}
+
+	.blue-class {
+		color: #55aaff;
+		cursor: pointer;
+	}
+
+	.register_btn {
+
+		text-decoration: underline;
+		margin-left: 0.5em;
+	}
 </style>

+ 75 - 78
pages/login/register.vue

@@ -2,8 +2,7 @@
 	<view>
 		<navigation-bar background-color="#fff" front-color="#000000" />
 		<view class="remain">
-			<h1>欢迎注册</h1>
-			<view class="wel">请注册您的账号</view>
+			<h1>账号注册</h1>
 		</view>
 		<view class="form">
 			<u-form :model="form" ref="uForm" label-width="100px" label-position="top">
@@ -13,35 +12,13 @@
 							placeholder='请输入手机号码' :clearable='false' />
 					</view>
 				</u-form-item>
-				<u-form-item label="选择你的身份" prop="type">
-					<view class="form-input" @click="show=true" >
-						<u-input v-model="form.type" type="text"
-							placeholder='请选择你的身份' :clearable='false' disabled />
-					<u-picker :show="show" :columns="columns" @confirm="confirm" @change="changeHandler"></u-picker>
-					</view>
-				</u-form-item>
 				<u-form-item label="验证码" prop="smsCode">
 					<view class="form-input">
-						<view class="u-demo-block__content">
-							<!-- 注意:由于兼容性差异,如果需要使用前后插槽,nvue下需使用u--input,非nvue下需使用u-input -->
-							<!-- #ifndef APP-NVUE -->
-							<u-input placeholder="请输入验证码">
-								<!-- #endif -->
-								<!-- #ifdef APP-NVUE -->
-								<u--input placeholder="请输入验证码">
-									<!-- #endif -->
-									<template slot="suffix">
-										<u-code ref="uCode" @change="codeChange" seconds="20"
-											changeText="X秒重新获取哈哈哈"></u-code>
-										<u-button @tap="getCode" :text="tips" type="error" size="mini"></u-button>
-									</template>
-									<!-- #ifndef APP-NVUE -->
-							</u-input>
-							<!-- #endif -->
-							<!-- #ifdef APP-NVUE -->
-							</u--input>
-							<!-- #endif -->
-						</view>
+						<u-input placeholder="请输入验证码" v-model="form.smsCode">
+							<template slot="suffix">
+								<span class="code" @click="getCode">{{code}}</span>
+							</template>
+						</u-input>
 					</view>
 				</u-form-item>
 				<u-form-item label="密码" prop="password">
@@ -55,17 +32,18 @@
 					</view>
 				</u-form-item>
 			</u-form>
-			<view style="font-size: 13px;">忘记密码?</view>
 			<view class="btn">
-				<view style="margin-bottom: 10px;">
-					<u-radio-group v-model="value" :wrap="true">
-						<u-radio :label="radioLabel"></u-radio>
-					</u-radio-group>
+				<view style="margin-bottom: 20rpx;font-size: 28rpx;">
+					<u-checkbox-group v-model="value" :wrap="true">
+						<u-checkbox name="1"></u-checkbox>注册同意<text class="blue-class">《用户协议》</text>和<text
+							class="blue-class">《隐私政策》</text>
+					</u-checkbox-group>
 				</view>
 				<view>
 					<u-button type="error" shape="circle" text="注册" @click="submit()"></u-button>
 				</view>
-				<view class="tip" @click="toLogin()">已有账号,去登录</view>
+				<view class="tip" @click="toLogin()">已有账号,去<text class="blue-class"
+						style="margin-left: 10rpx;">登录</text></view>
 			</view>
 
 		</view>
@@ -75,13 +53,18 @@
 <script>
 	export default {
 		data() {
+			const passwordValid = (rule, value, callback) => {
+				value == this.form.password ? callback() : callback(new Error('两次输入密码不一致'))
+			};
 			return {
+				time: 60,
+				code: '获取验证码',
+				value: ['1'],
 				form: {
 					phone: '',
 					smsCode: '',
 					password: '',
 					type: '',
-					nickName:'',
 					rePassword: '',
 				},
 				rules: {
@@ -102,44 +85,60 @@
 						required: true,
 						message: '请输入密码',
 						trigger: 'blur,change'
-					}]
+					}],
+					rePassword: [{
+						validator: passwordValid,
+						required: true,
+						trigger:'blur'
+
+					}],
 				},
-				radioLabel: "登录同意《用户协议》和《隐私政策》",
-				tips: '获取验证码',
-				value: '',
-				columns: [
-					// ['边民', '经销商', '外籍商户','司机']
-					[1,2,3,4]
-				],
-				show: false
 			}
 		},
 		onReady() {
 			this.$refs.uForm.setRules(this.rules);
 		},
+		onLoad(options) {
+			this.form.type = options.type;
+		},
 		methods: {
+			startCount() {
+				setTimeout(() => {
+					let time = this.time;
+					if (time == 0) {
+						this.code = '重新获取';
+						this.time = 60;
+						return;
+					}
+					this.time = --time;
+					this.code = time + '后重新获取';
+					this.startCount();
+				}, 1000)
+			},
 			getCode() {
-				if (this.$refs.uCode.canGetCode) {
-					// 模拟向后端请求验证码
-					uni.showLoading({
-						title: '正在获取验证码'
-					})
-					setTimeout(() => {
-						uni.hideLoading();
-						// 这里此提示会被this.start()方法中的提示覆盖
-						uni.$u.toast('验证码已发送');
-						// 通知验证码组件内部开始倒计时
-						this.$refs.uCode.start();
-					}, 2000);
-				} else {
-					uni.$u.toast('倒计时结束后再发送');
+				let time = this.time;
+				if (time > 0 && time < 60) {
+					return;
 				}
+				let phone = this.form.phone;
+				if (!this.$common.isPhone(phone)) {
+					this.$common.toast('请输入正确的手机号');
+					return;
+				}
+				this.startCount();
+				this.$api.getPhoneSmsCode().then(resp => {
+					this.$common.toast('已发送');
+				})
 			},
 			submit() {
 				this.$refs.uForm.validate().then(res => {
+					let value = this.value;
+					if (value.length == 0) {
+						this.$common.toast('请先同意协议');
+						return;
+					}
 					this.$api.doRefister(this.form).then(res => {
-						console.log(res)
-						if(res.code==200){
+						if (res.code == 200) {
 							uni.$u.toast('注册成功')
 							uni.navigateTo({
 								url: '/pages/login/login'
@@ -148,26 +147,13 @@
 					}).catch(err => {
 						console.log(err)
 					})
-				}).catch(errors => {
-					uni.$u.toast('注册失败')
-				})
-			},
-			radioChange() {
-				console.log("1111")
+				}).catch(errors => {})
 			},
 			toLogin() {
 				uni.navigateTo({
 					url: '/pages/login/login'
 				});
 			},
-			changeHandler(e){
-				console.log(e)
-				this.form.type=e.value[0]
-			},
-			confirm(e) {
-				// console.log(e)
-				this.show=false
-			}
 		}
 	}
 </script>
@@ -179,7 +165,7 @@
 	}
 
 	.remain {
-		margin: 50px 100px 0;
+		margin: 30rpx 150rpx 0;
 		text-align: center;
 	}
 
@@ -193,9 +179,10 @@
 
 	.form-input {
 		width: 100%;
-		background-color: #E8E8E8;
-		border-radius: 5px;
+		background-color: #f5f5f5;
 		margin-top: 5px;
+		border-radius: 20rpx;
+		border: none;
 	}
 
 	.btn {
@@ -207,4 +194,14 @@
 		text-align: center;
 		font-size: 14px;
 	}
+
+	.code {
+		color: red;
+		font-size: 13px;
+	}
+
+	.blue-class {
+		color: #55aaff;
+		cursor: pointer;
+	}
 </style>

+ 8 - 0
pages/message/MessageIndex.vue

@@ -0,0 +1,8 @@
+<template>
+</template>
+
+<script>
+</script>
+
+<style>
+</style>

+ 30 - 0
pages/order/OrderIndex.vue

@@ -0,0 +1,30 @@
+<template>
+	<view>
+		<u-tabs :list="list" :is-scroll="false" :current="current" @change="change"></u-tabs>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				list: [{
+					name: '全部'
+				}, {
+					name: '待确认'
+				}, {
+					name: '已取消'
+				}],
+				current: 0
+			}
+		},
+		onLoad() {},
+		methods: {
+
+
+		}
+	}
+</script>
+
+<style>
+</style>

BIN
static/home-icon-01.png


BIN
static/home-icon-02.png


BIN
static/home-icon-03.png


BIN
static/home-icon-04.png


BIN
static/home-icon-05.png


BIN
static/home-icon-06.jpg


BIN
static/home-icon-07.jpg


BIN
static/home-icon-charge.png


BIN
static/icon/home-icon-select.png


BIN
static/icon/home-icon.png


+ 0 - 0
static/login-bg.png → static/icon/login-bg.png


BIN
static/icon/message-icon-select.png


BIN
static/icon/message-icon.png


+ 0 - 0
static/noData.png → static/icon/noData.png


BIN
static/icon/order-icon-select.png


BIN
static/icon/order-icon.png


BIN
static/icon/person-icon-select.png


BIN
static/icon/person-icon.png


+ 0 - 0
static/user.png → static/icon/user.png


BIN
static/logo.png


BIN
static/qrcode.png


BIN
static/slider-verify/1.jpg


BIN
static/slider-verify/2.jpg


BIN
static/slider-verify/3.jpg


BIN
static/slider-verify/4.jpg


BIN
static/slider-verify/5.jpg


BIN
static/slider-verify/icon-button-normal.png


+ 2 - 2
utils/request.js

@@ -1,5 +1,5 @@
-// const server = 'http://127.0.0.1:8080';
-const server = 'http://192.168.88.34:8080';
+const server = 'http://127.0.0.1:8080';
+// const server = 'http://192.168.88.34:8080';
 
 
 

+ 2 - 2
uview-ui/LICENSE

@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2020 www.uviewui.com
+Copyright (c) 2023 www.uviewui.com
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+SOFTWARE.

+ 36 - 74
uview-ui/README.md

@@ -1,73 +1,56 @@
 <p align="center">
     <img alt="logo" src="https://uviewui.com/common/logo.png" width="120" height="120" style="margin-bottom: 10px;">
 </p>
-<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">uView</h3>
+<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">uView 2.0</h3>
 <h3 align="center">多平台快速开发的UI框架</h3>
 
+[![stars](https://img.shields.io/github/stars/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
+[![forks](https://img.shields.io/github/forks/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
+[![issues](https://img.shields.io/github/issues/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0/issues)
+[![Website](https://img.shields.io/badge/uView-up-blue?style=flat-square)](https://uviewui.com)
+[![release](https://img.shields.io/github/v/release/umicro/uView2.0?style=flat-square)](https://gitee.com/umicro/uView2.0/releases)
+[![license](https://img.shields.io/github/license/umicro/uView2.0?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)
+
 ## 说明
 
-uView UI,是[uni-app](https://uniapp.dcloud.io/)生态优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
+uView UI,是[uni-app](https://uniapp.dcloud.io/)全面兼容nvue的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
 
-## 特性
+## [官方文档:https://uviewui.com](https://uviewui.com)
 
-- 兼容安卓,iOS,微信小程序,H5,QQ小程序,百度小程序,支付宝小程序,头条小程序
-- 60+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用
-- 众多贴心的JS利器,让您飞镖在手,召之即来,百步穿杨
-- 众多的常用页面和布局,让您专注逻辑,事半功倍
-- 详尽的文档支持,现代化的演示效果
-- 按需引入,精简打包体积
 
+## 预览
 
-## 安装
+您可以通过**微信**扫码,查看最佳的演示效果。
+<br>
+<br>
+<img src="https://uviewui.com/common/weixin_mini_qrcode.png" width="220" height="220" >
 
-```bash
-# npm方式安装,插件市场导入无需执行此命令
-npm i uview-ui
-```
 
-## 快速上手
+## 链接
 
-1. `main.js`引入uView库
-```js
-// main.js
-import uView from 'uview-ui';
-Vue.use(uView);
-```
+- [官方文档](https://www.uviewui.com/)
+- [更新日志](https://www.uviewui.com/components/changelog.html)
+- [升级指南](https://www.uviewui.com/components/changeGuide.html)
+- [关于我们](https://www.uviewui.com/cooperation/about.html)
 
-2. `App.vue`引入基础样式(注意style标签需声明scss属性支持)
-```css
-/* App.vue */
-<style lang="scss">
-@import "uview-ui/index.scss";
-</style>
-```
+## 交流反馈
 
-3. `uni.scss`引入全局scss变量文件
-```css
-/* uni.scss */
-@import "uview-ui/theme.scss";
-```
+欢迎加入我们的QQ群交流反馈:[点此跳转](https://www.uviewui.com/components/addQQGroup.html)
 
-4. `pages.json`配置easycom规则(按需引入)
-
-```js
-// pages.json
-{
-	"easycom": {
-		// npm安装的方式不需要前面的"@/",下载安装的方式需要"@/"
-		// npm安装方式
-		"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
-		// 下载安装方式
-		// "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
-	},
-	// 此为本身已有的内容
-	"pages": [
-		// ......
-	]
-}
-```
+## 关于PR
+
+> 我们非常乐意接受各位的优质PR,但在此之前我希望您了解uView2.0是一个需要兼容多个平台的(小程序、h5、ios app、android app)包括nvue页面、vue页面。
+> 所以希望在您修复bug并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢!
+
+## 安装
+
+#### **uni-app插件市场链接** —— [https://ext.dcloud.net.cn/plugin?id=1593](https://ext.dcloud.net.cn/plugin?id=1593)
 
-请通过[快速上手](https://www.uviewui.com/components/quickstart.html)了解更详细的内容 
+请通过[官网安装文档](https://www.uviewui.com/components/install.html)了解更详细的内容
+
+## 快速上手
+
+请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容
 
 ## 使用方法
 配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
@@ -78,27 +61,6 @@ Vue.use(uView);
 </template>
 ```
 
-请通过[快速上手](https://www.uviewui.com/components/quickstart.html)了解更详细的内容 
-
-## 链接
-
-- [官方文档](https://www.uviewui.com/)
-- [更新日志](https://www.www.uviewui.com/components/changelog.html)
-- [升级指南](https://www.uviewui.com/components/changelog.html)
-- [关于我们](https://www.uviewui.com/cooperation/about.html)
-
-## 预览
-
-您可以通过**微信**扫码,查看最佳的演示效果。
-<br>
-<br>
-<img src="https://uviewui.com/common/weixin_mini_qrcode.png" width="220" height="220" >
-
-## 捐赠uView的研发
-
-uView文档和源码全部开源免费,如果您认为uView帮到了您的开发工作,您可以捐赠uView的研发工作,捐赠无门槛,哪怕是一杯可乐也好(相信这比打赏主播更有意义)。
-
-<img src="https://uviewui.com/common/alipay.png" width="220" ><img style="margin-left: 100px;" src="https://uviewui.com/common/wechat.png" width="220" >
-
 ## 版权信息
 uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。
+

+ 140 - 0
uview-ui/changelog.md

@@ -1,3 +1,143 @@
+## 2.0.36(2023-03-27)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 重构`deepClone` & `deepMerge`方法
+2. 其他优化
+## 2.0.34(2022-09-24)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. `u-input`、`u-textarea`增加`ignoreCompositionEvent`属性
+2. 修复`route`方法调用可能报错的问题
+3. 修复`u-no-network`组件`z-index`无效的问题
+4. 修复`textarea`组件在h5上confirmType=""报错的问题
+5. `u-rate`适配`nvue`
+6. 优化验证手机号码的正则表达式(根据工信部发布的《电信网编号计划(2017年版)》进行修改。)
+7. `form-item`添加`labelPosition`属性
+8. `u-calendar`修复`maxDate`设置为当前日期,并且当前时间大于08:00时无法显示日期列表的问题 (#724)
+9. `u-radio`增加一个默认插槽用于自定义修改label内容 (#680)
+10. 修复`timeFormat`函数在safari重的兼容性问题 (#664)
+## 2.0.33(2022-06-17)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复`loadmore`组件`lineColor`类型错误问题
+2. 修复`u-parse`组件`imgtap`、`linktap`不生效问题
+## 2.0.32(2022-06-16)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+1. `u-loadmore`新增自定义颜色、虚/实线
+2. 修复`u-swiper-action`组件部分平台不能上下滑动的问题
+3. 修复`u-list`回弹问题
+4. 修复`notice-bar`组件动画在低端安卓机可能会抖动的问题
+5. `u-loading-page`添加控制图标大小的属性`iconSize`
+6. 修复`u-tooltip`组件`color`参数不生效的问题
+7. 修复`u--input`组件使用`blur`事件输出为`undefined`的bug
+8. `u-code-input`组件新增键盘弹起时,是否自动上推页面参数`adjustPosition`
+9. 修复`image`组件`load`事件无回调对象问题
+10. 修复`button`组件`loadingSize`设置无效问题
+10. 其他修复
+## 2.0.31(2022-04-19)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复`upload`在`vue`页面上传成功后没有成功标志的问题
+2. 解决演示项目中微信小程序模拟上传图片一直出于上传中问题
+3. 修复`u-code-input`组件在`nvue`页面编译到`app`平台上光标异常问题(`app`去除此功能)
+4. 修复`actionSheet`组件标题关闭按钮点击事件名称错误的问题
+5. 其他修复
+## 2.0.30(2022-04-04)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. `u-rate`增加`readonly`属性
+2. `tabs`滑块支持设置背景图片
+3. 修复`u-subsection` `mode`为`subsection`时,滑块样式不正确的问题
+4. `u-code-input`添加光标效果动画
+5. 修复`popup`的`open`事件不触发
+6. 修复`u-flex-column`无效的问题
+7. 修复`u-datetime-picker`索引在特定场合异常问题
+8. 修复`u-datetime-picker`最小时间字符串模板错误问题
+9. `u-swiper`添加`m3u8`验证
+10. `u-swiper`修改判断image和video逻辑
+11. 修复`swiper`无法使用本地图片问题,增加`type`参数
+12. 修复`u-row-notice`格式错误问题
+13. 修复`u-switch`组件当`unit`为`rpx`时,`nodeStyle`消失的问题
+14. 修复`datetime-picker`组件`showToolbar`与`visibleItemCount`属性无效的问题
+15. 修复`upload`组件条件编译位置判断错误,导致`previewImage`属性设置为`false`时,整个组件都会被隐藏的问题
+16. 修复`u-checkbox-group`设置`shape`属性无效的问题
+17. 修复`u-upload`的`capture`传入字符串的时候不生效的问题
+18. 修复`u-action-sheet`组件,关闭事件逻辑错误的问题
+19. 修复`u-list`触顶事件的触发错误的问题
+20. 修复`u-text`只有手机号可拨打的问题
+21. 修复`u-textarea`不能换行的问题
+22. 其他修复
+## 2.0.29(2022-03-13)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复`u--text`组件设置`decoration`属性未生效的问题
+2. 修复`u-datetime-picker`使用`formatter`后返回值不正确
+3. 修复`u-datetime-picker` `intercept` 可能为undefined
+4. 修复已设置单位 uni..config.unit = 'rpx'时,线型指示器 `transform` 的位置翻倍,导致指示器超出宽度
+5. 修复mixin中bem方法生成的类名在支付宝和字节小程序中失效
+6. 修复默认值传值为空的时候,打开`u-datetime-picker`报错,不能选中第一列时间的bug
+7. 修复`u-datetime-picker`使用`formatter`后返回值不正确
+8. 修复`u-image`组件`loading`无效果的问题
+9. 修复`config.unit`属性设为`rpx`时,导航栏占用高度不足导致塌陷的问题
+10. 修复`u-datetime-picker`组件`itemHeight`无效问题
+11. 其他修复
+## 2.0.28(2022-02-22)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. search组件新增searchIconSize属性
+2. 兼容Safari/Webkit中传入时间格式如2022-02-17 12:00:56
+3. 修复text value.js 判断日期出format错误问题
+4. priceFormat格式化金额出现精度错误
+5. priceFormat在部分情况下出现精度损失问题
+6. 优化表单rules提示
+7. 修复avatar组件src为空时,展示状态不对
+8. 其他修复
+## 2.0.27(2022-01-28)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1.样式修复
+## 2.0.26(2022-01-28)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1.样式修复
+## 2.0.25(2022-01-27)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复text组件mode=price时,可能会导致精度错误的问题
+2. 添加$u.setConfig()方法,可设置uView内置的config, props, zIndex, color属性,详见:[修改uView内置配置方案](https://uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
+3. 优化form组件在errorType=toast时,如果输入错误页面会有抖动的问题
+4. 修复$u.addUnit()对配置默认单位可能无效的问题
+## 2.0.24(2022-01-25)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复swiper在current指定非0时缩放有误
+2. 修复u-icon添加stop属性的时候报错
+3. 优化遗留的通过正则判断rpx单位的问题
+4. 优化Layout布局 vue使用gutter时,会超出固定区域
+5. 优化search组件高度单位问题(rpx -> px)
+6. 修复u-image slot 加载和错误的图片失去了高度
+7. 修复u-index-list中footer插槽与header插槽存在性判断错误
+8. 修复部分机型下u-popup关闭时会闪烁
+9. 修复u-image在nvue-app下失去宽高
+10. 修复u-popup运行报错
+11. 修复u-tooltip报错
+12. 修复box-sizing在app下的警告
+13. 修复u-navbar在小程序中报运行时错误
+14. 其他修复
+## 2.0.23(2022-01-24)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复image组件在hx3.3.9的nvue下可能会显示异常的问题
+2. 修复col组件gutter参数带rpx单位处理不正确的问题
+3. 修复text组件单行时无法显示省略号的问题
+4. navbar添加titleStyle参数
+5. 升级到hx3.3.9可消除nvue下控制台样式警告的问题
+## 2.0.22(2022-01-19)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. $u.page()方法优化,避免在特殊场景可能报错的问题
+2. picker组件添加immediateChange参数
+3. 新增$u.pages()方法
 ## 2.0.21(2022-01-19)
 # uView2.0重磅发布,利剑出鞘,一统江湖
 

+ 2 - 1
uview-ui/components/u--input/u--input.vue

@@ -35,8 +35,9 @@
 		:shape="shape"
 		:customStyle="customStyle"
 		:formatter="formatter"
+		:ignoreCompositionEvent="ignoreCompositionEvent"
 		@focus="$emit('focus')"
-		@blur="$emit('blur')"
+		@blur="e => $emit('blur', e)"
 		@keyboardheightchange="$emit('keyboardheightchange')"
 		@change="e => $emit('change', e)"
 		@input="e => $emit('input', e)"

+ 1 - 0
uview-ui/components/u--text/u--text.vue

@@ -14,6 +14,7 @@
         :block="block"
         :lines="lines"
         :color="color"
+		:decoration="decoration"
         :size="size"
         :iconStyle="iconStyle"
         :margin="margin"

+ 1 - 0
uview-ui/components/u--textarea/u--textarea.vue

@@ -21,6 +21,7 @@
 		:border="border"
 		:customStyle="customStyle"
 		:formatter="formatter"
+		:ignoreCompositionEvent="ignoreCompositionEvent"
 		@focus="e => $emit('focus')"
 		@blur="e => $emit('blur')"
 		@linechange="e => $emit('linechange', e)"

+ 8 - 5
uview-ui/components/u-action-sheet/u-action-sheet.vue

@@ -3,8 +3,7 @@
 	<u-popup
 	    :show="show"
 	    mode="bottom"
-	    @close="close"
-	    :closeOnClickOverlay="closeOnClickOverlay"
+	    @close="closeHandler"
 	    :safeAreaInsetBottom="safeAreaInsetBottom"
 	    :round="round"
 	>
@@ -16,7 +15,7 @@
 				<text class="u-action-sheet__header__title u-line-1">{{title}}</text>
 				<view
 				    class="u-action-sheet__header__icon-wrap"
-				    @tap.stop="close"
+				    @tap.stop="cancel"
 				>
 					<u-icon
 					    name="close"
@@ -100,7 +99,7 @@
 				    :hover-stay-time="150"
 				    v-if="cancelText"
 				    class="u-action-sheet__cancel-text"
-				    @tap="close"
+				    @tap="cancel"
 				>{{cancelText}}</text>
 			</view>
 		</view>
@@ -167,12 +166,16 @@
 			},
 		},
 		methods: {
-			close() {
+			closeHandler() {
 				// 允许点击遮罩关闭时,才发出close事件
 				if(this.closeOnClickOverlay) {
 					this.$emit('close')
 				}
 			},
+			// 点击取消按钮
+			cancel() {
+				this.$emit('close')
+			},
 			selectHandler(index) {
 				const item = this.actions[index]
 				if (item && !item.disabled && !item.loading) {

+ 0 - 256
uview-ui/components/u-alert-tips/u-alert-tips.vue

@@ -1,256 +0,0 @@
-<template>
-	<view class="u-alert-tips" v-if="show" :class="[
-		!show ? 'u-close-alert-tips': '',
-		type ? 'u-alert-tips--bg--' + type + '-light' : '',
-		type ? 'u-alert-tips--border--' + type + '-disabled' : '',
-	]" :style="{
-		backgroundColor: bgColor,
-		borderColor: borderColor
-	}">
-		<view class="u-icon-wrap">
-			<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="[uTitleStyle]">
-				{{title}}
-			</view>
-			<view v-if="description" class="u-alert-desc" :style="[descStyle]">
-				{{description}}
-			</view>
-		</view>
-		<view class="u-icon-wrap">
-			<u-icon @click="close" v-if="closeAble && !closeText" hoverClass="u-type-error-hover-color" name="close" color="#c0c4cc"
-			 :size="22" class="u-close-icon" :style="{
-				top: description ? '18rpx' : '24rpx'
-			}"></u-icon>
-		</view>
-		<text v-if="closeAble && closeText" class="u-close-text" :style="{
-			top: description ? '18rpx' : '24rpx'
-		}">{{closeText}}</text>
-	</view>
-</template>
-
-<script>
-	/**
-	 * alertTips 警告提示
-	 * @description 警告提示,展现需要关注的信息
-	 * @tutorial https://uviewui.com/components/alertTips.html
-	 * @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 显示或隐藏组件
-	 * @event {Function} click 点击组件时触发
-	 * @event {Function} close 点击关闭按钮时触发
-	 */
-	export default {
-		name: 'u-alert-tips',
-		props: {
-			// 显示文字
-			title: {
-				type: String,
-				default: ''
-			},
-			// 主题,success/warning/info/error
-			type: {
-				type: String,
-				default: 'warning'
-			},
-			// 辅助性文字
-			description: {
-				type: String,
-				default: ''
-			},
-			// 是否可关闭
-			closeAble: {
-				type: Boolean,
-				default: false
-			},
-			// 关闭按钮自定义文本
-			closeText: {
-				type: String,
-				default: ''
-			},
-			// 是否显示图标
-			showIcon: {
-				type: Boolean,
-				default: false
-			},
-			// 文字颜色,如果定义了color值,icon会失效
-			color: {
-				type: String,
-				default: ''
-			},
-			// 背景颜色
-			bgColor: {
-				type: String,
-				default: ''
-			},
-			// 边框颜色
-			borderColor: {
-				type: String,
-				default: ''
-			},
-			// 是否显示
-			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(this.type);
-			},
-			uIconType() {
-				// 如果有设置图标的样式,优先使用,没有的话,则用type的样式
-				return Object.keys(this.iconStyle).length ? '' : this.type;
-			}
-		},
-		methods: {
-			// 点击内容
-			click() {
-				this.$emit('click');
-			},
-			// 点击关闭按钮
-			close() {
-				this.$emit('close');
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-	
-	.u-alert-tips {
-		@include vue-flex;
-		align-items: center;
-		padding: 16rpx 30rpx;
-		border-radius: 8rpx;
-		position: relative;
-		transition: all 0.3s linear;
-		border: 1px solid #fff;
-		
-		&--bg--primary-light {
-			background-color: $u-type-primary-light;
-		}
-		
-		&--bg--info-light {
-			background-color: $u-type-info-light;
-		}
-		
-		&--bg--success-light {
-			background-color: $u-type-success-light;
-		}
-		
-		&--bg--warning-light {
-			background-color: $u-type-warning-light;
-		}
-		
-		&--bg--error-light {
-			background-color: $u-type-error-light;
-		}
-		
-		&--border--primary-disabled {
-			border-color: $u-type-primary-disabled;
-		}
-		
-		&--border--success-disabled {
-			border-color: $u-type-success-disabled;
-		}
-		
-		&--border--error-disabled {
-			border-color: $u-type-error-disabled;
-		}
-		
-		&--border--warning-disabled {
-			border-color: $u-type-warning-disabled;
-		}
-		
-		&--border--info-disabled {
-			border-color: $u-type-info-disabled;
-		}
-	}
-
-	.u-close-alert-tips {
-		opacity: 0;
-		visibility: hidden;
-	}
-
-	.u-icon {
-		margin-right: 16rpx;
-	}
-
-	.u-alert-title {
-		font-size: 28rpx;
-		color: $u-main-color;
-	}
-
-	.u-alert-desc {
-		font-size: 26rpx;
-		text-align: left;
-		color: $u-content-color;
-	}
-
-	.u-close-icon {
-		position: absolute;
-		top: 20rpx;
-		right: 20rpx;
-	}
-
-	.u-close-hover {
-		color: red;
-	}
-	
-	.u-close-text {
-		font-size: 24rpx;
-		color: $u-tips-color;
-		position: absolute;
-		top: 20rpx;
-		right: 20rpx;
-		line-height: 1;
-	}
-</style>

+ 0 - 290
uview-ui/components/u-avatar-cropper/u-avatar-cropper.vue

@@ -1,290 +0,0 @@
-<template>
-	<view class="content">
-		<view class="cropper-wrapper" :style="{ height: cropperOpt.height + 'px' }">
-			<canvas
-				class="cropper"
-				:disable-scroll="true"
-				@touchstart="touchStart"
-				@touchmove="touchMove"
-				@touchend="touchEnd"
-				:style="{ width: cropperOpt.width, height: cropperOpt.height, backgroundColor: 'rgba(0, 0, 0, 0.8)' }"
-				canvas-id="cropper"
-				id="cropper"
-			></canvas>
-			<canvas
-				class="cropper"
-				:disable-scroll="true"
-				:style="{
-					position: 'fixed',
-					top: `-${cropperOpt.width * cropperOpt.pixelRatio}px`,
-					left: `-${cropperOpt.height * cropperOpt.pixelRatio}px`,
-					width: `${cropperOpt.width * cropperOpt.pixelRatio}px`,
-					height: `${cropperOpt.height * cropperOpt.pixelRatio}`
-				}"
-				canvas-id="targetId"
-				id="targetId"
-			></canvas>
-		</view>
-		<view class="cropper-buttons safe-area-padding" :style="{ height: bottomNavHeight + 'px' }">
-			<!-- #ifdef H5 -->
-			<view class="upload" @tap="uploadTap">选择图片</view>
-			<!-- #endif -->
-			<!-- #ifndef H5 -->
-			<view class="upload" @tap="uploadTap">重新选择</view>
-			<!-- #endif -->
-			<view class="getCropperImage" @tap="getCropperImage(false)">确定</view>
-		</view>
-	</view>
-</template>
-
-<script>
-import WeCropper from './weCropper.js';
-export default {
-	props: {
-		// 裁剪矩形框的样式,其中可包含的属性为lineWidth-边框宽度(单位rpx),color: 边框颜色,
-		// mask-遮罩颜色,一般设置为一个rgba的透明度,如"rgba(0, 0, 0, 0.35)"
-		boundStyle: {
-			type: Object,
-			default() {
-				return {
-					lineWidth: 4,
-					borderColor: 'rgb(245, 245, 245)',
-					mask: 'rgba(0, 0, 0, 0.35)'
-				};
-			}
-		}
-		// // 裁剪框宽度,单位rpx
-		// rectWidth: {
-		// 	type: [String, Number],
-		// 	default: 400
-		// },
-		// // 裁剪框高度,单位rpx
-		// rectHeight: {
-		// 	type: [String, Number],
-		// 	default: 400
-		// },
-		// // 输出图片宽度,单位rpx
-		// destWidth: {
-		// 	type: [String, Number],
-		// 	default: 400
-		// },
-		// // 输出图片高度,单位rpx
-		// destHeight: {
-		// 	type: [String, Number],
-		// 	default: 400
-		// },
-		// // 输出的图片类型,如果发现裁剪的图片很大,可能是因为设置为了"png",改成"jpg"即可
-		// fileType: {
-		// 	type: String,
-		// 	default: 'jpg',
-		// },
-		// // 生成的图片质量
-		// // H5上无效,目前不考虑使用此参数
-		// quality: {
-		// 	type: [Number, String],
-		// 	default: 1
-		// }
-	},
-	data() {
-		return {
-			// 底部导航的高度
-			bottomNavHeight: 50,
-			originWidth: 200,
-			width: 0,
-			height: 0,
-			cropperOpt: {
-				id: 'cropper',
-				targetId: 'targetCropper',
-				pixelRatio: 1,
-				width: 0,
-				height: 0,
-				scale: 2.5,
-				zoom: 8,
-				cut: {
-					x: (this.width - this.originWidth) / 2,
-					y: (this.height - this.originWidth) / 2,
-					width: this.originWidth,
-					height: this.originWidth
-				},
-				boundStyle: {
-					lineWidth: uni.upx2px(this.boundStyle.lineWidth),
-					mask: this.boundStyle.mask,
-					color: this.boundStyle.borderColor
-				}
-			},
-			// 裁剪框和输出图片的尺寸,高度默认等于宽度
-			// 输出图片宽度,单位px
-			destWidth: 200,
-			// 裁剪框宽度,单位px
-			rectWidth: 200,
-			// 输出的图片类型,如果'png'类型发现裁剪的图片太大,改成"jpg"即可
-			fileType: 'jpg',
-			src: '', // 选择的图片路径,用于在点击确定时,判断是否选择了图片
-		};
-	},
-	onLoad(option) {
-		let rectInfo = uni.getSystemInfoSync();
-		this.width = rectInfo.windowWidth;
-		this.height = rectInfo.windowHeight - this.bottomNavHeight;
-		this.cropperOpt.width = this.width;
-		this.cropperOpt.height = this.height;
-		this.cropperOpt.pixelRatio = rectInfo.pixelRatio;
-
-		if (option.destWidth) this.destWidth = option.destWidth;
-		if (option.rectWidth) {
-			let rectWidth = Number(option.rectWidth);
-			this.cropperOpt.cut = {
-				x: (this.width - rectWidth) / 2,
-				y: (this.height - rectWidth) / 2,
-				width: rectWidth,
-				height: rectWidth
-			};
-		}
-		this.rectWidth = option.rectWidth;
-		if (option.fileType) this.fileType = option.fileType;
-		// 初始化
-		this.cropper = new WeCropper(this.cropperOpt)
-			.on('ready', ctx => {
-				// wecropper is ready for work!
-			})
-			.on('beforeImageLoad', ctx => {
-				// before picture loaded, i can do something
-			})
-			.on('imageLoad', ctx => {
-				// picture loaded
-			})
-			.on('beforeDraw', (ctx, instance) => {
-				// before canvas draw,i can do something
-			});
-		// 设置导航栏样式,以免用户在page.json中没有设置为黑色背景
-		uni.setNavigationBarColor({
-			frontColor: '#ffffff',
-			backgroundColor: '#000000'
-		});
-		uni.chooseImage({
-			count: 1, // 默认9
-			sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
-			sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
-			success: res => {
-				this.src = res.tempFilePaths[0];
-				//  获取裁剪图片资源后,给data添加src属性及其值
-				this.cropper.pushOrign(this.src);
-			}
-		});
-	},
-	methods: {
-		touchStart(e) {
-			this.cropper.touchStart(e);
-		},
-		touchMove(e) {
-			this.cropper.touchMove(e);
-		},
-		touchEnd(e) {
-			this.cropper.touchEnd(e);
-		},
-		getCropperImage(isPre = false) {
-			if(!this.src) return this.$u.toast('请先选择图片再裁剪');
-
-			let cropper_opt = {
-				destHeight: Number(this.destWidth), // uni.canvasToTempFilePath要求这些参数为数值
-				destWidth: Number(this.destWidth),
-				fileType: this.fileType
-			};
-			this.cropper.getCropperImage(cropper_opt, (path, err) => {
-				if (err) {
-					uni.showModal({
-						title: '温馨提示',
-						content: err.message
-					});
-				} else {
-					if (isPre) {
-						uni.previewImage({
-							current: '', // 当前显示图片的 http 链接
-							urls: [path] // 需要预览的图片 http 链接列表
-						});
-					} else {
-						uni.$emit('uAvatarCropper', path);
-						this.$u.route({
-							type: 'back'
-						});
-					}
-				}
-			});
-		},
-		uploadTap() {
-			const self = this;
-			uni.chooseImage({
-				count: 1, // 默认9
-				sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
-				sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
-				success: (res) => {
-					self.src = res.tempFilePaths[0];
-					//  获取裁剪图片资源后,给data添加src属性及其值
-
-					self.cropper.pushOrign(this.src);
-				}
-			});
-		}
-	}
-};
-</script>
-
-<style scoped lang="scss">
-@import '../../libs/css/style.components.scss';
-
-.content {
-	background: rgba(255, 255, 255, 1);
-}
-
-.cropper {
-	position: absolute;
-	top: 0;
-	left: 0;
-	width: 100%;
-	height: 100%;
-	z-index: 11;
-}
-
-.cropper-buttons {
-	background-color: #000000;
-	color: #eee;
-}
-
-.cropper-wrapper {
-	position: relative;
-	@include vue-flex;
-	flex-direction: row;
-	justify-content: space-between;
-	align-items: center;
-	width: 100%;
-	background-color: #000;
-}
-
-.cropper-buttons {
-	width: 100vw;
-	@include vue-flex;
-	flex-direction: row;
-	justify-content: space-between;
-	align-items: center;
-	position: fixed;
-	bottom: 0;
-	left: 0;
-	font-size: 28rpx;
-}
-
-.cropper-buttons .upload,
-.cropper-buttons .getCropperImage {
-	width: 50%;
-	text-align: center;
-}
-
-.cropper-buttons .upload {
-	text-align: left;
-	padding-left: 50rpx;
-}
-
-.cropper-buttons .getCropperImage {
-	text-align: right;
-	padding-right: 50rpx;
-}
-</style>

+ 0 - 1265
uview-ui/components/u-avatar-cropper/weCropper.js

@@ -1,1265 +0,0 @@
-/**
- * we-cropper v1.3.9
- * (c) 2020 dlhandsome
- * @license MIT
- */
-(function(global, factory) {
-	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
-		typeof define === 'function' && define.amd ? define(factory) :
-		(global.WeCropper = factory());
-}(this, (function() {
-	'use strict';
-
-	var device = void 0;
-	var TOUCH_STATE = ['touchstarted', 'touchmoved', 'touchended'];
-
-	function firstLetterUpper(str) {
-		return str.charAt(0).toUpperCase() + str.slice(1)
-	}
-
-	function setTouchState(instance) {
-		var arg = [],
-			len = arguments.length - 1;
-		while (len-- > 0) arg[len] = arguments[len + 1];
-
-		TOUCH_STATE.forEach(function(key, i) {
-			if (arg[i] !== undefined) {
-				instance[key] = arg[i];
-			}
-		});
-	}
-
-	function validator(instance, o) {
-		Object.defineProperties(instance, o);
-	}
-
-	function getDevice() {
-		if (!device) {
-			device = uni.getSystemInfoSync();
-		}
-		return device
-	}
-
-	var tmp = {};
-
-	var ref = getDevice();
-	var pixelRatio = ref.pixelRatio;
-
-	var DEFAULT = {
-		id: {
-			default: 'cropper',
-			get: function get() {
-				return tmp.id
-			},
-			set: function set(value) {
-				if (typeof(value) !== 'string') {
-					console.error(("id:" + value + " is invalid"));
-				}
-				tmp.id = value;
-			}
-		},
-		width: {
-			default: 750,
-			get: function get() {
-				return tmp.width
-			},
-			set: function set(value) {
-				if (typeof(value) !== 'number') {
-					console.error(("width:" + value + " is invalid"));
-				}
-				tmp.width = value;
-			}
-		},
-		height: {
-			default: 750,
-			get: function get() {
-				return tmp.height
-			},
-			set: function set(value) {
-				if (typeof(value) !== 'number') {
-					console.error(("height:" + value + " is invalid"));
-				}
-				tmp.height = value;
-			}
-		},
-		pixelRatio: {
-			default: pixelRatio,
-			get: function get() {
-				return tmp.pixelRatio
-			},
-			set: function set(value) {
-				if (typeof(value) !== 'number') {
-					console.error(("pixelRatio:" + value + " is invalid"));
-				}
-				tmp.pixelRatio = value;
-			}
-		},
-		scale: {
-			default: 2.5,
-			get: function get() {
-				return tmp.scale
-			},
-			set: function set(value) {
-				if (typeof(value) !== 'number') {
-					console.error(("scale:" + value + " is invalid"));
-				}
-				tmp.scale = value;
-			}
-		},
-		zoom: {
-			default: 5,
-			get: function get() {
-				return tmp.zoom
-			},
-			set: function set(value) {
-				if (typeof(value) !== 'number') {
-					console.error(("zoom:" + value + " is invalid"));
-				} else if (value < 0 || value > 10) {
-					console.error("zoom should be ranged in 0 ~ 10");
-				}
-				tmp.zoom = value;
-			}
-		},
-		src: {
-			default: '',
-			get: function get() {
-				return tmp.src
-			},
-			set: function set(value) {
-				if (typeof(value) !== 'string') {
-					console.error(("src:" + value + " is invalid"));
-				}
-				tmp.src = value;
-			}
-		},
-		cut: {
-			default: {},
-			get: function get() {
-				return tmp.cut
-			},
-			set: function set(value) {
-				if (typeof(value) !== 'object') {
-					console.error(("cut:" + value + " is invalid"));
-				}
-				tmp.cut = value;
-			}
-		},
-		boundStyle: {
-			default: {},
-			get: function get() {
-				return tmp.boundStyle
-			},
-			set: function set(value) {
-				if (typeof(value) !== 'object') {
-					console.error(("boundStyle:" + value + " is invalid"));
-				}
-				tmp.boundStyle = value;
-			}
-		},
-		onReady: {
-			default: null,
-			get: function get() {
-				return tmp.ready
-			},
-			set: function set(value) {
-				tmp.ready = value;
-			}
-		},
-		onBeforeImageLoad: {
-			default: null,
-			get: function get() {
-				return tmp.beforeImageLoad
-			},
-			set: function set(value) {
-				tmp.beforeImageLoad = value;
-			}
-		},
-		onImageLoad: {
-			default: null,
-			get: function get() {
-				return tmp.imageLoad
-			},
-			set: function set(value) {
-				tmp.imageLoad = value;
-			}
-		},
-		onBeforeDraw: {
-			default: null,
-			get: function get() {
-				return tmp.beforeDraw
-			},
-			set: function set(value) {
-				tmp.beforeDraw = value;
-			}
-		}
-	};
-
-	var ref$1 = getDevice();
-	var windowWidth = ref$1.windowWidth;
-
-	function prepare() {
-		var self = this;
-
-		// v1.4.0 版本中将不再自动绑定we-cropper实例
-		self.attachPage = function() {
-			var pages = getCurrentPages();
-			// 获取到当前page上下文
-			var pageContext = pages[pages.length - 1];
-			// 把this依附在Page上下文的wecropper属性上,便于在page钩子函数中访问
-			Object.defineProperty(pageContext, 'wecropper', {
-				get: function get() {
-					console.warn(
-						'Instance will not be automatically bound to the page after v1.4.0\n\n' +
-						'Please use a custom instance name instead\n\n' +
-						'Example: \n' +
-						'this.mycropper = new WeCropper(options)\n\n' +
-						'// ...\n' +
-						'this.mycropper.getCropperImage()'
-					);
-					return self
-				},
-				configurable: true
-			});
-		};
-
-		self.createCtx = function() {
-			var id = self.id;
-			var targetId = self.targetId;
-
-			if (id) {
-				self.ctx = self.ctx || uni.createCanvasContext(id);
-				self.targetCtx = self.targetCtx || uni.createCanvasContext(targetId);
-			} else {
-				console.error("constructor: create canvas context failed, 'id' must be valuable");
-			}
-		};
-
-		self.deviceRadio = windowWidth / 750;
-	}
-
-	var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !==
-		'undefined' ? self : {};
-
-
-
-
-
-	function createCommonjsModule(fn, module) {
-		return module = {
-			exports: {}
-		}, fn(module, module.exports), module.exports;
-	}
-
-	var tools = createCommonjsModule(function(module, exports) {
-		/**
-		 * String type check
-		 */
-		exports.isStr = function(v) {
-			return typeof v === 'string';
-		};
-		/**
-		 * Number type check
-		 */
-		exports.isNum = function(v) {
-			return typeof v === 'number';
-		};
-		/**
-		 * Array type check
-		 */
-		exports.isArr = Array.isArray;
-		/**
-		 * undefined type check
-		 */
-		exports.isUndef = function(v) {
-			return v === undefined;
-		};
-
-		exports.isTrue = function(v) {
-			return v === true;
-		};
-
-		exports.isFalse = function(v) {
-			return v === false;
-		};
-		/**
-		 * Function type check
-		 */
-		exports.isFunc = function(v) {
-			return typeof v === 'function';
-		};
-		/**
-		 * Quick object check - this is primarily used to tell
-		 * Objects from primitive values when we know the value
-		 * is a JSON-compliant type.
-		 */
-		exports.isObj = exports.isObject = function(obj) {
-			return obj !== null && typeof obj === 'object'
-		};
-
-		/**
-		 * Strict object type check. Only returns true
-		 * for plain JavaScript objects.
-		 */
-		var _toString = Object.prototype.toString;
-		exports.isPlainObject = function(obj) {
-			return _toString.call(obj) === '[object Object]'
-		};
-
-		/**
-		 * Check whether the object has the property.
-		 */
-		var hasOwnProperty = Object.prototype.hasOwnProperty;
-		exports.hasOwn = function(obj, key) {
-			return hasOwnProperty.call(obj, key)
-		};
-
-		/**
-		 * Perform no operation.
-		 * Stubbing args to make Flow happy without leaving useless transpiled code
-		 * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)
-		 */
-		exports.noop = function(a, b, c) {};
-
-		/**
-		 * Check if val is a valid array index.
-		 */
-		exports.isValidArrayIndex = function(val) {
-			var n = parseFloat(String(val));
-			return n >= 0 && Math.floor(n) === n && isFinite(val)
-		};
-	});
-
-	var tools_7 = tools.isFunc;
-	var tools_10 = tools.isPlainObject;
-
-	var EVENT_TYPE = ['ready', 'beforeImageLoad', 'beforeDraw', 'imageLoad'];
-
-	function observer() {
-		var self = this;
-
-		self.on = function(event, fn) {
-			if (EVENT_TYPE.indexOf(event) > -1) {
-				if (tools_7(fn)) {
-					event === 'ready' ?
-						fn(self) :
-						self[("on" + (firstLetterUpper(event)))] = fn;
-				}
-			} else {
-				console.error(("event: " + event + " is invalid"));
-			}
-			return self
-		};
-	}
-
-	function wxPromise(fn) {
-		return function(obj) {
-			var args = [],
-				len = arguments.length - 1;
-			while (len-- > 0) args[len] = arguments[len + 1];
-
-			if (obj === void 0) obj = {};
-			return new Promise(function(resolve, reject) {
-				obj.success = function(res) {
-					resolve(res);
-				};
-				obj.fail = function(err) {
-					reject(err);
-				};
-				fn.apply(void 0, [obj].concat(args));
-			})
-		}
-	}
-
-	function draw(ctx, reserve) {
-		if (reserve === void 0) reserve = false;
-
-		return new Promise(function(resolve) {
-			ctx.draw(reserve, resolve);
-		})
-	}
-
-	var getImageInfo = wxPromise(uni.getImageInfo);
-
-	var canvasToTempFilePath = wxPromise(uni.canvasToTempFilePath);
-
-	var base64 = createCommonjsModule(function(module, exports) {
-		/*! http://mths.be/base64 v0.1.0 by @mathias | MIT license */
-		(function(root) {
-
-			// Detect free variables `exports`.
-			var freeExports = 'object' == 'object' && exports;
-
-			// Detect free variable `module`.
-			var freeModule = 'object' == 'object' && module &&
-				module.exports == freeExports && module;
-
-			// Detect free variable `global`, from Node.js or Browserified code, and use
-			// it as `root`.
-			var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal;
-			if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
-				root = freeGlobal;
-			}
-
-			/*--------------------------------------------------------------------------*/
-
-			var InvalidCharacterError = function(message) {
-				this.message = message;
-			};
-			InvalidCharacterError.prototype = new Error;
-			InvalidCharacterError.prototype.name = 'InvalidCharacterError';
-
-			var error = function(message) {
-				// Note: the error messages used throughout this file match those used by
-				// the native `atob`/`btoa` implementation in Chromium.
-				throw new InvalidCharacterError(message);
-			};
-
-			var TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
-			// http://whatwg.org/html/common-microsyntaxes.html#space-character
-			var REGEX_SPACE_CHARACTERS = /[\t\n\f\r ]/g;
-
-			// `decode` is designed to be fully compatible with `atob` as described in the
-			// HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob
-			// The optimized base64-decoding algorithm used is based on @atk’s excellent
-			// implementation. https://gist.github.com/atk/1020396
-			var decode = function(input) {
-				input = String(input)
-					.replace(REGEX_SPACE_CHARACTERS, '');
-				var length = input.length;
-				if (length % 4 == 0) {
-					input = input.replace(/==?$/, '');
-					length = input.length;
-				}
-				if (
-					length % 4 == 1 ||
-					// http://whatwg.org/C#alphanumeric-ascii-characters
-					/[^+a-zA-Z0-9/]/.test(input)
-				) {
-					error(
-						'Invalid character: the string to be decoded is not correctly encoded.'
-					);
-				}
-				var bitCounter = 0;
-				var bitStorage;
-				var buffer;
-				var output = '';
-				var position = -1;
-				while (++position < length) {
-					buffer = TABLE.indexOf(input.charAt(position));
-					bitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;
-					// Unless this is the first of a group of 4 characters…
-					if (bitCounter++ % 4) {
-						// …convert the first 8 bits to a single ASCII character.
-						output += String.fromCharCode(
-							0xFF & bitStorage >> (-2 * bitCounter & 6)
-						);
-					}
-				}
-				return output;
-			};
-
-			// `encode` is designed to be fully compatible with `btoa` as described in the
-			// HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa
-			var encode = function(input) {
-				input = String(input);
-				if (/[^\0-\xFF]/.test(input)) {
-					// Note: no need to special-case astral symbols here, as surrogates are
-					// matched, and the input is supposed to only contain ASCII anyway.
-					error(
-						'The string to be encoded contains characters outside of the ' +
-						'Latin1 range.'
-					);
-				}
-				var padding = input.length % 3;
-				var output = '';
-				var position = -1;
-				var a;
-				var b;
-				var c;
-				var buffer;
-				// Make sure any padding is handled outside of the loop.
-				var length = input.length - padding;
-
-				while (++position < length) {
-					// Read three bytes, i.e. 24 bits.
-					a = input.charCodeAt(position) << 16;
-					b = input.charCodeAt(++position) << 8;
-					c = input.charCodeAt(++position);
-					buffer = a + b + c;
-					// Turn the 24 bits into four chunks of 6 bits each, and append the
-					// matching character for each of them to the output.
-					output += (
-						TABLE.charAt(buffer >> 18 & 0x3F) +
-						TABLE.charAt(buffer >> 12 & 0x3F) +
-						TABLE.charAt(buffer >> 6 & 0x3F) +
-						TABLE.charAt(buffer & 0x3F)
-					);
-				}
-
-				if (padding == 2) {
-					a = input.charCodeAt(position) << 8;
-					b = input.charCodeAt(++position);
-					buffer = a + b;
-					output += (
-						TABLE.charAt(buffer >> 10) +
-						TABLE.charAt((buffer >> 4) & 0x3F) +
-						TABLE.charAt((buffer << 2) & 0x3F) +
-						'='
-					);
-				} else if (padding == 1) {
-					buffer = input.charCodeAt(position);
-					output += (
-						TABLE.charAt(buffer >> 2) +
-						TABLE.charAt((buffer << 4) & 0x3F) +
-						'=='
-					);
-				}
-
-				return output;
-			};
-
-			var base64 = {
-				'encode': encode,
-				'decode': decode,
-				'version': '0.1.0'
-			};
-
-			// Some AMD build optimizers, like r.js, check for specific condition patterns
-			// like the following:
-			if (
-				typeof undefined == 'function' &&
-				typeof undefined.amd == 'object' &&
-				undefined.amd
-			) {
-				undefined(function() {
-					return base64;
-				});
-			} else if (freeExports && !freeExports.nodeType) {
-				if (freeModule) { // in Node.js or RingoJS v0.8.0+
-					freeModule.exports = base64;
-				} else { // in Narwhal or RingoJS v0.7.0-
-					for (var key in base64) {
-						base64.hasOwnProperty(key) && (freeExports[key] = base64[key]);
-					}
-				}
-			} else { // in Rhino or a web browser
-				root.base64 = base64;
-			}
-
-		}(commonjsGlobal));
-	});
-
-	function makeURI(strData, type) {
-		return 'data:' + type + ';base64,' + strData
-	}
-
-	function fixType(type) {
-		type = type.toLowerCase().replace(/jpg/i, 'jpeg');
-		var r = type.match(/png|jpeg|bmp|gif/)[0];
-		return 'image/' + r
-	}
-
-	function encodeData(data) {
-		var str = '';
-		if (typeof data === 'string') {
-			str = data;
-		} else {
-			for (var i = 0; i < data.length; i++) {
-				str += String.fromCharCode(data[i]);
-			}
-		}
-		return base64.encode(str)
-	}
-
-	/**
-	 * 获取图像区域隐含的像素数据
-	 * @param canvasId canvas标识
-	 * @param x 将要被提取的图像数据矩形区域的左上角 x 坐标
-	 * @param y 将要被提取的图像数据矩形区域的左上角 y 坐标
-	 * @param width 将要被提取的图像数据矩形区域的宽度
-	 * @param height 将要被提取的图像数据矩形区域的高度
-	 * @param done 完成回调
-	 */
-	function getImageData(canvasId, x, y, width, height, done) {
-		uni.canvasGetImageData({
-			canvasId: canvasId,
-			x: x,
-			y: y,
-			width: width,
-			height: height,
-			success: function success(res) {
-				done(res, null);
-			},
-			fail: function fail(res) {
-				done(null, res);
-			}
-		});
-	}
-
-	/**
-	 * 生成bmp格式图片
-	 * 按照规则生成图片响应头和响应体
-	 * @param oData 用来描述 canvas 区域隐含的像素数据 { data, width, height } = oData
-	 * @returns {*} base64字符串
-	 */
-	function genBitmapImage(oData) {
-		//
-		// BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
-		// BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
-		//
-		var biWidth = oData.width;
-		var biHeight = oData.height;
-		var biSizeImage = biWidth * biHeight * 3;
-		var bfSize = biSizeImage + 54; // total header size = 54 bytes
-
-		//
-		//  typedef struct tagBITMAPFILEHEADER {
-		//  	WORD bfType;
-		//  	DWORD bfSize;
-		//  	WORD bfReserved1;
-		//  	WORD bfReserved2;
-		//  	DWORD bfOffBits;
-		//  } BITMAPFILEHEADER;
-		//
-		var BITMAPFILEHEADER = [
-			// WORD bfType -- The file type signature; must be "BM"
-			0x42, 0x4D,
-			// DWORD bfSize -- The size, in bytes, of the bitmap file
-			bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
-			// WORD bfReserved1 -- Reserved; must be zero
-			0, 0,
-			// WORD bfReserved2 -- Reserved; must be zero
-			0, 0,
-			// DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
-			54, 0, 0, 0
-		];
-
-		//
-		//  typedef struct tagBITMAPINFOHEADER {
-		//  	DWORD biSize;
-		//  	LONG  biWidth;
-		//  	LONG  biHeight;
-		//  	WORD  biPlanes;
-		//  	WORD  biBitCount;
-		//  	DWORD biCompression;
-		//  	DWORD biSizeImage;
-		//  	LONG  biXPelsPerMeter;
-		//  	LONG  biYPelsPerMeter;
-		//  	DWORD biClrUsed;
-		//  	DWORD biClrImportant;
-		//  } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
-		//
-		var BITMAPINFOHEADER = [
-			// DWORD biSize -- The number of bytes required by the structure
-			40, 0, 0, 0,
-			// LONG biWidth -- The width of the bitmap, in pixels
-			biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
-			// LONG biHeight -- The height of the bitmap, in pixels
-			biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
-			// WORD biPlanes -- The number of planes for the target device. This value must be set to 1
-			1, 0,
-			// WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
-			// has a maximum of 2^24 colors (16777216, Truecolor)
-			24, 0,
-			// DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
-			0, 0, 0, 0,
-			// DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
-			biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
-			// LONG biXPelsPerMeter, unused
-			0, 0, 0, 0,
-			// LONG biYPelsPerMeter, unused
-			0, 0, 0, 0,
-			// DWORD biClrUsed, the number of color indexes of palette, unused
-			0, 0, 0, 0,
-			// DWORD biClrImportant, unused
-			0, 0, 0, 0
-		];
-
-		var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
-
-		var aImgData = oData.data;
-
-		var strPixelData = '';
-		var biWidth4 = biWidth << 2;
-		var y = biHeight;
-		var fromCharCode = String.fromCharCode;
-
-		do {
-			var iOffsetY = biWidth4 * (y - 1);
-			var strPixelRow = '';
-			for (var x = 0; x < biWidth; x++) {
-				var iOffsetX = x << 2;
-				strPixelRow += fromCharCode(aImgData[iOffsetY + iOffsetX + 2]) +
-					fromCharCode(aImgData[iOffsetY + iOffsetX + 1]) +
-					fromCharCode(aImgData[iOffsetY + iOffsetX]);
-			}
-
-			for (var c = 0; c < iPadding; c++) {
-				strPixelRow += String.fromCharCode(0);
-			}
-
-			strPixelData += strPixelRow;
-		} while (--y)
-
-		var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
-
-		return strEncoded
-	}
-
-	/**
-	 * 转换为图片base64
-	 * @param canvasId canvas标识
-	 * @param x 将要被提取的图像数据矩形区域的左上角 x 坐标
-	 * @param y 将要被提取的图像数据矩形区域的左上角 y 坐标
-	 * @param width 将要被提取的图像数据矩形区域的宽度
-	 * @param height 将要被提取的图像数据矩形区域的高度
-	 * @param type 转换图片类型
-	 * @param done 完成回调
-	 */
-	function convertToImage(canvasId, x, y, width, height, type, done) {
-		if (done === void 0) done = function() {};
-
-		if (type === undefined) {
-			type = 'png';
-		}
-		type = fixType(type);
-		if (/bmp/.test(type)) {
-			getImageData(canvasId, x, y, width, height, function(data, err) {
-				var strData = genBitmapImage(data);
-				tools_7(done) && done(makeURI(strData, 'image/' + type), err);
-			});
-		} else {
-			console.error('暂不支持生成\'' + type + '\'类型的base64图片');
-		}
-	}
-
-	var CanvasToBase64 = {
-		convertToImage: convertToImage,
-		// convertToPNG: function (width, height, done) {
-		//   return convertToImage(width, height, 'png', done)
-		// },
-		// convertToJPEG: function (width, height, done) {
-		//   return convertToImage(width, height, 'jpeg', done)
-		// },
-		// convertToGIF: function (width, height, done) {
-		//   return convertToImage(width, height, 'gif', done)
-		// },
-		convertToBMP: function(ref, done) {
-			if (ref === void 0) ref = {};
-			var canvasId = ref.canvasId;
-			var x = ref.x;
-			var y = ref.y;
-			var width = ref.width;
-			var height = ref.height;
-			if (done === void 0) done = function() {};
-
-			return convertToImage(canvasId, x, y, width, height, 'bmp', done)
-		}
-	};
-
-	function methods() {
-		var self = this;
-
-		var boundWidth = self.width; // 裁剪框默认宽度,即整个画布宽度
-		var boundHeight = self.height; // 裁剪框默认高度,即整个画布高度
-
-		var id = self.id;
-		var targetId = self.targetId;
-		var pixelRatio = self.pixelRatio;
-
-		var ref = self.cut;
-		var x = ref.x;
-		if (x === void 0) x = 0;
-		var y = ref.y;
-		if (y === void 0) y = 0;
-		var width = ref.width;
-		if (width === void 0) width = boundWidth;
-		var height = ref.height;
-		if (height === void 0) height = boundHeight;
-
-		self.updateCanvas = function(done) {
-			if (self.croperTarget) {
-				//  画布绘制图片
-				self.ctx.drawImage(
-					self.croperTarget,
-					self.imgLeft,
-					self.imgTop,
-					self.scaleWidth,
-					self.scaleHeight
-				);
-			}
-			tools_7(self.onBeforeDraw) && self.onBeforeDraw(self.ctx, self);
-
-			self.setBoundStyle(self.boundStyle); //	设置边界样式
-
-			self.ctx.draw(false, done);
-			return self
-		};
-
-		self.pushOrigin = self.pushOrign = function(src) {
-			self.src = src;
-
-			tools_7(self.onBeforeImageLoad) && self.onBeforeImageLoad(self.ctx, self);
-
-			return getImageInfo({
-					src: src
-				})
-				.then(function(res) {
-					var innerAspectRadio = res.width / res.height;
-					var customAspectRadio = width / height;
-
-					self.croperTarget = res.path;
-
-					if (innerAspectRadio < customAspectRadio) {
-						self.rectX = x;
-						self.baseWidth = width;
-						self.baseHeight = width / innerAspectRadio;
-						self.rectY = y - Math.abs((height - self.baseHeight) / 2);
-					} else {
-						self.rectY = y;
-						self.baseWidth = height * innerAspectRadio;
-						self.baseHeight = height;
-						self.rectX = x - Math.abs((width - self.baseWidth) / 2);
-					}
-
-					self.imgLeft = self.rectX;
-					self.imgTop = self.rectY;
-					self.scaleWidth = self.baseWidth;
-					self.scaleHeight = self.baseHeight;
-
-					self.update();
-
-					return new Promise(function(resolve) {
-						self.updateCanvas(resolve);
-					})
-				})
-				.then(function() {
-					tools_7(self.onImageLoad) && self.onImageLoad(self.ctx, self);
-				})
-		};
-
-		self.removeImage = function() {
-			self.src = '';
-			self.croperTarget = '';
-			return draw(self.ctx)
-		};
-
-		self.getCropperBase64 = function(done) {
-			if (done === void 0) done = function() {};
-
-			CanvasToBase64.convertToBMP({
-				canvasId: id,
-				x: x,
-				y: y,
-				width: width,
-				height: height
-			}, done);
-		};
-
-		self.getCropperImage = function(opt, fn) {
-			var customOptions = opt;
-
-			var canvasOptions = {
-				canvasId: id,
-				x: x,
-				y: y,
-				width: width,
-				height: height
-			};
-
-			var task = function() {
-				return Promise.resolve();
-			};
-
-			if (
-				tools_10(customOptions) &&
-				customOptions.original
-			) {
-				// original mode
-				task = function() {
-					self.targetCtx.drawImage(
-						self.croperTarget,
-						self.imgLeft * pixelRatio,
-						self.imgTop * pixelRatio,
-						self.scaleWidth * pixelRatio,
-						self.scaleHeight * pixelRatio
-					);
-
-					canvasOptions = {
-						canvasId: targetId,
-						x: x * pixelRatio,
-						y: y * pixelRatio,
-						width: width * pixelRatio,
-						height: height * pixelRatio
-					};
-
-					return draw(self.targetCtx)
-				};
-			}
-
-			return task()
-				.then(function() {
-					if (tools_10(customOptions)) {
-						canvasOptions = Object.assign({}, canvasOptions, customOptions);
-					}
-
-					if (tools_7(customOptions)) {
-						fn = customOptions;
-					}
-
-					var arg = canvasOptions.componentContext ?
-						[canvasOptions, canvasOptions.componentContext] :
-						[canvasOptions];
-
-					return canvasToTempFilePath.apply(null, arg)
-				})
-				.then(function(res) {
-					var tempFilePath = res.tempFilePath;
-
-					return tools_7(fn) ?
-						fn.call(self, tempFilePath, null) :
-						tempFilePath
-				})
-				.catch(function(err) {
-					if (tools_7(fn)) {
-						fn.call(self, null, err);
-					} else {
-						throw err
-					}
-				})
-		};
-	}
-
-	/**
-	 * 获取最新缩放值
-	 * @param oldScale 上一次触摸结束后的缩放值
-	 * @param oldDistance 上一次触摸结束后的双指距离
-	 * @param zoom 缩放系数
-	 * @param touch0 第一指touch对象
-	 * @param touch1 第二指touch对象
-	 * @returns {*}
-	 */
-	var getNewScale = function(oldScale, oldDistance, zoom, touch0, touch1) {
-		var xMove, yMove, newDistance;
-		// 计算二指最新距离
-		xMove = Math.round(touch1.x - touch0.x);
-		yMove = Math.round(touch1.y - touch0.y);
-		newDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove));
-
-		return oldScale + 0.001 * zoom * (newDistance - oldDistance)
-	};
-
-	function update() {
-		var self = this;
-
-		if (!self.src) {
-			return
-		}
-
-		self.__oneTouchStart = function(touch) {
-			self.touchX0 = Math.round(touch.x);
-			self.touchY0 = Math.round(touch.y);
-		};
-
-		self.__oneTouchMove = function(touch) {
-			var xMove, yMove;
-			// 计算单指移动的距离
-			if (self.touchended) {
-				return self.updateCanvas()
-			}
-			xMove = Math.round(touch.x - self.touchX0);
-			yMove = Math.round(touch.y - self.touchY0);
-
-			var imgLeft = Math.round(self.rectX + xMove);
-			var imgTop = Math.round(self.rectY + yMove);
-
-			self.outsideBound(imgLeft, imgTop);
-
-			self.updateCanvas();
-		};
-
-		self.__twoTouchStart = function(touch0, touch1) {
-			var xMove, yMove, oldDistance;
-
-			self.touchX1 = Math.round(self.rectX + self.scaleWidth / 2);
-			self.touchY1 = Math.round(self.rectY + self.scaleHeight / 2);
-
-			// 计算两指距离
-			xMove = Math.round(touch1.x - touch0.x);
-			yMove = Math.round(touch1.y - touch0.y);
-			oldDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove));
-
-			self.oldDistance = oldDistance;
-		};
-
-		self.__twoTouchMove = function(touch0, touch1) {
-			var oldScale = self.oldScale;
-			var oldDistance = self.oldDistance;
-			var scale = self.scale;
-			var zoom = self.zoom;
-
-			self.newScale = getNewScale(oldScale, oldDistance, zoom, touch0, touch1);
-
-			//  设定缩放范围
-			self.newScale <= 1 && (self.newScale = 1);
-			self.newScale >= scale && (self.newScale = scale);
-
-			self.scaleWidth = Math.round(self.newScale * self.baseWidth);
-			self.scaleHeight = Math.round(self.newScale * self.baseHeight);
-			var imgLeft = Math.round(self.touchX1 - self.scaleWidth / 2);
-			var imgTop = Math.round(self.touchY1 - self.scaleHeight / 2);
-
-			self.outsideBound(imgLeft, imgTop);
-
-			self.updateCanvas();
-		};
-
-		self.__xtouchEnd = function() {
-			self.oldScale = self.newScale;
-			self.rectX = self.imgLeft;
-			self.rectY = self.imgTop;
-		};
-	}
-
-	var handle = {
-		//  图片手势初始监测
-		touchStart: function touchStart(e) {
-			var self = this;
-			var ref = e.touches;
-			var touch0 = ref[0];
-			var touch1 = ref[1];
-
-			if (!self.src) {
-				return
-			}
-
-			setTouchState(self, true, null, null);
-
-			// 计算第一个触摸点的位置,并参照改点进行缩放
-			self.__oneTouchStart(touch0);
-
-			// 两指手势触发
-			if (e.touches.length >= 2) {
-				self.__twoTouchStart(touch0, touch1);
-			}
-		},
-
-		//  图片手势动态缩放
-		touchMove: function touchMove(e) {
-			var self = this;
-			var ref = e.touches;
-			var touch0 = ref[0];
-			var touch1 = ref[1];
-
-			if (!self.src) {
-				return
-			}
-
-			setTouchState(self, null, true);
-
-			// 单指手势时触发
-			if (e.touches.length === 1) {
-				self.__oneTouchMove(touch0);
-			}
-			// 两指手势触发
-			if (e.touches.length >= 2) {
-				self.__twoTouchMove(touch0, touch1);
-			}
-		},
-
-		touchEnd: function touchEnd(e) {
-			var self = this;
-
-			if (!self.src) {
-				return
-			}
-
-			setTouchState(self, false, false, true);
-			self.__xtouchEnd();
-		}
-	};
-
-	function cut() {
-		var self = this;
-		var boundWidth = self.width; // 裁剪框默认宽度,即整个画布宽度
-		var boundHeight = self.height;
-		// 裁剪框默认高度,即整个画布高度
-		var ref = self.cut;
-		var x = ref.x;
-		if (x === void 0) x = 0;
-		var y = ref.y;
-		if (y === void 0) y = 0;
-		var width = ref.width;
-		if (width === void 0) width = boundWidth;
-		var height = ref.height;
-		if (height === void 0) height = boundHeight;
-
-		/**
-		 * 设置边界
-		 * @param imgLeft 图片左上角横坐标值
-		 * @param imgTop 图片左上角纵坐标值
-		 */
-		self.outsideBound = function(imgLeft, imgTop) {
-			self.imgLeft = imgLeft >= x ?
-				x :
-				self.scaleWidth + imgLeft - x <= width ?
-				x + width - self.scaleWidth :
-				imgLeft;
-
-			self.imgTop = imgTop >= y ?
-				y :
-				self.scaleHeight + imgTop - y <= height ?
-				y + height - self.scaleHeight :
-				imgTop;
-		};
-
-		/**
-		 * 设置边界样式
-		 * @param color	边界颜色
-		 */
-		self.setBoundStyle = function(ref) {
-			if (ref === void 0) ref = {};
-			var color = ref.color;
-			if (color === void 0) color = '#04b00f';
-			var mask = ref.mask;
-			if (mask === void 0) mask = 'rgba(0, 0, 0, 0.3)';
-			var lineWidth = ref.lineWidth;
-			if (lineWidth === void 0) lineWidth = 1;
-
-			var half = lineWidth / 2;
-			var boundOption = [{
-					start: {
-						x: x - half,
-						y: y + 10 - half
-					},
-					step1: {
-						x: x - half,
-						y: y - half
-					},
-					step2: {
-						x: x + 10 - half,
-						y: y - half
-					}
-				},
-				{
-					start: {
-						x: x - half,
-						y: y + height - 10 + half
-					},
-					step1: {
-						x: x - half,
-						y: y + height + half
-					},
-					step2: {
-						x: x + 10 - half,
-						y: y + height + half
-					}
-				},
-				{
-					start: {
-						x: x + width - 10 + half,
-						y: y - half
-					},
-					step1: {
-						x: x + width + half,
-						y: y - half
-					},
-					step2: {
-						x: x + width + half,
-						y: y + 10 - half
-					}
-				},
-				{
-					start: {
-						x: x + width + half,
-						y: y + height - 10 + half
-					},
-					step1: {
-						x: x + width + half,
-						y: y + height + half
-					},
-					step2: {
-						x: x + width - 10 + half,
-						y: y + height + half
-					}
-				}
-			];
-
-			// 绘制半透明层
-			self.ctx.beginPath();
-			self.ctx.setFillStyle(mask);
-			self.ctx.fillRect(0, 0, x, boundHeight);
-			self.ctx.fillRect(x, 0, width, y);
-			self.ctx.fillRect(x, y + height, width, boundHeight - y - height);
-			self.ctx.fillRect(x + width, 0, boundWidth - x - width, boundHeight);
-			self.ctx.fill();
-
-			boundOption.forEach(function(op) {
-				self.ctx.beginPath();
-				self.ctx.setStrokeStyle(color);
-				self.ctx.setLineWidth(lineWidth);
-				self.ctx.moveTo(op.start.x, op.start.y);
-				self.ctx.lineTo(op.step1.x, op.step1.y);
-				self.ctx.lineTo(op.step2.x, op.step2.y);
-				self.ctx.stroke();
-			});
-		};
-	}
-
-	var version = "1.3.9";
-
-	var WeCropper = function WeCropper(params) {
-		var self = this;
-		var _default = {};
-
-		validator(self, DEFAULT);
-
-		Object.keys(DEFAULT).forEach(function(key) {
-			_default[key] = DEFAULT[key].default;
-		});
-		Object.assign(self, _default, params);
-
-		self.prepare();
-		self.attachPage();
-		self.createCtx();
-		self.observer();
-		self.cutt();
-		self.methods();
-		self.init();
-		self.update();
-
-		return self
-	};
-
-	WeCropper.prototype.init = function init() {
-		var self = this;
-		var src = self.src;
-
-		self.version = version;
-
-		typeof self.onReady === 'function' && self.onReady(self.ctx, self);
-
-		if (src) {
-			self.pushOrign(src);
-		} else {
-			self.updateCanvas();
-		}
-		setTouchState(self, false, false, false);
-
-		self.oldScale = 1;
-		self.newScale = 1;
-
-		return self
-	};
-
-	Object.assign(WeCropper.prototype, handle);
-
-	WeCropper.prototype.prepare = prepare;
-	WeCropper.prototype.observer = observer;
-	WeCropper.prototype.methods = methods;
-	WeCropper.prototype.cutt = cut;
-	WeCropper.prototype.update = update;
-
-	return WeCropper;
-
-})));

+ 4 - 0
uview-ui/components/u-avatar/u-avatar.vue

@@ -103,6 +103,10 @@
 				immediate: true,
 				handler(newVal) {
 					this.avatarUrl = newVal
+					// 如果没有传src,则主动触发error事件,用于显示默认的头像,否则src为''空字符等的时候,会无内容展示
+					if(!newVal) {
+						this.errorHandler()
+					}
 				}
 			}
 		},

+ 2 - 2
uview-ui/components/u-button/u-button.vue

@@ -28,7 +28,7 @@
         <template v-if="loading">
             <u-loading-icon
                 :mode="loadingMode"
-                :size="textSize * 1.15"
+                :size="loadingSize * 1.15"
                 :color="loadingColor"
             ></u-loading-icon>
             <text
@@ -75,7 +75,7 @@
         <template v-if="loading">
             <u-loading-icon
                 :mode="loadingMode"
-                :size="textSize * 1.15"
+                :size="loadingSize * 1.15"
                 :color="loadingColor"
             ></u-loading-icon>
             <text

+ 4 - 3
uview-ui/components/u-calendar/u-calendar.vue

@@ -209,12 +209,13 @@ export default {
 			}
 		},
 		init() {
-			// 校验maxDate,不能小于当前时间
+			// 校验maxDate,不能小于minDate
 			if (
 				this.innerMaxDate &&
-				new Date(this.innerMaxDate).getTime() <= Date.now()
+				this.innerMinDate &&
+				new Date(this.innerMaxDate).getTime() < new Date(this.innerMinDate).getTime()
 			) {
-				return uni.$u.error('maxDate不能小于当前时间')
+				return uni.$u.error('maxDate不能小于minDate')
 			}
 			// 滚动区域的高度
 			this.listHeight = this.rowHeight * 5 + 30

+ 0 - 299
uview-ui/components/u-card/u-card.vue

@@ -1,299 +0,0 @@
-<template>
-	<view
-		class="u-card"
-		@tap.stop="click"
-		:class="{ 'u-border': border, 'u-card-full': full, 'u-card--border': borderRadius > 0 }"
-		:style="{
-			borderRadius: borderRadius + 'rpx',
-			margin: margin,
-			boxShadow: boxShadow
-		}"
-	>
-		<view
-			v-if="showHead"
-			class="u-card__head"
-			:style="[{padding: padding + 'rpx'}, headStyle]"
-			:class="{
-				'u-border-bottom': headBorderBottom
-			}"
-			@tap="headClick"
-		>
-			<view v-if="!$slots.head" class="u-flex u-row-between">
-				<view class="u-card__head--left u-flex u-line-1" v-if="title">
-					<image
-						:src="thumb"
-						class="u-card__head--left__thumb"
-						mode="aspectfull"
-						v-if="thumb"
-						:style="{ 
-							height: thumbWidth + 'rpx', 
-							width: thumbWidth + 'rpx', 
-							borderRadius: thumbCircle ? '100rpx' : '6rpx' 
-						}"
-					></image>
-					<text
-						class="u-card__head--left__title u-line-1"
-						:style="{
-							fontSize: titleSize + 'rpx',
-							color: titleColor
-						}"
-					>
-						{{ title }}
-					</text>
-				</view>
-				<view class="u-card__head--right u-line-1" v-if="subTitle">
-					<text
-						class="u-card__head__title__text"
-						:style="{
-							fontSize: subTitleSize + 'rpx',
-							color: subTitleColor
-						}"
-					>
-						{{ subTitle }}
-					</text>
-				</view>
-			</view>
-			<slot name="head" v-else />
-		</view>
-		<view @tap="bodyClick" class="u-card__body" :style="[{padding: padding + 'rpx'}, bodyStyle]"><slot name="body" /></view>
-		<view
-			v-if="showFoot"
-			class="u-card__foot"
-			 @tap="footClick"
-			:style="[{padding: $slots.foot ? padding + 'rpx' : 0}, footStyle]"
-			:class="{
-				'u-border-top': footBorderTop
-			}"
-		>
-			<slot name="foot" />
-		</view>
-	</view>
-</template>
-
-<script>
-/**
- * card 卡片
- * @description 卡片组件一般用于多个列表条目,且风格统一的场景
- * @tutorial https://www.uviewui.com/components/card.html
- * @property {Boolean} full 卡片与屏幕两侧是否留空隙(默认false)
- * @property {String} title 头部左边的标题
- * @property {String} title-color 标题颜色(默认#303133)
- * @property {String | Number} title-size 标题字体大小,单位rpx(默认30)
- * @property {String} sub-title 头部右边的副标题
- * @property {String} sub-title-color 副标题颜色(默认#909399)
- * @property {String | Number} sub-title-size 副标题字体大小(默认26)
- * @property {Boolean} border 是否显示边框(默认true)
- * @property {String | Number} index 用于标识点击了第几个卡片
- * @property {String} box-shadow 卡片外围阴影,字符串形式(默认none)
- * @property {String} margin 卡片与屏幕两边和上下元素的间距,需带单位,如"30rpx 20rpx"(默认30rpx)
- * @property {String | Number} border-radius 卡片整体的圆角值,单位rpx(默认16)
- * @property {Object} head-style 头部自定义样式,对象形式
- * @property {Object} body-style 中部自定义样式,对象形式
- * @property {Object} foot-style 底部自定义样式,对象形式
- * @property {Boolean} head-border-bottom 是否显示头部的下边框(默认true)
- * @property {Boolean} foot-border-top 是否显示底部的上边框(默认true)
- * @property {Boolean} show-head 是否显示头部(默认true)
- * @property {Boolean} show-head 是否显示尾部(默认true)
- * @property {String} thumb 缩略图路径,如设置将显示在标题的左边,不建议使用相对路径
- * @property {String | Number} thumb-width 缩略图的宽度,高等于宽,单位rpx(默认60)
- * @property {Boolean} thumb-circle 缩略图是否为圆形(默认false)
- * @event {Function} click 整个卡片任意位置被点击时触发
- * @event {Function} head-click 卡片头部被点击时触发
- * @event {Function} body-click 卡片主体部分被点击时触发
- * @event {Function} foot-click 卡片底部部分被点击时触发
- * @example <u-card padding="30" title="card"></u-card>
- */
-export default {
-	name: 'u-card',
-	props: {
-		// 与屏幕两侧是否留空隙
-		full: {
-			type: Boolean,
-			default: false
-		},
-		// 标题
-		title: {
-			type: String,
-			default: ''
-		},
-		// 标题颜色
-		titleColor: {
-			type: String,
-			default: '#303133'
-		},
-		// 标题字体大小,单位rpx
-		titleSize: {
-			type: [Number, String],
-			default: '30'
-		},
-		// 副标题
-		subTitle: {
-			type: String,
-			default: ''
-		},
-		// 副标题颜色
-		subTitleColor: {
-			type: String,
-			default: '#909399'
-		},
-		// 副标题字体大小,单位rpx
-		subTitleSize: {
-			type: [Number, String],
-			default: '26'
-		},
-		// 是否显示外部边框,只对full=false时有效(卡片与边框有空隙时)
-		border: {
-			type: Boolean,
-			default: true
-		},
-		// 用于标识点击了第几个
-		index: {
-			type: [Number, String, Object],
-			default: ''
-		},
-		// 用于隔开上下左右的边距,带单位的写法,如:"30rpx 30rpx","20rpx 20rpx 30rpx 30rpx"
-		margin: {
-			type: String,
-			default: '30rpx'
-		},
-		// card卡片的圆角
-		borderRadius: {
-			type: [Number, String],
-			default: '16'
-		},
-		// 头部自定义样式,对象形式
-		headStyle: {
-			type: Object,
-			default() {
-				return {};
-			}
-		},
-		// 主体自定义样式,对象形式
-		bodyStyle: {
-			type: Object,
-			default() {
-				return {};
-			}
-		},
-		// 底部自定义样式,对象形式
-		footStyle: {
-			type: Object,
-			default() {
-				return {};
-			}
-		},
-		// 头部是否下边框
-		headBorderBottom: {
-			type: Boolean,
-			default: true
-		},
-		// 底部是否有上边框
-		footBorderTop: {
-			type: Boolean,
-			default: true
-		},
-		// 标题左边的缩略图
-		thumb: {
-			type: String,
-			default: ''
-		},
-		// 缩略图宽高,单位rpx
-		thumbWidth: {
-			type: [String, Number],
-			default: '60'
-		},
-		// 缩略图是否为圆形
-		thumbCircle: {
-			type: Boolean,
-			default: false
-		},
-		// 给head,body,foot的内边距
-		padding: {
-			type: [String, Number],
-			default: '30'
-		},
-		// 是否显示头部
-		showHead: {
-			type: Boolean,
-			default: true
-		},
-		// 是否显示尾部
-		showFoot: {
-			type: Boolean,
-			default: true
-		},
-		// 卡片外围阴影,字符串形式
-		boxShadow: {
-			type: String,
-			default: 'none'
-		}
-	},
-	data() {
-		return {};
-	},
-	methods: {
-		click() {
-			this.$emit('click', this.index);
-		},
-		headClick() {
-			this.$emit('head-click', this.index);
-		},
-		bodyClick() {
-			this.$emit('body-click', this.index);
-		},
-		footClick() {
-			this.$emit('foot-click', this.index);
-		}
-	}
-};
-</script>
-
-<style lang="scss" scoped>
-@import "../../libs/css/style.components.scss";
-	
-.u-card {
-	position: relative;
-	overflow: hidden;
-	font-size: 28rpx;
-	background-color: #ffffff;
-	box-sizing: border-box;
-	
-	&-full {
-		// 如果是与屏幕之间不留空隙,应该设置左右边距为0
-		margin-left: 0 !important;
-		margin-right: 0 !important;
-		width: 100%;
-	}
-	
-	&--border:after {
-		border-radius: 16rpx;
-	}
-
-	&__head {
-		&--left {
-			color: $u-main-color;
-			
-			&__thumb {
-				margin-right: 16rpx;
-			}
-			
-			&__title {
-				max-width: 400rpx;
-			}
-		}
-
-		&--right {
-			color: $u-tips-color;
-			margin-left: 6rpx;
-		}
-	}
-
-	&__body {
-		color: $u-content-color;
-	}
-
-	&__foot {
-		color: $u-tips-color;
-	}
-}
-</style>

+ 0 - 316
uview-ui/components/u-cell-item/u-cell-item.vue

@@ -1,316 +0,0 @@
-<template>
-	<view
-		@tap="click"
-		class="u-cell"
-		:class="{ 'u-border-bottom': borderBottom, 'u-border-top': borderTop, 'u-col-center': center, 'u-cell--required': required }"
-		hover-stay-time="150"
-		:hover-class="hoverClass"
-		:style="{
-			backgroundColor: bgColor
-		}"
-	>
-		<u-icon :size="iconSize" :name="icon" v-if="icon" :custom-style="iconStyle" class="u-cell__left-icon-wrap"></u-icon>
-		<view class="u-flex" v-else>
-			<slot name="icon"></slot>
-		</view>
-		<view
-			class="u-cell_title"
-			:style="[
-				{
-					width: titleWidth ? titleWidth + 'rpx' : 'auto'
-				},
-				titleStyle
-			]"
-		>
-			<block v-if="title !== ''">{{ title }}</block>
-			<slot name="title" v-else></slot>
-
-			<view class="u-cell__label" v-if="label || $slots.label" :style="[labelStyle]">
-				<block v-if="label !== ''">{{ label }}</block>
-				<slot name="label" v-else></slot>
-			</view>
-		</view>
-
-		<view class="u-cell__value" :style="[valueStyle]">
-			<block class="u-cell__value" v-if="value !== ''">{{ value }}</block>
-			<slot v-else></slot>
-		</view>
-		<view class="u-flex u-cell_right" v-if="$slots['right-icon']">
-			<slot name="right-icon"></slot>
-		</view>
-		<u-icon v-if="arrow" name="arrow-right" :style="[arrowStyle]" class="u-icon-wrap u-cell__right-icon-wrap"></u-icon>
-	</view>
-</template>
-
-<script>
-/**
- * cellItem 单元格Item
- * @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。搭配u-cell-group使用
- * @tutorial https://www.uviewui.com/components/cell.html
- * @property {String} title 左侧标题
- * @property {String} icon 左侧图标名,只支持uView内置图标,见Icon 图标
- * @property {Object} icon-style 左边图标的样式,对象形式
- * @property {String} value 右侧内容
- * @property {String} label 标题下方的描述信息
- * @property {Boolean} border-bottom 是否显示cell的下边框(默认true)
- * @property {Boolean} border-top 是否显示cell的上边框(默认false)
- * @property {Boolean} center 是否使内容垂直居中(默认false)
- * @property {String} hover-class 是否开启点击反馈,none为无效果(默认true)
- * // @property {Boolean} border-gap border-bottom为true时,Cell列表中间的条目的下边框是否与左边有一个间隔(默认true)
- * @property {Boolean} arrow 是否显示右侧箭头(默认true)
- * @property {Boolean} required 箭头方向,可选值(默认right)
- * @property {Boolean} arrow-direction 是否显示左边表示必填的星号(默认false)
- * @property {Object} title-style 标题样式,对象形式
- * @property {Object} value-style 右侧内容样式,对象形式
- * @property {Object} label-style 标题下方描述信息的样式,对象形式
- * @property {String} bg-color 背景颜色(默认transparent)
- * @property {String Number} index 用于在click事件回调中返回,标识当前是第几个Item
- * @property {String Number} title-width 标题的宽度,单位rpx
- * @example <u-cell-item icon="integral-fill" title="会员等级" value="新版本"></u-cell-item>
- */
-export default {
-	name: 'u-cell-item',
-	props: {
-		// 左侧图标名称(只能uView内置图标),或者图标src
-		icon: {
-			type: String,
-			default: ''
-		},
-		// 左侧标题
-		title: {
-			type: [String, Number],
-			default: ''
-		},
-		// 右侧内容
-		value: {
-			type: [String, Number],
-			default: ''
-		},
-		// 标题下方的描述信息
-		label: {
-			type: [String, Number],
-			default: ''
-		},
-		// 是否显示下边框
-		borderBottom: {
-			type: Boolean,
-			default: true
-		},
-		// 是否显示上边框
-		borderTop: {
-			type: Boolean,
-			default: false
-		},
-		// 多个cell中,中间的cell显示下划线时,下划线是否给一个到左边的距离
-		// 1.4.0版本废除此参数,默认边框由border-top和border-bottom提供,此参数会造成干扰
-		// borderGap: {
-		// 	type: Boolean,
-		// 	default: true
-		// },
-		// 是否开启点击反馈,即点击时cell背景为灰色,none为无效果
-		hoverClass: {
-			type: String,
-			default: 'u-cell-hover'
-		},
-		// 是否显示右侧箭头
-		arrow: {
-			type: Boolean,
-			default: true
-		},
-		// 内容是否垂直居中
-		center: {
-			type: Boolean,
-			default: false
-		},
-		// 是否显示左边表示必填的星号
-		required: {
-			type: Boolean,
-			default: false
-		},
-		// 标题的宽度,单位rpx
-		titleWidth: {
-			type: [Number, String],
-			default: ''
-		},
-		// 右侧箭头方向,可选值:right|up|down,默认为right
-		arrowDirection: {
-			type: String,
-			default: 'right'
-		},
-		// 控制标题的样式
-		titleStyle: {
-			type: Object,
-			default() {
-				return {};
-			}
-		},
-		// 右侧显示内容的样式
-		valueStyle: {
-			type: Object,
-			default() {
-				return {};
-			}
-		},
-		// 描述信息的样式
-		labelStyle: {
-			type: Object,
-			default() {
-				return {};
-			}
-		},
-		// 背景颜色
-		bgColor: {
-			type: String,
-			default: 'transparent'
-		},
-		// 用于识别被点击的是第几个cell
-		index: {
-			type: [String, Number],
-			default: ''
-		},
-		// 是否使用lable插槽
-		useLabelSlot: {
-			type: Boolean,
-			default: false
-		},
-		// 左边图标的大小,单位rpx,只对传入icon字段时有效
-		iconSize: {
-			type: [Number, String],
-			default: 34
-		},
-		// 左边图标的样式,对象形式
-		iconStyle: {
-			type: Object,
-			default() {
-				return {}
-			}
-		},
-	},
-	data() {
-		return {
-
-		};
-	},
-	computed: {
-		arrowStyle() {
-			let style = {};
-			if (this.arrowDirection == 'up') style.transform = 'rotate(-90deg)';
-			else if (this.arrowDirection == 'down') style.transform = 'rotate(90deg)';
-			else style.transform = 'rotate(0deg)';
-			return style;
-		}
-	},
-	methods: {
-		click() {
-			this.$emit('click', this.index);
-		}
-	}
-};
-</script>
-
-<style lang="scss" scoped>
-@import "../../libs/css/style.components.scss";
-.u-cell {
-	@include vue-flex;
-	align-items: center;
-	position: relative;
-	/* #ifndef APP-NVUE */
-	box-sizing: border-box;
-	/* #endif */
-	width: 100%;
-	padding: 26rpx 32rpx;
-	font-size: 28rpx;
-	line-height: 54rpx;
-	color: $u-content-color;
-	background-color: #fff;
-	text-align: left;
-}
-
-.u-cell_title {
-	font-size: 28rpx;
-}
-
-.u-cell__left-icon-wrap {
-	margin-right: 10rpx;
-	font-size: 32rpx;
-}
-
-.u-cell__right-icon-wrap {
-	margin-left: 10rpx;
-	color: #969799;
-	font-size: 28rpx;
-}
-
-.u-cell__left-icon-wrap,
-.u-cell__right-icon-wrap {
-	@include vue-flex;
-	align-items: center;
-	height: 48rpx;
-}
-
-.u-cell-border:after {
-	position: absolute; 
-	/* #ifndef APP-NVUE */
-	box-sizing: border-box;
-	content: ' ';
-	pointer-events: none;
-	border-bottom: 1px solid $u-border-color;
-	/* #endif */
-	right: 0;
-	left: 0;
-	top: 0;
-	transform: scaleY(0.5);
-}
-
-.u-cell-border {
-	position: relative;
-}
-
-.u-cell__label {
-	margin-top: 6rpx;
-	font-size: 26rpx;
-	line-height: 36rpx;
-	color: $u-tips-color;
-	/* #ifndef APP-NVUE */
-	word-wrap: break-word;
-	/* #endif */
-}
-
-.u-cell__value {
-	overflow: hidden;
-	text-align: right;
-	/* #ifndef APP-NVUE */
-	vertical-align: middle;
-	/* #endif */
-	color: $u-tips-color;
-	font-size: 26rpx;
-}
-
-.u-cell__title,
-.u-cell__value {
-	flex: 1;
-}
-
-.u-cell--required {
-	/* #ifndef APP-NVUE */
-	overflow: visible;
-	/* #endif */
-	@include vue-flex;
-	align-items: center;
-}
-
-.u-cell--required:before {
-	position: absolute;
-	/* #ifndef APP-NVUE */
-	content: '*';
-	/* #endif */
-	left: 8px;
-	margin-top: 4rpx;
-	font-size: 14px;
-	color: $u-type-error;
-}
-
-.u-cell_right {
-	line-height: 1;
-}
-</style>

+ 0 - 5
uview-ui/components/u-cell/props.js

@@ -20,11 +20,6 @@ export default {
             type: String,
             default: uni.$u.props.cell.icon
         },
-        // 标题的宽度,单位任意,数值默认为px单位
-        titleWidth: {
-            type: [String, Number],
-            default: uni.$u.props.cell.titleWidth
-        },
         // 是否禁用cell
         disabled: {
             type: Boolean,

+ 0 - 1
uview-ui/components/u-cell/u-cell.vue

@@ -47,7 +47,6 @@
 	 * @property {String | Number}	label			标题下方的描述信息
 	 * @property {String | Number}	value			右侧的内容
 	 * @property {String}			icon			左侧图标名称,或者图片链接(本地文件建议使用绝对地址)
-	 * @property {String | Number}	titleWidth		标题的宽度,单位任意,数值默认为px单位
 	 * @property {Boolean}			disabled		是否禁用cell	
 	 * @property {Boolean}			border			是否显示下边框 (默认 true )
 	 * @property {Boolean}			center			内容是否垂直居中(主要是针对右侧的value部分) (默认 false )

+ 0 - 147
uview-ui/components/u-circle-progress/u-line-progress/u-line-progress.vue

@@ -1,147 +0,0 @@
-<template>
-	<view class="u-progress" :style="{
-		borderRadius: round ? '100rpx' : 0,
-		height: height + 'rpx',
-		backgroundColor: inactiveColor
-	}">
-		<view :class="[
-			type ? `u-type-${type}-bg` : '',
-			striped ? 'u-striped' : '',
-			striped && stripedActive ? 'u-striped-active' : ''
-		]" class="u-active" :style="[progressStyle]">
-			<slot v-if="$slots.default || $slots.$default" />
-			<block v-else-if="showPercent">
-				{{percent + '%'}}
-			</block>
-		</view>
-	</view>
-</template>
-
-<script>
-	/**
-	 * lineProgress 线型进度条
-	 * @description 展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。
-	 * @tutorial https://www.uviewui.com/components/lineProgress.html
-	 * @property {String Number} percent 进度条百分比值,为数值类型,0-100
-	 * @property {Boolean} round 进度条两端是否为半圆(默认true)
-	 * @property {String} type 如设置,active-color值将会失效
-	 * @property {String} active-color 进度条激活部分的颜色(默认#19be6b)
-	 * @property {String} inactive-color 进度条的底色(默认#ececec)
-	 * @property {Boolean} show-percent 是否在进度条内部显示当前的百分比值数值(默认true)
-	 * @property {String Number} height 进度条的高度,单位rpx(默认28)
-	 * @property {Boolean} striped 是否显示进度条激活部分的条纹(默认false)
-	 * @property {Boolean} striped-active 条纹是否具有动态效果(默认false)
-	 * @example <u-line-progress :percent="70" :show-percent="true"></u-line-progress>
-	 */
-	export default {
-		name: "u-line-progress",
-		props: {
-			// 两端是否显示半圆形
-			round: {
-				type: Boolean,
-				default: true
-			},
-			// 主题颜色
-			type: {
-				type: String,
-				default: ''
-			},
-			// 激活部分的颜色
-			activeColor: {
-				type: String,
-				default: '#19be6b'
-			},
-			inactiveColor: {
-				type: String,
-				default: '#ececec'
-			},
-			// 进度百分比,数值
-			percent: {
-				type: Number,
-				default: 0
-			},
-			// 是否在进度条内部显示百分比的值
-			showPercent: {
-				type: Boolean,
-				default: true
-			},
-			// 进度条的高度,单位rpx
-			height: {
-				type: [Number, String],
-				default: 28
-			},
-			// 是否显示条纹
-			striped: {
-				type: Boolean,
-				default: false
-			},
-			// 条纹是否显示活动状态
-			stripedActive: {
-				type: Boolean,
-				default: false
-			}
-		},
-		data() {
-			return {
-
-			}
-		},
-		computed: {
-			progressStyle() {
-				let style = {};
-				style.width = this.percent + '%';
-				if(this.activeColor) style.backgroundColor = this.activeColor;
-				return style;
-			}
-		},
-		methods: {
-
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-	
-	.u-progress {
-		overflow: hidden;
-		height: 15px;
-		/* #ifndef APP-NVUE */
-		display: inline-flex;
-		/* #endif */
-		align-items: center;
-		width: 100%;
-		border-radius: 100rpx;
-	}
-
-	.u-active {
-		width: 0;
-		height: 100%;
-		align-items: center;
-		@include vue-flex;
-		justify-items: flex-end;
-		justify-content: space-around;
-		font-size: 20rpx;
-		color: #ffffff;
-		transition: all 0.4s ease;
-	}
-
-	.u-striped {
-		background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-		background-size: 39px 39px;
-	}
-
-	.u-striped-active {
-		animation: progress-stripes 2s linear infinite;
-	}
-
-	@keyframes progress-stripes {
-		0% {
-			background-position: 0 0;
-		}
-
-		100% {
-			background-position: 39px 0;
-		}
-	}
-</style>

+ 5 - 0
uview-ui/components/u-code-input/props.js

@@ -1,5 +1,10 @@
 export default {
     props: {
+		// 键盘弹起时,是否自动上推页面
+		adjustPosition: {
+			type: Boolean,
+            default: uni.$u.props.codeInput.adjustPosition
+		},
         // 最大输入长度
         maxlength: {
             type: [String, Number],

+ 40 - 1
uview-ui/components/u-code-input/u-code-input.vue

@@ -23,6 +23,9 @@
 				v-if="mode === 'line'"
 				:style="[lineStyle]"
 			></view>
+			<!-- #ifndef APP-PLUS -->
+			<view v-if="isFocus && codeArray.length === index" :style="{backgroundColor: color}" class="u-code-input__item__cursor"></view>
+			<!-- #endif -->
 		</view>
 		<input
 			:disabled="disabledKeyboard"
@@ -30,11 +33,14 @@
 			:focus="focus"
 			:value="inputValue"
 			:maxlength="maxlength"
+			:adjustPosition="adjustPosition"
 			class="u-code-input__input"
 			@input="inputHandler"
 			:style="{
 				height: $u.addUnit(size) 
 			}"
+			@focus="isFocus = true"
+			@blur="isFocus = false"
 		/>
 	</view>
 </template>
@@ -69,7 +75,8 @@
 		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
 		data() {
 			return {
-				inputValue: ''
+				inputValue: '',
+				isFocus: this.focus
 			}
 		},
 		watch: {
@@ -166,6 +173,10 @@
 
 <style lang="scss" scoped>
 	@import "../../libs/css/components.scss";
+	$u-code-input-cursor-width: 1px;
+	$u-code-input-cursor-height: 40%;
+	$u-code-input-cursor-animation-duration: 1s;
+	$u-code-input-cursor-animation-name: u-cursor-flicker;
 
 	.u-code-input {
 		@include flex;
@@ -176,6 +187,7 @@
 			@include flex;
 			justify-content: center;
 			align-items: center;
+			position: relative;
 
 			&__text {
 				font-size: 15px;
@@ -197,6 +209,18 @@
 				width: 40px;
 				background-color: $u-content-color;
 			}
+			/* #ifndef APP-PLUS */
+			&__cursor {
+				position: absolute;
+				top: 50%;
+				left: 50%;
+				transform: translate(-50%,-50%);
+				width: $u-code-input-cursor-width;
+				height: $u-code-input-cursor-height;
+				animation: $u-code-input-cursor-animation-duration u-cursor-flicker infinite;
+			}
+			/* #endif */
+			
 		}
 
 		&__input {
@@ -210,4 +234,19 @@
 			text-align: left;
 		}
 	}
+	
+	/* #ifndef APP-PLUS */
+	@keyframes u-cursor-flicker {
+		0% {
+		    opacity: 0;
+		}
+		50% {
+		    opacity: 1;
+		}
+		100% {
+		    opacity: 0;
+		}
+	}
+	/* #endif */
+
 </style>

+ 4 - 4
uview-ui/components/u-code/u-code.vue

@@ -16,11 +16,11 @@
 	 * @property {String}			endText			倒计结束的提示语,见官网说明(默认 '重新获取' )
 	 * @property {Boolean}			keepRunning		是否在H5刷新或各端返回再进入时继续倒计时( 默认false )
 	 * @property {String}			uniqueKey		为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
-	 * 
+	 *
 	 * @event {Function}	change	倒计时期间,每秒触发一次
 	 * @event {Function}	start	开始倒计时触发
 	 * @event {Function}	end		结束倒计时触发
-	 * @example <u-code ref="uCode" @change="codeChange" seconds="20"></u-code> 
+	 * @example <u-code ref="uCode" @change="codeChange" seconds="20"></u-code>
 	 */
 	export default {
 		name: "u-code",
@@ -74,7 +74,6 @@
 				this.canGetCode = false
 				// 这里放这句,是为了一开始时就提示,否则要等setInterval的1秒后才会有提示
 				this.changeEvent(this.changeText.replace(/x|X/, this.secNum))
-				this.setTimeToStorage()
 				this.timer = setInterval(() => {
 					if (--this.secNum) {
 						// 用当前倒计时的秒数替换提示字符串中的"x"字母
@@ -88,7 +87,8 @@
 						this.canGetCode = true
 					}
 				}, 1000)
-			},
+        this.setTimeToStorage()
+      },
 			// 重置,可以让用户再次获取验证码
 			reset() {
 				this.canGetCode = true

+ 5 - 2
uview-ui/components/u-col/u-col.vue

@@ -53,8 +53,8 @@
 			colStyle() {
 				const style = {
 					// 这里写成"padding: 0 10px"的形式是因为nvue的需要
-					paddingLeft: uni.$u.addUnit(Number(this.parentData.gutter)/2),
-					paddingRight: uni.$u.addUnit(Number(this.parentData.gutter)/2),
+					paddingLeft: uni.$u.addUnit(uni.$u.getPx(this.parentData.gutter)/2),
+					paddingRight: uni.$u.addUnit(uni.$u.getPx(this.parentData.gutter)/2),
 					alignItems: this.uAlignItem,
 					justifyContent: this.uJustify,
 					textAlign: this.textAlign,
@@ -96,6 +96,9 @@
 
 	.u-col {
 		padding: 0;
+		/* #ifndef APP-NVUE */
+		box-sizing:border-box;
+		/* #endif */
 		/* #ifdef MP */
 		display: block;
 		/* #endif */

+ 28 - 9
uview-ui/components/u-datetime-picker/u-datetime-picker.vue

@@ -5,6 +5,9 @@
 		:closeOnClickOverlay="closeOnClickOverlay"
 		:columns="columns"
 		:title="title"
+		:itemHeight="itemHeight"
+		:showToolbar="showToolbar"
+		:visibleItemCount="visibleItemCount"
 		:defaultIndex="innerDefaultIndex"
 		:cancelText="cancelText"
 		:confirmText="confirmText"
@@ -74,7 +77,7 @@
 		watch: {
 			show(newValue, oldValue) {
 				if (newValue) {
-					this.updateColumnValue(this.value)
+					this.updateColumnValue(this.innerValue)
 				}
 			},
 			propsChange() {
@@ -117,21 +120,37 @@
 				})
 				this.$emit('input', this.innerValue)
 			},
+			//用正则截取输出值,当出现多组数字时,抛出错误
+			intercept(e,type){
+				let judge = e.match(/\d+/g)
+				//判断是否掺杂数字
+				if(judge.length>1){
+					uni.$u.error("请勿在过滤或格式化函数时添加数字")
+					return 0
+				}else if(type&&judge[0].length==4){//判断是否是年份
+					return judge[0]
+				}else if(judge[0].length>2){
+					uni.$u.error("请勿在过滤或格式化函数时添加数字")
+					return 0
+				}else{
+					return judge[0]
+				}
+			},
 			// 列发生变化时触发
 			change(e) {
 				const { indexs, values } = e
 				let selectValue = ''
 				if(this.mode === 'time') {
 					// 根据value各列索引,从各列数组中,取出当前时间的选中值
-					selectValue = `${values[0][indexs[0]]}:${values[1][indexs[1]]}`
+					selectValue = `${this.intercept(values[0][indexs[0]])}:${this.intercept(values[1][indexs[1]])}`
 				} else {
 					// 将选择的值转为数值,比如'03'转为数值的3,'2019'转为数值的2019
-					const year = parseInt(values[0][indexs[0]])
-					const month = parseInt(values[1][indexs[1]])
-					let date = parseInt(values[2] ? values[2][indexs[2]] : 1)
+					const year = parseInt(this.intercept(values[0][indexs[0]],'year'))
+					const month = parseInt(this.intercept(values[1][indexs[1]]))
+					let date = parseInt(values[2] ? this.intercept(values[2][indexs[2]]) : 1)
 					let hour = 0, minute = 0
 					// 此月份的最大天数
-					const maxDate = dayjs(`${year}-${month}-${date}`).daysInMonth()
+					const maxDate = dayjs(`${year}-${month}`).daysInMonth()
 					// year-month模式下,date不会出现在列中,设置为1,为了符合后边需要减1的需求
 					if (this.mode === 'year-month') {
 					    date = 1
@@ -139,8 +158,8 @@
 					// 不允许超过maxDate值
 					date = Math.min(maxDate, date)
 					if (this.mode === 'datetime') {
-					    hour = parseInt(values[3][indexs[3]])
-					    minute = parseInt(values[4][indexs[4]])
+					    hour = parseInt(this.intercept(values[3][indexs[3]]))
+					    minute = parseInt(this.intercept(values[4][indexs[4]]))
 					}
 					// 转为时间模式
 					selectValue = Number(new Date(year, month - 1, date, hour, minute))
@@ -234,7 +253,7 @@
 					value = this.minDate
 				} else if (!isDateMode && !value) {
 					// 如果是时间类型,而又没有默认值的话,就用最小时间
-					value = `${uni.$u.padZero(this.minHour)}:uni.$u.padZero(this.minMinute)}`
+					value = `${uni.$u.padZero(this.minHour)}:${uni.$u.padZero(this.minMinute)}`
 				}
 				// 时间类型
 				if (!isDateMode) {

+ 120 - 139
uview-ui/components/u-dropdown-item/u-dropdown-item.vue

@@ -1,146 +1,127 @@
 <template>
-	<view class="u-drawdown-item">
-		<u-overlay
-			customStyle="top: 126px"
-			:show="show"
-			:closeOnClickOverlay="closeOnClickOverlay"
-			@click="overlayClick"
-		></u-overlay>
-		<view
-			class="u-drawdown-item__content"
-			:style="[style]"
-			:animation="animationData"
-			ref="animation"
-		>
-			<slot />
-		</view>
-	</view>
+  <view class="u-drawdown">
+    <view
+      class="u-dropdown__menu"
+      :style="{
+				height: $u.addUnit(height)
+			}"
+      ref="u-dropdown__menu"
+    >
+      <view
+        class="u-dropdown__menu__item"
+        v-for="(item, index) in menuList"
+        :key="index"
+        @tap.stop="clickHandler(item, index)"
+      >
+        <view class="u-dropdown__menu__item__content">
+          <text
+            class="u-dropdown__menu__item__content__text"
+            :style="[index === current ? activeStyle : inactiveStyle]"
+          >{{item.title}}</text>
+          <view
+            class="u-dropdown__menu__item__content__arrow"
+            :class="[index === current && 'u-dropdown__menu__item__content__arrow--rotate']"
+          >
+            <u-icon
+              :name="menuIcon"
+              :size="$u.addUnit(menuIconSize)"
+            ></u-icon>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view class="u-dropdown__content">
+      <slot />
+    </view>
+  </view>
 </template>
 
 <script>
-	// #ifdef APP-NVUE
-	const animation = uni.requireNativePlugin('animation')
-	const dom = uni.requireNativePlugin('dom')
-	// #endif
-	import props from './props.js';
-	/**
-	 * Drawdownitem
-	 * @description 
-	 * @tutorial url
-	 * @property {String}
-	 * @event {Function}
-	 * @example
-	 */
-	export default {
-		name: 'u-drawdown-item',
-		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
-		data() {
-			return {
-				show: false,
-				top: '126px',
-				// uni.createAnimation的导出数据
-				animationData: {},
-			}
-		},
-		mounted() {
-			this.init()
-		},
-		watch: {
-			// 发生变化时,需要去更新父组件对应的值
-			dataChange(newValue, oldValue) {
-				this.updateParentData()
-			}
-		},
-		computed: {
-			// 监听对应变量的变化
-			dataChange() {
-				return [this.title, this.disabled]
-			},
-			style() {
-				const style = {
-					zIndex: 10071,
-					position: 'fixed',
-					display: 'flex',
-					left: 0,
-					right: 0
-				}
-				style.top = uni.$u.addUnit(this.top)
-				return style
-			}
-		},
-		methods: {
-			init() {
-				this.updateParentData()
-			},
-			// 更新父组件所需的数据
-			updateParentData() {
-				// 获取父组件u-dropdown
-				this.getParentData('u-dropdown')
-				if (!this.parent) uni.$u.error('u-dropdown-item必须配合u-dropdown使用')
-				// 查找父组件menuList数组中对应的标题数据
-				const menuIndex = this.parent.menuList.findIndex(item => item.title === this.title)
-				const menuContent = {
-					title: this.title,
-					disabled: this.disabled
-				}
-				if (menuIndex >= 0) {
-					// 如果能找到,则直接修改
-					this.parent.menuList[menuIndex] = menuContent;
-				} else {
-					// 如果无法找到,则为第一次添加,直接push即可
-					this.parent.menuList.push(menuContent);
-				}
-			},
-			async setContentAnimate(height) {
-				this.animating = true
-				// #ifdef APP-NVUE
-				const ref = this.$refs['animation'].ref
-				animation.transition(ref, {
-					styles: {
-						height: uni.$u.addUnit(height)
-					},
-					duration: this.duration,
-					timingFunction: 'ease-in-out',
-				}, () => {
-					this.animating = false
-				})
-				// #endif
-			
-				// #ifndef APP-NVUE
-				const animation = uni.createAnimation({
-					timingFunction: 'ease-in-out',
-				});
-				animation
-					.height(height)
-					.step({
-						duration: this.duration,
-					})
-					.step()
-				// 导出动画数据给面板的animationData值
-				this.animationData = animation.export()
-				// 标识动画结束
-				uni.$u.sleep(this.duration).then(() => {
-					this.animating = false
-				})
-				// #endif
-			},
-			overlayClick() {
-				this.show = false
-				this.setContentAnimate(0)
-			}
-		},
-	}
+import props from './props.js';
+/**
+ * Dropdown
+ * @description
+ * @tutorial url
+ * @property {String}
+ * @event {Function}
+ * @example
+ */
+export default {
+  name: 'u-dropdown',
+  mixins: [uni.$u.mixin, props],
+  data() {
+    return {
+      // �˵�����
+      menuList: [],
+      current: 0
+    }
+  },
+  computed: {
+  
+  },
+  created() {
+    // �������������(u-dropdown-item)��this��������data������������������΢��С��������ѭ�����ö�����
+    this.children = [];
+  },
+  methods: {
+    clickHandler(item, index) {
+      this.children.map(child => {
+        if(child.title === item.title) {
+          // this.queryRect('u-dropdown__menu').then(size => {
+          child.$emit('click')
+          child.setContentAnimate(child.show ? 0 : 300)
+          child.show = !child.show
+          // })
+        } else {
+          child.show = false
+          child.setContentAnimate(0)
+        }
+      })
+    },
+    // ��ȡ��ǩ�ijߴ�λ��
+    queryRect(el) {
+      // #ifndef APP-NVUE
+      // $uGetRectΪuView�Դ��Ľڵ��ѯ�򻯷���������ĵ����ܣ�https://www.uviewui.com/js/getRect.html
+      // ����ڲ�һ����this.$uGetRect�������Ϊthis.$u.getRect�����߹���һ�£����Ʋ�ͬ
+      return new Promise(resolve => {
+        this.$uGetRect(`.${el}`).then(size => {
+          resolve(size)
+        })
+      })
+      // #endif
+      
+      // #ifdef APP-NVUE
+      // nvue�£�ʹ��domģ���ѯԪ�ظ߶�
+      // ����һ��promise���õ��ô˷�����������ʹ��then�ص�
+      return new Promise(resolve => {
+        dom.getComponentRect(this.$refs[el], res => {
+          resolve(res.size)
+        })
+      })
+      // #endif
+    },
+  },
+}
 </script>
 
-<style lang="scss" scoped>
-	@import '../../libs/css/components.scss';
-	
-	.u-drawdown-item {
-		
-		&__content {
-			background-color: #FFFFFF;
-			overflow: hidden;
-			height: 0;
-		}
-	}
+<style lang="scss">
+@import '../../libs/css/components.scss';
+
+.u-dropdown {
+  
+  &__menu {
+    @include flex;
+    
+    &__item {
+      flex: 1;
+      @include flex;
+      justify-content: center;
+      
+      &__content {
+        @include flex;
+        align-items: center;
+      }
+    }
+  }
+}
 </style>

+ 116 - 116
uview-ui/components/u-dropdown/u-dropdown.vue

@@ -1,127 +1,127 @@
 <template>
-	<view class="u-drawdown">
-		<view
-			class="u-dropdown__menu"
-			:style="{
+  <view class="u-drawdown">
+    <view
+      class="u-dropdown__menu"
+      :style="{
 				height: $u.addUnit(height)
 			}"
-			ref="u-dropdown__menu"
-		>
-			<view
-				class="u-dropdown__menu__item"
-				v-for="(item, index) in menuList"
-				:key="index"
-				@tap.stop="clickHandler(item, index)"
-			>
-				<view class="u-dropdown__menu__item__content">
-					<text
-						class="u-dropdown__menu__item__content__text"
-						:style="[index === current ? activeStyle : inactiveStyle]"
-					>{{item.title}}</text>
-					<view
-						class="u-dropdown__menu__item__content__arrow"
-						:class="[index === current && 'u-dropdown__menu__item__content__arrow--rotate']"
-					>
-						<u-icon
-							:name="menuIcon"
-							:size="$u.addUnit(menuIconSize)"
-						></u-icon>
-					</view>
-				</view>
-			</view>
-		</view>
-		<view class="u-dropdown__content">
-			<slot />
-		</view>
-	</view>
+      ref="u-dropdown__menu"
+    >
+      <view
+        class="u-dropdown__menu__item"
+        v-for="(item, index) in menuList"
+        :key="index"
+        @tap.stop="clickHandler(item, index)"
+      >
+        <view class="u-dropdown__menu__item__content">
+          <text
+            class="u-dropdown__menu__item__content__text"
+            :style="[index === current ? activeStyle : inactiveStyle]"
+          >{{item.title}}</text>
+          <view
+            class="u-dropdown__menu__item__content__arrow"
+            :class="[index === current && 'u-dropdown__menu__item__content__arrow--rotate']"
+          >
+            <u-icon
+              :name="menuIcon"
+              :size="$u.addUnit(menuIconSize)"
+            ></u-icon>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view class="u-dropdown__content">
+      <slot />
+    </view>
+  </view>
 </template>
 
 <script>
-	import props from './props.js';
-	/**
-	 * Dropdown  
-	 * @description 
-	 * @tutorial url
-	 * @property {String}
-	 * @event {Function}
-	 * @example
-	 */
-	export default {
-		name: 'u-dropdown',
-		mixins: [uni.$u.mixin, props],
-		data() {
-			return {
-				// 菜单数组
-				menuList: [],
-				current: 0
-			}
-		},
-		computed: {
-		
-		},
-		created() {
-			// 引用所有子组件(u-dropdown-item)的this,不能在data中声明变量,否则在微信小程序会造成循环引用而报错
-			this.children = [];
-		},
-		methods: {
-			clickHandler(item, index) {
-				this.children.map(child => {
-					if(child.title === item.title) {
-						// this.queryRect('u-dropdown__menu').then(size => {
-							child.$emit('click')
-							child.setContentAnimate(child.show ? 0 : 300)
-							child.show = !child.show
-						// })
-					} else {
-						child.show = false
-						child.setContentAnimate(0)
-					}
-				})
-			},
-			// 获取标签的尺寸位置
-			queryRect(el) {
-				// #ifndef APP-NVUE
-				// $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://www.uviewui.com/js/getRect.html
-				// 组件内部一般用this.$uGetRect,对外的为this.$u.getRect,二者功能一致,名称不
-				return new Promise(resolve => {
-					this.$uGetRect(`.${el}`).then(size => {
-						resolve(size)
-					})
-				})
-				// #endif
-			
-				// #ifdef APP-NVUE 
-				// nvue下,使用dom模块查询元素高度
-				// 返回一个promise,让调用此方法的主体能使用then回调
-				return new Promise(resolve => {
-					dom.getComponentRect(this.$refs[el], res => {
-						resolve(res.size)
-					})
-				})
-				// #endif
-			},
-		},
-	}
+import props from './props.js';
+/**
+ * Dropdown
+ * @description
+ * @tutorial url
+ * @property {String}
+ * @event {Function}
+ * @example
+ */
+export default {
+  name: 'u-dropdown',
+  mixins: [uni.$u.mixin, props],
+  data() {
+    return {
+      // 锟剿碉拷锟斤拷锟斤拷
+      menuList: [],
+      current: 0
+    }
+  },
+  computed: {
+  
+  },
+  created() {
+    // 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟�(u-dropdown-item)锟斤拷this锟斤拷锟斤拷锟斤拷锟斤拷data锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷小锟斤拷锟斤拷锟斤拷锟斤拷循锟斤拷锟斤拷锟矫讹拷锟斤拷锟斤拷
+    this.children = [];
+  },
+  methods: {
+    clickHandler(item, index) {
+      this.children.map(child => {
+        if(child.title === item.title) {
+          // this.queryRect('u-dropdown__menu').then(size => {
+          child.$emit('click')
+          child.setContentAnimate(child.show ? 0 : 300)
+          child.show = !child.show
+          // })
+        } else {
+          child.show = false
+          child.setContentAnimate(0)
+        }
+      })
+    },
+    // 锟斤拷取锟斤拷签锟侥尺达拷位锟斤拷
+    queryRect(el) {
+      // #ifndef APP-NVUE
+      // $uGetRect为uView锟皆达拷锟侥节碉拷锟窖�拷蚧�锟斤拷锟斤拷锟斤拷锟斤拷锟侥碉拷锟斤拷锟杰o拷https://www.uviewui.com/js/getRect.html
+      // 锟斤拷锟斤拷诓锟揭伙拷锟斤拷锟絫his.$uGetRect锟斤拷锟斤拷锟斤拷锟轿猼his.$u.getRect锟斤拷锟斤拷锟竭癸拷锟斤拷一锟铰o拷锟斤拷锟狡诧拷
+      return new Promise(resolve => {
+        this.$uGetRect(`.${el}`).then(size => {
+          resolve(size)
+        })
+      })
+      // #endif
+      
+      // #ifdef APP-NVUE
+      // nvue锟铰o拷使锟斤拷dom模锟斤拷锟窖��拷馗叨锟�
+      // 锟斤拷锟斤拷一锟斤拷promise锟斤拷锟矫碉拷锟矫此凤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷使锟斤拷then锟截碉拷
+      return new Promise(resolve => {
+        dom.getComponentRect(this.$refs[el], res => {
+          resolve(res.size)
+        })
+      })
+      // #endif
+    },
+  },
+}
 </script>
 
 <style lang="scss">
-	@import '../../libs/css/components.scss';
+@import '../../libs/css/components.scss';
 
-	.u-dropdown {
-
-		&__menu {
-			@include flex;
-
-			&__item {
-				flex: 1;
-				@include flex;
-				justify-content: center;
-
-				&__content {
-					@include flex;
-					align-items: center;
-				}
-			}
-		}
-	}
+.u-dropdown {
+  
+  &__menu {
+    @include flex;
+    
+    &__item {
+      flex: 1;
+      @include flex;
+      justify-content: center;
+      
+      &__content {
+        @include flex;
+        align-items: center;
+      }
+    }
+  }
+}
 </style>

+ 0 - 384
uview-ui/components/u-field/u-field.vue

@@ -1,384 +0,0 @@
-<template>
-	<view class="u-field" :class="{'u-border-top': borderTop, 'u-border-bottom': borderBottom }">
-		<view class="u-field-inner" :class="[type == 'textarea' ? 'u-textarea-inner' : '', 'u-label-postion-' + labelPosition]">
-			<view class="u-label" :class="[required ? 'u-required' : '']" :style="{
-				justifyContent: justifyContent, 
-				flex: labelPosition == 'left' ? `0 0 ${labelWidth}rpx` : '1'
-			}">
-				<view class="u-icon-wrap" v-if="icon">
-					<u-icon size="32" :custom-style="iconStyle" :name="icon" :color="iconColor" class="u-icon"></u-icon>
-				</view>
-				<slot name="icon"></slot>
-				<text class="u-label-text" :class="[this.$slots.icon || icon ? 'u-label-left-gap' : '']">{{ label }}</text>
-			</view>
-			<view class="fild-body">
-				<view class="u-flex-1 u-flex" :style="[inputWrapStyle]">
-					<textarea v-if="type == 'textarea'" class="u-flex-1 u-textarea-class" :style="[fieldStyle]" :value="value"
-					 :placeholder="placeholder" :placeholderStyle="placeholderStyle" :disabled="disabled" :maxlength="inputMaxlength"
-					 :focus="focus" :autoHeight="autoHeight" :fixed="fixed" @input="onInput" @blur="onBlur" @focus="onFocus" @confirm="onConfirm"
-					 @tap="fieldClick" />
-					<input
-						v-else
-						:style="[fieldStyle]"
-						:type="type"
-						class="u-flex-1 u-field__input-wrap"
-						:value="value"
-						:password="password || this.type === 'password'"
-						:placeholder="placeholder"
-						:placeholderStyle="placeholderStyle"
-						:disabled="disabled"
-						:maxlength="inputMaxlength"
-						:focus="focus"
-						:confirmType="confirmType"
-						@focus="onFocus"
-						@blur="onBlur"
-						@input="onInput"
-						@confirm="onConfirm"
-						@tap="fieldClick"
-					/>
-				</view>
-				<u-icon :size="clearSize" v-if="clearable && value != '' && focused" name="close-circle-fill" color="#c0c4cc" class="u-clear-icon" @click="onClear"/>
-				<view class="u-button-wrap"><slot name="right" /></view>
-				<u-icon v-if="rightIcon" @click="rightIconClick" :name="rightIcon" color="#c0c4cc" :style="[rightIconStyle]" size="26" class="u-arror-right" />
-			</view>
-		</view>
-		<view v-if="errorMessage !== false && errorMessage != ''" class="u-error-message" :style="{
-			paddingLeft: labelWidth + 'rpx'
-		}">{{ errorMessage }}</view>
-	</view>
-</template>
-
-<script>
-/**
- * field 输入框
- * @description 借助此组件,可以实现表单的输入, 有"text"和"textarea"类型的,此外,借助uView的picker和actionSheet组件可以快速实现上拉菜单,时间,地区选择等, 为表单解决方案的利器。
- * @tutorial https://www.uviewui.com/components/field.html
- * @property {String} type 输入框的类型(默认text)
- * @property {String} icon label左边的图标,限uView的图标名称
- * @property {Object} icon-style 左边图标的样式,对象形式
- * @property {Boolean} right-icon 输入框右边的图标名称,限uView的图标名称(默认false)
- * @property {Boolean} required 是否必填,左边您显示红色"*"号(默认false)
- * @property {String} label 输入框左边的文字提示
- * @property {Boolean} password 是否密码输入方式(用点替换文字),type为text时有效(默认false)
- * @property {Boolean} clearable 是否显示右侧清空内容的图标控件(输入框有内容,且获得焦点时才显示),点击可清空输入框内容(默认true)
- * @property {Number String} label-width label的宽度,单位rpx(默认130)
- * @property {String} label-align label的文字对齐方式(默认left)
- * @property {Object} field-style 自定义输入框的样式,对象形式
- * @property {Number | String} clear-size 清除图标的大小,单位rpx(默认30)
- * @property {String} input-align 输入框内容对齐方式(默认left)
- * @property {Boolean} border-bottom 是否显示field的下边框(默认true)
- * @property {Boolean} border-top 是否显示field的上边框(默认false)
- * @property {String} icon-color 左边通过icon配置的图标的颜色(默认#606266)
- * @property {Boolean} auto-height 是否自动增高输入区域,type为textarea时有效(默认true)
- * @property {String Boolean} error-message 显示的错误提示内容,如果为空字符串或者false,则不显示错误信息
- * @property {String} placeholder 输入框的提示文字
- * @property {String} placeholder-style placeholder的样式(内联样式,字符串),如"color: #ddd"
- * @property {Boolean} focus 是否自动获得焦点(默认false)
- * @property {Boolean} fixed 如果type为textarea,且在一个"position:fixed"的区域,需要指明为true(默认false)
- * @property {Boolean} disabled 是否不可输入(默认false)
- * @property {Number String} maxlength 最大输入长度,设置为 -1 的时候不限制最大长度(默认140)
- * @property {String} confirm-type 设置键盘右下角按钮的文字,仅在type="text"时生效(默认done)
- * @event {Function} input 输入框内容发生变化时触发
- * @event {Function} focus 输入框获得焦点时触发
- * @event {Function} blur 输入框失去焦点时触发
- * @event {Function} confirm 点击完成按钮时触发
- * @event {Function} right-icon-click 通过right-icon生成的图标被点击时触发
- * @event {Function} click 输入框被点击或者通过right-icon生成的图标被点击时触发,这样设计是考虑到传递右边的图标,一般都为需要弹出"picker"等操作时的场景,点击倒三角图标,理应发出此事件,见上方说明
- * @example <u-field v-model="mobile" label="手机号" required :error-message="errorMessage"></u-field>
- */
-export default {
-	name:"u-field",
-	props: {
-		icon: String,
-		rightIcon: String,
-		// arrowDirection: {
-		// 	type: String,
-		// 	default: 'right'
-		// },
-		required: Boolean,
-		label: String,
-		password: Boolean,
-		clearable: {
-			type: Boolean,
-			default: true
-		},
-		// 左边标题的宽度单位rpx
-		labelWidth: {
-			type: [Number, String],
-			default: 130
-		},
-		// 对齐方式,left|center|right
-		labelAlign: {
-			type: String,
-			default: 'left'
-		},
-		inputAlign: {
-			type: String,
-			default: 'left'
-		},
-		iconColor: {
-			type: String,
-			default: '#606266'
-		},
-		autoHeight: {
-			type: Boolean,
-			default: true
-		},
-		errorMessage: {
-			type: [String, Boolean],
-			default: ''
-		},
-		placeholder: String,
-		placeholderStyle: String,
-		focus: Boolean,
-		fixed: Boolean,
-		value: [Number, String],
-		type: {
-			type: String,
-			default: 'text'
-		},
-		disabled: {
-			type: Boolean,
-			default: false
-		},
-		maxlength: {
-			type: [Number, String],
-			default: 140
-		},
-		confirmType: {
-			type: String,
-			default: 'done'
-		},
-		// lable的位置,可选为 left-左边,top-上边
-		labelPosition: {
-			type: String,
-			default: 'left'
-		},
-		// 输入框的自定义样式
-		fieldStyle: {
-			type: Object,
-			default() {
-				return {}
-			}
-		},
-		// 清除按钮的大小
-		clearSize: {
-			type: [Number, String],
-			default: 30
-		},
-		// lable左边的图标样式,对象形式
-		iconStyle: {
-			type: Object,
-			default() {
-				return {}
-			}
-		},
-		// 是否显示上边框
-		borderTop: {
-			type: Boolean,
-			default: false
-		},
-		// 是否显示下边框
-		borderBottom: {
-			type: Boolean,
-			default: true
-		},
-		// 是否自动去除两端的空格
-		trim: {
-			type: Boolean,
-			default: true
-		}
-	},
-	data() {
-		return {
-			focused: false,
-			itemIndex: 0,
-		};
-	},
-	computed: {
-		inputWrapStyle() {
-			let style = {};
-			style.textAlign = this.inputAlign;
-			// 判断lable的位置,如果是left的话,让input左边两边有间隙
-			if(this.labelPosition == 'left') {
-				style.margin = `0 8rpx`;
-			} else {
-				// 如果lable是top的,input的左边就没必要有间隙了
-				style.marginRight = `8rpx`;
-			}
-			return style;
-		},
-		rightIconStyle() {
-			let style = {};
-			if (this.arrowDirection == 'top') style.transform = 'roate(-90deg)';
-			if (this.arrowDirection == 'bottom') style.transform = 'roate(90deg)';
-			else style.transform = 'roate(0deg)';
-			return style;
-		},
-		labelStyle() {
-			let style = {};
-			if(this.labelAlign == 'left') style.justifyContent = 'flext-start';
-			if(this.labelAlign == 'center') style.justifyContent = 'center';
-			if(this.labelAlign == 'right') style.justifyContent = 'flext-end';
-			return style;
-		},
-		// uni不支持在computed中写style.justifyContent = 'center'的形式,故用此方法
-		justifyContent() {
-			if(this.labelAlign == 'left') return 'flex-start';
-			if(this.labelAlign == 'center') return 'center';
-			if(this.labelAlign == 'right') return 'flex-end';
-		},
-		// 因为uniapp的input组件的maxlength组件必须要数值,这里转为数值,给用户可以传入字符串数值
-		inputMaxlength() {
-			return Number(this.maxlength)
-		},
-		// label的位置
-		fieldInnerStyle() {
-			let style = {};
-			if(this.labelPosition == 'left') {
-				style.flexDirection = 'row';
-			} else {
-				style.flexDirection = 'column';
-			}
-			
-			return style;
-		}
-	},
-	methods: {
-		onInput(event) {
-			let value = event.detail.value;
-			// 判断是否去除空格
-			if(this.trim) value = this.$u.trim(value);
-			this.$emit('input', value);
-		},
-		onFocus(event) {
-			this.focused = true;
-			this.$emit('focus', event);
-		},
-		onBlur(event) {
-			// 最开始使用的是监听图标@touchstart事件,自从hx2.8.4后,此方法在微信小程序出错
-			// 这里改为监听点击事件,手点击清除图标时,同时也发生了@blur事件,导致图标消失而无法点击,这里做一个延时
-			setTimeout(() => {
-				this.focused = false;
-			}, 100)
-			this.$emit('blur', event);
-		},
-		onConfirm(e) {
-			this.$emit('confirm', e.detail.value);
-		},
-		onClear(event) {
-			this.$emit('input', '');
-		},
-		rightIconClick() {
-			this.$emit('right-icon-click');
-			this.$emit('click');
-		},
-		fieldClick() {
-			this.$emit('click');
-		}
-	}
-};
-</script>
-
-<style lang="scss" scoped>
-@import "../../libs/css/style.components.scss";
-	
-.u-field {
-	font-size: 28rpx;
-	padding: 20rpx 28rpx;
-	text-align: left;
-	position: relative;
-	color: $u-main-color;
-}
-
-.u-field-inner {
-	@include vue-flex;
-	align-items: center;
-}
-
-.u-textarea-inner {
-	align-items: flex-start;
-}
-
-.u-textarea-class {
-	min-height: 96rpx;
-	width: auto;
-	font-size: 28rpx;
-}
-
-.fild-body {
-	@include vue-flex;
-	flex: 1;
-	align-items: center;
-}
-
-.u-arror-right {
-	margin-left: 8rpx;
-}
-
-.u-label-text {
-	/* #ifndef APP-NVUE */
-	display: inline-flex;		
-	/* #endif */
-}
-
-.u-label-left-gap {
-	margin-left: 6rpx;
-}
-
-.u-label-postion-top {
-	flex-direction: column;
-	align-items: flex-start;
-}
-
-.u-label {
-	width: 130rpx;
-	flex: 1 1 130rpx;
-	text-align: left;
-	position: relative;
-	@include vue-flex;
-	align-items: center;
-}
-
-.u-required::before {
-	content: '*';
-	position: absolute;
-	left: -16rpx;
-	font-size: 14px;
-	color: $u-type-error;
-	height: 9px;
-	line-height: 1;
-}
-
-.u-field__input-wrap {
-	position: relative;
-	overflow: hidden;
-	font-size: 28rpx;
-	height: 48rpx;
-	flex: 1;
-	width: auto;
-}
-
-.u-clear-icon {
-	@include vue-flex;
-	align-items: center;
-}
-
-.u-error-message {
-	color: $u-type-error;
-	font-size: 26rpx;
-	text-align: left;
-}
-
-.placeholder-style {
-	color: rgb(150, 151, 153);
-}
-
-.u-input-class {
-	font-size: 28rpx;
-}
-
-.u-button-wrap {
-	margin-left: 8rpx;
-}
-</style>

+ 9 - 0
uview-ui/components/u-form-item/props.js

@@ -15,6 +15,11 @@ export default {
             type: [String, Boolean],
             default: uni.$u.props.formItem.borderBottom
         },
+        // label的位置,left-左边,top-上边
+        labelPosition: {
+            type: String,
+            default: uni.$u.props.formItem.labelPosition
+        },
         // label的宽度,单位px
         labelWidth: {
             type: [String, Number],
@@ -34,6 +39,10 @@ export default {
         required: {
             type: Boolean,
             default: uni.$u.props.formItem.required
+        },
+        leftIconStyle: {
+            type: [String, Object],
+            default: uni.$u.props.formItem.leftIconStyle,
         }
     }
 }

+ 3 - 2
uview-ui/components/u-form-item/u-form-item.vue

@@ -4,7 +4,7 @@
 			class="u-form-item__body"
 			@tap="clickHandler"
 			:style="[$u.addStyle(customStyle), {
-				flexDirection: parentData.labelPosition === 'left' ? 'row' : 'column'
+				flexDirection: (labelPosition || parentData.labelPosition) === 'left' ? 'row' : 'column'
 			}]"
 		>
 			<!-- 微信小程序中,将一个参数设置空字符串,结果会变成字符串"true" -->
@@ -69,7 +69,7 @@
 		<u-line
 			v-if="borderBottom"
 			:color="message && parentData.errorType === 'border-bottom' ? $u.color.error : propsLine.color"
-			:customStyle="`margin-top: ${message ? '5px' : 0}`"
+			:customStyle="`margin-top: ${message && parentData.errorType === 'message' ? '5px' : 0}`"
 		></u-line>
 	</view>
 </template>
@@ -86,6 +86,7 @@
 	 * @property {String | Number}	labelWidth		label的宽度,单位px
 	 * @property {String}			rightIcon		右侧图标
 	 * @property {String}			leftIcon		左侧图标
+	 * @property {String | Object} leftIconStyle 左侧图标的样式
 	 * @property {Boolean}			required		是否显示左边的必填星号,只作显示用,具体校验必填的逻辑,请在rules中配置 (默认 false )
 	 *
 	 * @example <u-form-item label="姓名" prop="userInfo.name" borderBottom ref="item1"></u-form-item>

+ 8 - 7
uview-ui/components/u-form/u-form.vue

@@ -90,8 +90,8 @@
 			setRules(rules) {
 				// 判断是否有规则
 				if (Object.keys(rules).length === 0) return;
-				if (Object.keys(this.model).length === 0) {
-					uni.$u.error('设置rules,model必须设置!');
+				if (process.env.NODE_ENV === 'development' && Object.keys(this.model).length === 0) {
+					uni.$u.error('设置rules,model必须设置!如果已经设置,请刷新页面。');
 					return;
 				};
 				this.formRules = rules;
@@ -116,17 +116,13 @@
 				props = [].concat(props);
 				this.children.map((child) => {
 					// 如果u-form-item的prop在props数组中,则清除对应的校验结果信息
-					if (props.includes(child.props)) {
+					if (props[0] === undefined || props.includes(child.prop)) {
 						child.message = null;
 					}
 				});
 			},
 			// 对部分表单字段进行校验
 			async validateField(value, callback, event = null) {
-				if (Object.keys(this.formRules).length === 0) {
-					uni.$u.error('未设置rules,请看文档说明!');
-					return;
-				}
 				// $nextTick是必须的,否则model的变更,可能会延后于此方法的执行
 				this.$nextTick(() => {
 					// 校验错误信息,返回给回调方法,用于存放所有form-item的错误信息
@@ -186,6 +182,11 @@
 			},
 			// 校验全部数据
 			validate(callback) {
+				// 开发环境才提示,生产环境不会提示
+				if (process.env.NODE_ENV === 'development' && Object.keys(this.formRules).length === 0) {
+					uni.$u.error('未设置rules,请看文档说明!如果已经设置,请刷新页面。');
+					return;
+				}
 				return new Promise((resolve, reject) => {
 					// $nextTick是必须的,否则model的变更,可能会延后于validate方法
 					this.$nextTick(() => {

+ 0 - 52
uview-ui/components/u-full-screen/u-full-screen.vue

@@ -1,52 +0,0 @@
-<template>
-	<u-modal v-model="show" :show-cancel-button="true" confirm-text="升级" title="发现新版本" @cancel="cancel" @confirm="confirm">
-		<view class="u-update-content">
-			<rich-text :nodes="content"></rich-text>
-		</view>
-	</u-modal>
-</template>
-
-<script>
-	export default {
-		data() {
-			return {
-				show: false,
-				content: `
-					1. 修复badge组件的size参数无效问题<br>
-					2. 新增Modal模态框组件<br>
-					3. 新增压窗屏组件,可以在APP上以弹窗的形式遮盖导航栏和底部tabbar<br>
-					4. 修复键盘组件在微信小程序上遮罩无效的问题
-				`,
-			}
-		},
-		onReady() {
-			this.show = true;
-		},
-		methods: {
-			cancel() {
-				this.closeModal();
-			},
-			confirm() {
-				this.closeModal();
-			},
-			closeModal() {
-				uni.navigateBack();
-			}
-		}
-	}
-</script>
-
-<style scoped lang="scss">
-	@import "../../libs/css/style.components.scss";
-	
-	.u-full-content {
-		background-color: #00C777;
-	}
-	
-	.u-update-content {
-		font-size: 26rpx;
-		color: $u-content-color;
-		line-height: 1.7;
-		padding: 30rpx;
-	}
-</style>

+ 12 - 4
uview-ui/components/u-image/u-image.vue

@@ -119,8 +119,8 @@
 						this.isError = true
 						
 					} else {
-						this.isError = false
-						this.loading = false
+						this.isError = false;
+						this.loading = true;
 					}
 				}
 			}
@@ -128,6 +128,9 @@
 		computed: {
 			wrapStyle() {
 				let style = {};
+				// 通过调用addUnit()方法,如果有单位,如百分比,px单位等,直接返回,如果是纯粹的数值,则加上rpx单位
+				style.width = this.$u.addUnit(this.width);
+				style.height = this.$u.addUnit(this.height);
 				// 如果是显示圆形,设置一个很多的半径值即可
 				style.borderRadius = this.shape == 'circle' ? '10000px' : uni.$u.addUnit(this.radius)
 				// 如果设置圆角,必须要有hidden,否则可能圆角无效
@@ -158,10 +161,10 @@
 				this.$emit('error', err)
 			},
 			// 图片加载完成,标记loading结束
-			onLoadHandler() {
+			onLoadHandler(event) {
 				this.loading = false
 				this.isError = false
-				this.$emit('load')
+				this.$emit('load', event)
 				this.removeBgColor()
 				// 如果不需要动画效果,就不执行下方代码,同时移除加载时的背景颜色
 				// 否则无需fade效果时,png图片依然能看到下方的背景色
@@ -206,6 +209,11 @@
 		position: relative;
 		transition: opacity 0.5s ease-in-out;
 
+		&__image {
+			width: 100%;
+			height: 100%;
+		}
+
 		&__loading,
 		&__error {
 			position: absolute;

+ 2 - 2
uview-ui/components/u-index-list/u-index-list.vue

@@ -18,7 +18,7 @@
 				<slot name="header" />
 			</cell>
 			<slot />
-			<cell v-if="$slots.header">
+			<cell v-if="$slots.footer">
 				<slot name="footer" />
 			</cell>
 		</list>
@@ -39,7 +39,7 @@
 				<slot name="header" />
 			</view>
 			<slot />
-			<view v-if="$slots.header">
+			<view v-if="$slots.footer">
 				<slot name="footer" />
 			</view>
 		</scroll-view>

+ 5 - 0
uview-ui/components/u-input/props.js

@@ -177,6 +177,11 @@ export default {
 		formatter: {
 			type: [Function, null],
 			default: uni.$u.props.input.formatter
+		},
+		// 是否忽略组件内对文本合成系统事件的处理
+		ignoreCompositionEvent: {
+			type: Boolean,
+			default: true
 		}
 	}
 }

+ 3 - 4
uview-ui/components/u-input/u-input.vue

@@ -38,6 +38,7 @@
             	    :selection-end="selectionEnd"
             	    :selection-start="selectionStart"
             	    :password="password || type === 'password' || undefined"
+                    :ignoreCompositionEvent="ignoreCompositionEvent"
             	    @input="onInput"
             	    @blur="onBlur"
             	    @focus="onFocus"
@@ -114,7 +115,7 @@ import props from "./props.js";
  * @property {Boolean}			readonly				是否只读,与disabled不同之处在于disabled会置灰组件,而readonly则不会 ( 默认 false )
  * @property {String}			shape					输入框形状,circle-圆形,square-方形 ( 默认 'square' )
  * @property {Object}			customStyle				定义需要用到的外部样式
- *
+ * @property {Boolean}			ignoreCompositionEvent	是否忽略组件内对文本合成系统事件的处理。
  * @example <u-input v-model="value" :password="true" suffix-icon="lock-fill" />
  */
 export default {
@@ -287,9 +288,7 @@ export default {
 
 <style lang="scss" scoped>
 @import "../../libs/css/components.scss";
-.u-border{
-	border: none;
-}
+
 .u-input {
     @include flex(row);
     align-items: center;

File diff suppressed because it is too large
+ 0 - 57
uview-ui/components/u-lazy-load/u-lazy-load.vue


+ 1 - 1
uview-ui/components/u-line/props.js

@@ -24,7 +24,7 @@ export default {
             type: [String, Number],
             default: uni.$u.props.line.margin
         },
-        // 是否虚线,true-实线,false-虚线
+        // 是否虚线,true-虚线,false-实线
         dashed: {
             type: Boolean,
             default: uni.$u.props.line.dashed

+ 2 - 4
uview-ui/components/u-list/u-list.vue

@@ -29,9 +29,7 @@
 		@scrolltolower="scrolltolower"
 		@scrolltoupper="scrolltoupper"
 	>
-		<view :style="{
-			paddingTop: `${offset}px`
-		}">
+		<view>
 			<slot />
 		</view>
 	</scroll-view>
@@ -139,7 +137,7 @@
 			// 滚动到底部时触发,非nvue有效
 			scrolltoupper(e) {
 				uni.$u.sleep(30).then(() => {
-					this.$emit('scrolltolower')
+					this.$emit('scrolltoupper')
 					// 这一句很重要,能绝对保证在性功能障碍的webview,滚动条到顶时,取消偏移值,让页面置顶
 					this.offset = 0
 				})

+ 5 - 0
uview-ui/components/u-loading-page/props.js

@@ -35,6 +35,11 @@ export default {
             type: [String, Number],
             default: uni.$u.props.loadingPage.fontSize
         },
+		// 图标大小
+		iconSize: {
+		    type: [String, Number],
+		    default: uni.$u.props.loadingPage.fontSize
+		},
         // 加载中图标的颜色,只能rgb或者十六进制颜色值
         loadingColor: {
             type: String,

+ 6 - 1
uview-ui/components/u-loading-page/u-loading-page.vue

@@ -19,11 +19,15 @@
                         :src="image"
                         class="u-loading-page__warpper__loading-icon__img"
                         mode="widthFit"
+						:style="{
+							width: $u.addUnit(iconSize),
+						    height: $u.addUnit(iconSize)
+						}"
                     ></image>
                     <u-loading-icon
                         v-else
                         :mode="loadingMode"
-                        size="28"
+                        :size="$u.addUnit(iconSize)"
                         :color="loadingColor"
                     ></u-loading-icon>
                 </view>
@@ -55,6 +59,7 @@ import props from "./props.js";
  * @property {String}			bgColor			背景色 (默认 '#ffffff' )
  * @property {String}			color			文字颜色 (默认 '#C8C8C8' )
  * @property {String | Number}	fontSize		文字大小 (默认 19 )
+ * @property {String | Number}	iconSize		图标大小 (默认 28 )
  * @property {String}			loadingColor	加载中图标的颜色,只能rgb或者十六进制颜色值 (默认 '#C8C8C8' )
  * @property {Object}			customStyle		自定义样式
  * @example <u-loading mode="circle"></u-loading>

+ 0 - 103
uview-ui/components/u-loading/u-loading.vue

@@ -1,103 +0,0 @@
-<template>
-	<view v-if="show" class="u-loading" :class="mode == 'circle' ? 'u-loading-circle' : 'u-loading-flower'" :style="[cricleStyle]">
-	</view>
-</template>
-
-<script>
-	/**
-	 * loading 加载动画
-	 * @description 警此组件为一个小动画,目前用在uView的loadmore加载更多和switch开关等组件的正在加载状态场景。
-	 * @tutorial https://www.uviewui.com/components/loading.html
-	 * @property {String} mode 模式选择,见官网说明(默认circle)
-	 * @property {String} color 动画活动区域的颜色,只对 mode = flower 模式有效(默认#c7c7c7)
-	 * @property {String Number} size 加载图标的大小,单位rpx(默认34)
-	 * @property {Boolean} show 是否显示动画(默认true)
-	 * @example <u-loading mode="circle"></u-loading>
-	 */
-	export default {
-		name: "u-loading",
-		props: {
-			// 动画的类型
-			mode: {
-				type: String,
-				default: 'circle'
-			},
-			// 动画的颜色
-			color: {
-				type: String,
-				default: '#c7c7c7'
-			},
-			// 加载图标的大小,单位rpx
-			size: {
-				type: [String, Number],
-				default: '34'
-			},
-			// 是否显示动画
-			show: {
-				type: Boolean,
-				default: true
-			}
-		},
-		computed: {
-			// 加载中圆圈动画的样式
-			cricleStyle() {
-				let style = {};
-				style.width = this.size + 'rpx';
-				style.height = this.size + 'rpx';
-				if (this.mode == 'circle') style.borderColor = `#e4e4e4 #e4e4e4 #e4e4e4 ${this.color ? this.color : '#c7c7c7'}`;
-				return style;
-			},
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-	
-	.u-loading-circle {
-		/* #ifndef APP-NVUE */
-		display: inline-flex;
-		/* #endif */
-		vertical-align: middle;
-		width: 28rpx;
-		height: 28rpx;
-		background: 0 0;
-		border-radius: 50%;
-		border: 2px solid;
-		border-color: #e5e5e5 #e5e5e5 #e5e5e5 #8f8d8e;
-		animation: u-circle 1s linear infinite;
-	}
-
-	.u-loading-flower {
-		width: 20px;
-		height: 20px;
-		display: inline-block;
-		vertical-align: middle;
-		-webkit-animation: a 1s steps(12) infinite;
-		animation: u-flower 1s steps(12) infinite;
-		background: transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=) no-repeat;
-		background-size: 100%;
-	}
-
-	@keyframes u-flower {
-		0% {
-			-webkit-transform: rotate(0deg);
-			transform: rotate(0deg);
-		}
-
-		to {
-			-webkit-transform: rotate(1turn);
-			transform: rotate(1turn);
-		}
-	}
-
-	@-webkit-keyframes u-circle {
-		0% {
-			transform: rotate(0);
-		}
-
-		100% {
-			transform: rotate(360deg);
-		}
-	}
-</style>

+ 15 - 1
uview-ui/components/u-loadmore/props.js

@@ -20,12 +20,16 @@ export default {
             type: [String, Number],
             default: uni.$u.props.loadmore.fontSize
         },
+		    // 图标大小
+        iconSize: {
+            type: [String, Number],
+            default: uni.$u.props.loadmore.iconSize
+        },
         // 字体颜色
         color: {
             type: String,
             default: uni.$u.props.loadmore.color
         },
-
         // 加载中状态的图标,spinner-花朵状图标,circle-圆圈状,semicircle-半圆
         loadingIcon: {
             type: String,
@@ -75,6 +79,16 @@ export default {
         line: {
             type: Boolean,
             default: uni.$u.props.loadmore.line
+        },
+        // 线条颜色
+        lineColor: {
+            type: String,
+            default: uni.$u.props.loadmore.lineColor
+        },
+        // 是否虚线,true-虚线,false-实线
+        dashed: {
+            type: Boolean,
+            default: uni.$u.props.loadmore.dashed
         }
     }
 }

+ 9 - 4
uview-ui/components/u-loadmore/u-loadmore.vue

@@ -13,8 +13,9 @@
 	>
 		<u-line
 		    length="140rpx"
-		    color="#E6E8EB"
+		    :color="lineColor"
 		    :hairline="false"
+			:dashed="dashed"
 			v-if="line"
 		></u-line>
 		<!-- 加载中和没有更多的状态才显示两边的横线 -->
@@ -28,7 +29,7 @@
 			>
 				<u-loading-icon
 				    :color="iconColor"
-				    size="17"
+				    :size="iconSize"
 				    :mode="loadingIcon"
 				></u-loading-icon>
 			</view>
@@ -42,8 +43,9 @@
 		</view>
 		<u-line
 		    length="140rpx"
-		    color="#E6E8EB"
+		    :color="lineColor"
 			:hairline="false"
+			:dashed="dashed"
 			v-if="line"
 		></u-line>
 	</view>
@@ -60,17 +62,20 @@
 	 * @property {String}			bgColor			组件背景颜色,在页面是非白色时会用到(默认 'transparent' )
 	 * @property {Boolean}			icon			加载中时是否显示图标(默认 true )
 	 * @property {String | Number}	fontSize		字体大小(默认 14 )
+	 * @property {String | Number}	iconSize		图标大小(默认 17 )
 	 * @property {String}			color			字体颜色(默认 '#606266' )
-	 * @property {String}			loadingIcon		加载前的提示语(默认 'circle' )
+	 * @property {String}			loadingIcon		加载图标(默认 'circle' )
 	 * @property {String}			loadmoreText	加载前的提示语(默认 '加载更多' )
 	 * @property {String}			loadingText		加载中提示语(默认 '正在加载...' )
 	 * @property {String}			nomoreText		没有更多的提示语(默认 '没有更多了' )
 	 * @property {Boolean}			isDot			到上一个相邻元素的距离 (默认 false )
 	 * @property {String}			iconColor		加载中图标的颜色 (默认 '#b7b7b7' )
+	 * @property {String}			lineColor		线条颜色(默认 #E6E8EB )
 	 * @property {String | Number}	marginTop		上边距 (默认 10 )
 	 * @property {String | Number}	marginBottom	下边距 (默认 10 )
 	 * @property {String | Number}	height			高度,单位px (默认 'auto' )
 	 * @property {Boolean}			line			是否显示左边分割线  (默认 false )
+	 * @property {Boolean}			dashed		// 是否虚线,true-虚线,false-实线  (默认 false )
 	 * @event {Function} loadmore status为loadmore时,点击组件会发出此事件
 	 * @example <u-loadmore :status="status" icon-type="iconType" load-text="loadText" />
 	 */

+ 0 - 123
uview-ui/components/u-mask/u-mask.vue

@@ -1,123 +0,0 @@
-<template>
-	<view class="u-mask" hover-stop-propagation :style="[maskStyle, zoomStyle]" @tap="click" @touchmove.stop.prevent="() => {}" :class="{
-		'u-mask-zoom': zoom,
-		'u-mask-show': show
-	}">
-		<slot />
-	</view>
-</template>
-
-<script>
-	/**
-	 * mask 遮罩
-	 * @description 创建一个遮罩层,用于强调特定的页面元素,并阻止用户对遮罩下层的内容进行操作,一般用于弹窗场景
-	 * @tutorial https://www.uviewui.com/components/mask.html
-	 * @property {Boolean} show 是否显示遮罩(默认false)
-	 * @property {String Number} z-index z-index 层级(默认1070)
-	 * @property {Object} custom-style 自定义样式对象,见上方说明
-	 * @property {String Number} duration 动画时长,单位毫秒(默认300)
-	 * @property {Boolean} zoom 是否使用scale对遮罩进行缩放(默认true)
-	 * @property {Boolean} mask-click-able 遮罩是否可点击,为false时点击不会发送click事件(默认true)
-	 * @event {Function} click mask-click-able为true时,点击遮罩发送此事件
-	 * @example <u-mask :show="show" @click="show = false"></u-mask>
-	 */
-	export default {
-		name: "u-mask",
-		props: {
-			// 是否显示遮罩
-			show: {
-				type: Boolean,
-				default: false
-			},
-			// 层级z-index
-			zIndex: {
-				type: [Number, String],
-				default: ''
-			},
-			// 用户自定义样式
-			customStyle: {
-				type: Object,
-				default () {
-					return {}
-				}
-			},
-			// 遮罩的动画样式, 是否使用使用zoom进行scale进行缩放
-			zoom: {
-				type: Boolean,
-				default: true
-			},
-			// 遮罩的过渡时间,单位为ms
-			duration: {
-				type: [Number, String],
-				default: 300
-			},
-			// 是否可以通过点击遮罩进行关闭
-			maskClickAble: {
-				type: Boolean,
-				default: true
-			}
-		},
-		data() {
-			return {
-				zoomStyle: {
-					transform: ''
-				},
-				scale: 'scale(1.2, 1.2)'
-			}
-		},
-		watch: {
-			show(n) {
-				if(n && this.zoom) {
-					// 当展示遮罩的时候,设置scale为1,达到缩小(原来为1.2)的效果
-					this.zoomStyle.transform = 'scale(1, 1)';
-				} else if(!n && this.zoom) {
-					// 当隐藏遮罩的时候,设置scale为1.2,达到放大(因为显示遮罩时已重置为1)的效果
-					this.zoomStyle.transform = this.scale;
-				}
-			}
-		},
-		computed: {
-			maskStyle() {
-				let style = {};
-				style.backgroundColor = "rgba(0, 0, 0, 0.6)";
-				if(this.show) style.zIndex = this.zIndex ? this.zIndex : this.$u.zIndex.mask;
-				else style.zIndex = -1;
-				style.transition = `all ${this.duration / 1000}s ease-in-out`;
-				// 判断用户传递的对象是否为空,不为空就进行合并
-				if (Object.keys(this.customStyle).length) style = { 
-					...style,
-					...this.customStyle
-				};
-				return style;
-			}
-		},
-		methods: {
-			click() {
-				if (!this.maskClickAble) return;
-				this.$emit('click');
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-	
-	.u-mask {
-		position: fixed;
-		top: 0;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		opacity: 0;
-		transition: transform 0.3s;
-	}
-
-	.u-mask-show {
-		opacity: 1;
-	}
-	
-	.u-mask-zoom {
-		transform: scale(1.2, 1.2);
-	}
-</style>

+ 0 - 311
uview-ui/components/u-message-input/u-message-input.vue

@@ -1,311 +0,0 @@
-<template>
-	<view class="u-char-box">
-		<view class="u-char-flex">
-			<input :disabled="disabledKeyboard" :value="valueModel" type="number" :focus="focus" :maxlength="maxlength" class="u-input" @input="getVal"/>
-			<view v-for="(item, index) in loopCharArr" :key="index">
-				<view :class="[breathe && charArrLength == index ? 'u-breathe' : '', 'u-char-item',
-				charArrLength === index && mode == 'box' ? 'u-box-active' : '',
-				mode === 'box' ? 'u-box' : '']" :style="{
-					fontWeight: bold ? 'bold' : 'normal',
-					fontSize: fontSize + 'rpx',
-					width: width + 'rpx',
-					height: width + 'rpx',
-					color: inactiveColor,
-					borderColor: charArrLength === index && mode == 'box' ? activeColor : inactiveColor
-				}">
-					<view class="u-placeholder-line" :style="{
-							display: charArrLength === index ? 'block' : 'none',
-							height: width * 0.5 +'rpx'
-						}"
-						v-if="mode !== 'middleLine'"
-					></view>
-					<view v-if="mode === 'middleLine' && charArrLength <= index" :class="[breathe && charArrLength == index ? 'u-breathe' : '', charArrLength === index ? 'u-middle-line-active' : '']"
-					 class="u-middle-line" :style="{height: bold ? '4px' : '2px', background: charArrLength === index ? activeColor : inactiveColor}"></view>
-					<view v-if="mode === 'bottomLine'" :class="[breathe && charArrLength == index ? 'u-breathe' : '', charArrLength === index ? 'u-buttom-line-active' : '']"
-					 class="u-bottom-line" :style="{height: bold ? '4px' : '2px', background: charArrLength === index ? activeColor : inactiveColor}"></view>
-					<block v-if="!dotFill"> {{ charArr[index] ? charArr[index] : ''}}</block>
-					<block v-else>
-						<text class="u-dot">{{ charArr[index] ? '●' : ''}}</text>
-					</block>
-				</view>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	/**
-	 * messageInput 验证码输入框
-	 * @description 该组件一般用于验证用户短信验证码的场景,也可以结合uView的键盘组件使用
-	 * @tutorial https://www.uviewui.com/components/messageInput.html
-	 * @property {String Number} maxlength 输入字符个数(默认4)
-	 * @property {Boolean} dot-fill 是否用圆点填充(默认false)
-	 * @property {String} mode 模式选择,见上方"基本使用"说明(默认box)
-	 * @property {String Number} value 预置值
-	 * @property {Boolean} breathe 是否开启呼吸效果,见上方说明(默认true)
-	 * @property {Boolean} focus 是否自动获取焦点(默认false)
-	 * @property {Boolean} bold 字体和输入横线是否加粗(默认true)
-	 * @property {String Number} font-size 字体大小,单位rpx(默认60)
-	 * @property {String} active-color 当前激活输入框的样式(默认#2979ff)
-	 * @property {String} inactive-color 非激活输入框的样式,文字颜色同此值(默认#606266)
-	 * @property {String | Number} width 输入框宽度,单位rpx,高等于宽(默认80)
-	 * @property {Boolean} disabled-keyboard 禁止点击输入框唤起系统键盘(默认false)
-	 * @event {Function} change 输入内容发生改变时触发,具体见官网说明
-	 * @event {Function} finish 输入字符个数达maxlength值时触发,见官网说明
-	 * @example <u-message-input mode="bottomLine"></u-message-input>
-	 */
-	export default {
-		name: "u-message-input",
-		props: {
-			// 最大输入长度
-			maxlength: {
-				type: [Number, String],
-				default: 4
-			},
-			// 是否用圆点填充
-			dotFill: {
-				type: Boolean,
-				default: false
-			},
-			// 显示模式,box-盒子模式,bottomLine-横线在底部模式,middleLine-横线在中部模式
-			mode: {
-				type: String,
-				default: "box"
-			},
-			// 预置值
-			value: {
-				type: [String, Number],
-				default: ''
-			},
-			// 当前激活输入item,是否带有呼吸效果
-			breathe: {
-				type: Boolean,
-				default: true
-			},
-			// 是否自动获取焦点
-			focus: {
-				type: Boolean,
-				default: false
-			},
-			// 字体是否加粗
-			bold: {
-				type: Boolean,
-				default: false
-			},
-			// 字体大小
-			fontSize: {
-				type: [String, Number],
-				default: 60
-			},
-			// 激活样式
-			activeColor: {
-				type: String,
-				default: '#2979ff'
-			},
-			// 未激活的样式
-			inactiveColor: {
-				type: String,
-				default: '#606266'
-			},
-			// 输入框的大小,单位rpx,宽等于高
-			width: {
-				type: [Number, String],
-				default: '80'
-			},
-			// 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true
-			disabledKeyboard: {
-				type: Boolean,
-				default: false
-			}
-		},
-		watch: {
-			// maxlength: {
-			// 	// 此值设置为true,会在组件加载后无需maxlength变化就会执行一次本监听函数,无需再created生命周期中处理
-			// 	immediate: true,
-			// 	handler(val) {
-			// 		this.maxlength = Number(val);
-			// 	}
-			// }, 
-			value: {
-				immediate: true,
-				handler(val) {
-					// 转为字符串
-					val = String(val);
-					// 超出部分截掉
-					this.valueModel = val.substring(0, this.maxlength);
-				}
-			},
-		},
-		data() {
-			return {
-				valueModel: ""
-			}
-		},
-		computed: {
-			// 是否显示呼吸灯效果
-			animationClass() {
-				return (index) => {
-					if (this.breathe && this.charArr.length == index) return 'u-breathe';
-					else return '';
-				}
-			},
-			// 用于显示字符
-			charArr() {
-				return this.valueModel.split('');
-			},
-			charArrLength() {
-				return this.charArr.length;
-			},
-			// 根据长度,循环输入框的个数,因为头条小程序数值不能用于v-for
-			loopCharArr() {
-				return new Array(this.maxlength);
-			}
-		},
-		methods: {
-			getVal(e) {
-				let {
-					value
-				} = e.detail
-				this.valueModel = value;
-				// 判断长度是否超出了maxlength值,理论上不会发生,因为input组件设置了maxlength属性值
-				if (String(value).length > this.maxlength) return;
-				// 未达到maxlength之前,发送change事件,达到后发送finish事件
-				this.$emit('change', value);
-				if (String(value).length == this.maxlength) {
-					this.$emit('finish', value);
-				}
-			}
-		}
-	}
-</script>
-
-<style scoped lang="scss">
-	@import "../../libs/css/style.components.scss";
-
-	@keyframes breathe {
-		0% {
-			opacity: 0.3;
-		}
-
-		50% {
-			opacity: 1;
-		}
-
-		100% {
-			opacity: 0.3;
-		}
-	}
-
-	.u-char-box {
-		text-align: center;
-	}
-
-	.u-char-flex {
-		@include vue-flex;
-		justify-content: center;
-		flex-wrap: wrap;
-		position: relative;
-	}
-
-	.u-input {
-		position: absolute;
-		top: 0;
-		left: -100%;
-		width: 200%;
-		height: 100%;
-		text-align: left;
-		z-index: 9;
-		opacity: 0;
-		background: none;
-	}
-
-	.u-char-item {
-		position: relative;
-		width: 90rpx;
-		height: 90rpx;
-		margin: 10rpx 10rpx;
-		font-size: 60rpx;
-		font-weight: bold;
-		color: $u-main-color;
-		line-height: 90rpx;
-		@include vue-flex;
-		justify-content: center;
-		align-items: center;
-	}
-
-	.u-middle-line {
-		border: none;
-	}
-
-	.u-box {
-		box-sizing: border-box;
-		border: 2rpx solid #cccccc;
-		border-radius: 6rpx;
-	}
-
-	.u-box-active {
-		overflow: hidden;
-		animation-timing-function: ease-in-out;
-		animation-duration: 1500ms;
-		animation-iteration-count: infinite;
-		animation-direction: alternate;
-		border: 2rpx solid $u-type-primary;
-	}
-
-	.u-middle-line-active {
-		background: $u-type-primary;
-	}
-
-	.u-breathe {
-		animation: breathe 2s infinite ease;
-	}
-
-	.u-placeholder-line {
-		/* #ifndef APP-NVUE */
-		display: none;
-		/* #endif */
-		position: absolute;
-		left: 50%;
-		top: 50%;
-		transform: translate(-50%, -50%);
-		width: 2rpx;
-		height: 40rpx;
-		background: #333333;
-		animation: twinkling 1.5s infinite ease;
-	}
-
-	.u-animation-breathe {
-		animation-name: breathe;
-	}
-
-	.u-dot {
-		font-size: 34rpx;
-		line-height: 34rpx;
-	}
-
-	.u-middle-line {
-		height: 4px;
-		background: #000000;
-		width: 80%;
-		position: absolute;
-		border-radius: 2px;
-		top: 50%;
-		left: 50%;
-		transform: translate(-50%, -50%);
-	}
-
-	.u-buttom-line-active {
-		background: $u-type-primary;
-	}
-
-	.u-bottom-line {
-		height: 4px;
-		background: #000000;
-		width: 80%;
-		position: absolute;
-		border-radius: 2px;
-		bottom: 0;
-		left: 50%;
-		transform: translate(-50%);
-	}
-</style>

+ 2 - 2
uview-ui/components/u-modal/u-modal.vue

@@ -114,7 +114,7 @@
 	 * @event {Function} confirm	点击确认按钮时触发
 	 * @event {Function} cancel		点击取消按钮时触发
 	 * @event {Function} close		点击遮罩关闭出发,closeOnClickOverlay为true有效
-	 * @example <u-loadmore :status="status" icon-type="iconType" load-text="loadText" />
+	 * @example <u-modal :show="true" title="title" content="content"></u-modal>
 	 */
 	export default {
 		name: 'u-modal',
@@ -146,7 +146,7 @@
 			},
 			// 点击遮罩
 			// 从原理上来说,modal的遮罩点击,并不是真的点击到了遮罩
-			// 因为modal依赖于popup的中部弹窗类型,中部弹窗比较特殊,虽然遮罩,但是为了让弹窗内容能flex居中
+			// 因为modal依赖于popup的中部弹窗类型,中部弹窗比较特殊,虽然遮罩,但是为了让弹窗内容能flex居中
 			// 多了一个透明的遮罩,此透明的遮罩会覆盖在灰色的遮罩上,所以实际上是点击不到灰色遮罩的,popup内部在
 			// 透明遮罩的子元素做了.stop处理,所以点击内容区,也不会导致误触发
 			clickHandler() {

+ 5 - 0
uview-ui/components/u-navbar/props.js

@@ -74,6 +74,11 @@ export default {
 		autoBack: {
 			type: Boolean,
 			default: uni.$u.props.navbar.autoBack
+		},
+		// 标题的样式,对象或字符串
+		titleStyle: {
+			type: [String, Object],
+			default: uni.$u.props.navbar.titleStyle
 		}
 	}
 }

+ 6 - 5
uview-ui/components/u-navbar/u-navbar.vue

@@ -4,7 +4,7 @@
 			class="u-navbar__placeholder"
 			v-if="fixed && placeholder"
 			:style="{
-				height: $u.addUnit($u.getPx(height) + $u.sys().statusBarHeight),
+				height: $u.addUnit($u.getPx(height) + $u.sys().statusBarHeight,'px'),
 			}"
 		></view>
 		<view :class="[fixed && 'u-navbar--fixed']">
@@ -45,9 +45,9 @@
 				<slot name="center">
 					<text
 						class="u-line-1 u-navbar__content__title"
-						:style="{
-							width: $u.addUnit(titleWidth)
-						}"
+						:style="[{
+							width: $u.addUnit(titleWidth),
+						}, $u.addStyle(titleStyle)]"
 					>{{ title }}</text>
 				</slot>
 				<view
@@ -93,6 +93,7 @@
 	 * @property {String | Number}	leftIconSize		左侧返回图标的大小(默认 20px )
 	 * @property {String | Number}	leftIconColor		左侧返回图标的颜色(默认 #303133 )
 	 * @property {Boolean}	        autoBack			点击左侧区域(返回图标),是否自动返回上一页(默认 false )
+	 * @property {Object | String}	titleStyle			标题的样式,对象或字符串
 	 * @event {Function} leftClick		点击左侧区域
 	 * @event {Function} rightClick		点击右侧区域
 	 * @example <u-navbar title="剑未配妥,出门已是江湖" left-text="返回" right-text="帮助" @click-left="onClickBack" @click-right="onClickRight"></u-navbar>
@@ -175,7 +176,7 @@
 			&__right {
 				right: 0;
 
-				&__txet {
+				&__text {
 					font-size: 15px;
 					margin-left: 3px;
 				}

+ 1 - 0
uview-ui/components/u-no-network/u-no-network.vue

@@ -1,6 +1,7 @@
 <template>
 	<u-overlay
 	    :show="!isConnected"
+		:zIndex="zIndex"
 	    @touchmove.stop.prevent="noop"
 		:customStyle="{
 			backgroundColor: '#fff',

+ 0 - 100
uview-ui/components/u-parse/libs/CssHandler.js

@@ -1,100 +0,0 @@
-const cfg = require('./config.js'),
-	isLetter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
-
-function CssHandler(tagStyle) {
-	var styles = Object.assign(Object.create(null), cfg.userAgentStyles);
-	for (var item in tagStyle)
-		styles[item] = (styles[item] ? styles[item] + ';' : '') + tagStyle[item];
-	this.styles = styles;
-}
-CssHandler.prototype.getStyle = function(data) {
-	this.styles = new parser(data, this.styles).parse();
-}
-CssHandler.prototype.match = function(name, attrs) {
-	var tmp, matched = (tmp = this.styles[name]) ? tmp + ';' : '';
-	if (attrs.class) {
-		var items = attrs.class.split(' ');
-		for (var i = 0, item; item = items[i]; i++)
-			if (tmp = this.styles['.' + item])
-				matched += tmp + ';';
-	}
-	if (tmp = this.styles['#' + attrs.id])
-		matched += tmp + ';';
-	return matched;
-}
-module.exports = CssHandler;
-
-function parser(data, init) {
-	this.data = data;
-	this.floor = 0;
-	this.i = 0;
-	this.list = [];
-	this.res = init;
-	this.state = this.Space;
-}
-parser.prototype.parse = function() {
-	for (var c; c = this.data[this.i]; this.i++)
-		this.state(c);
-	return this.res;
-}
-parser.prototype.section = function() {
-	return this.data.substring(this.start, this.i);
-}
-// 状态机
-parser.prototype.Space = function(c) {
-	if (c == '.' || c == '#' || isLetter(c)) {
-		this.start = this.i;
-		this.state = this.Name;
-	} else if (c == '/' && this.data[this.i + 1] == '*')
-		this.Comment();
-	else if (!cfg.blankChar[c] && c != ';')
-		this.state = this.Ignore;
-}
-parser.prototype.Comment = function() {
-	this.i = this.data.indexOf('*/', this.i) + 1;
-	if (!this.i) this.i = this.data.length;
-	this.state = this.Space;
-}
-parser.prototype.Ignore = function(c) {
-	if (c == '{') this.floor++;
-	else if (c == '}' && !--this.floor) {
-		this.list = [];
-		this.state = this.Space;
-	}
-}
-parser.prototype.Name = function(c) {
-	if (cfg.blankChar[c]) {
-		this.list.push(this.section());
-		this.state = this.NameSpace;
-	} else if (c == '{') {
-		this.list.push(this.section());
-		this.Content();
-	} else if (c == ',') {
-		this.list.push(this.section());
-		this.Comma();
-	} else if (!isLetter(c) && (c < '0' || c > '9') && c != '-' && c != '_')
-		this.state = this.Ignore;
-}
-parser.prototype.NameSpace = function(c) {
-	if (c == '{') this.Content();
-	else if (c == ',') this.Comma();
-	else if (!cfg.blankChar[c]) this.state = this.Ignore;
-}
-parser.prototype.Comma = function() {
-	while (cfg.blankChar[this.data[++this.i]]);
-	if (this.data[this.i] == '{') this.Content();
-	else {
-		this.start = this.i--;
-		this.state = this.Name;
-	}
-}
-parser.prototype.Content = function() {
-	this.start = ++this.i;
-	if ((this.i = this.data.indexOf('}', this.i)) == -1) this.i = this.data.length;
-	var content = this.section();
-	for (var i = 0, item; item = this.list[i++];)
-		if (this.res[item]) this.res[item] += ';' + content;
-		else this.res[item] = content;
-	this.list = [];
-	this.state = this.Space;
-}

+ 0 - 580
uview-ui/components/u-parse/libs/MpHtmlParser.js

@@ -1,580 +0,0 @@
-/**
- * html 解析器
- * @tutorial https://github.com/jin-yufeng/Parser
- * @version 20201029
- * @author JinYufeng
- * @listens MIT
- */
-const cfg = require('./config.js'),
-	blankChar = cfg.blankChar,
-	CssHandler = require('./CssHandler.js'),
-	windowWidth = uni.getSystemInfoSync().windowWidth;
-var emoji;
-
-function MpHtmlParser(data, options = {}) {
-	this.attrs = {};
-	this.CssHandler = new CssHandler(options.tagStyle, windowWidth);
-	this.data = data;
-	this.domain = options.domain;
-	this.DOM = [];
-	this.i = this.start = this.audioNum = this.imgNum = this.videoNum = 0;
-	options.prot = (this.domain || '').includes('://') ? this.domain.split('://')[0] : 'http';
-	this.options = options;
-	this.state = this.Text;
-	this.STACK = [];
-	// 工具函数
-	this.bubble = () => {
-		for (var i = this.STACK.length, item; item = this.STACK[--i];) {
-			if (cfg.richOnlyTags[item.name]) return false;
-			item.c = 1;
-		}
-		return true;
-	}
-	this.decode = (val, amp) => {
-		var i = -1,
-			j, en;
-		while (1) {
-			if ((i = val.indexOf('&', i + 1)) == -1) break;
-			if ((j = val.indexOf(';', i + 2)) == -1) break;
-			if (val[i + 1] == '#') {
-				en = parseInt((val[i + 2] == 'x' ? '0' : '') + val.substring(i + 2, j));
-				if (!isNaN(en)) val = val.substr(0, i) + String.fromCharCode(en) + val.substr(j + 1);
-			} else {
-				en = val.substring(i + 1, j);
-				if (cfg.entities[en] || en == amp)
-					val = val.substr(0, i) + (cfg.entities[en] || '&') + val.substr(j + 1);
-			}
-		}
-		return val;
-	}
-	this.getUrl = url => {
-		if (url[0] == '/') {
-			if (url[1] == '/') url = this.options.prot + ':' + url;
-			else if (this.domain) url = this.domain + url;
-		} else if (this.domain && url.indexOf('data:') != 0 && !url.includes('://'))
-			url = this.domain + '/' + url;
-		return url;
-	}
-	this.isClose = () => this.data[this.i] == '>' || (this.data[this.i] == '/' && this.data[this.i + 1] == '>');
-	this.section = () => this.data.substring(this.start, this.i);
-	this.parent = () => this.STACK[this.STACK.length - 1];
-	this.siblings = () => this.STACK.length ? this.parent().children : this.DOM;
-}
-MpHtmlParser.prototype.parse = function() {
-	if (emoji) this.data = emoji.parseEmoji(this.data);
-	for (var c; c = this.data[this.i]; this.i++)
-		this.state(c);
-	if (this.state == this.Text) this.setText();
-	while (this.STACK.length) this.popNode(this.STACK.pop());
-	return this.DOM;
-}
-// 设置属性
-MpHtmlParser.prototype.setAttr = function() {
-	var name = this.attrName.toLowerCase(),
-		val = this.attrVal;
-	if (cfg.boolAttrs[name]) this.attrs[name] = 'T';
-	else if (val) {
-		if (name == 'src' || (name == 'data-src' && !this.attrs.src)) this.attrs.src = this.getUrl(this.decode(val, 'amp'));
-		else if (name == 'href' || name == 'style') this.attrs[name] = this.decode(val, 'amp');
-		else if (name.substr(0, 5) != 'data-') this.attrs[name] = val;
-	}
-	this.attrVal = '';
-	while (blankChar[this.data[this.i]]) this.i++;
-	if (this.isClose()) this.setNode();
-	else {
-		this.start = this.i;
-		this.state = this.AttrName;
-	}
-}
-// 设置文本节点
-MpHtmlParser.prototype.setText = function() {
-	var back, text = this.section();
-	if (!text) return;
-	text = (cfg.onText && cfg.onText(text, () => back = true)) || text;
-	if (back) {
-		this.data = this.data.substr(0, this.start) + text + this.data.substr(this.i);
-		let j = this.start + text.length;
-		for (this.i = this.start; this.i < j; this.i++) this.state(this.data[this.i]);
-		return;
-	}
-	if (!this.pre) {
-		// 合并空白符
-		var flag, tmp = [];
-		for (let i = text.length, c; c = text[--i];)
-			if (!blankChar[c]) {
-				tmp.unshift(c);
-				if (!flag) flag = 1;
-			} else {
-				if (tmp[0] != ' ') tmp.unshift(' ');
-				if (c == '\n' && flag == void 0) flag = 0;
-			}
-		if (flag == 0) return;
-		text = tmp.join('');
-	}
-	this.siblings().push({
-		type: 'text',
-		text: this.decode(text)
-	});
-}
-// 设置元素节点
-MpHtmlParser.prototype.setNode = function() {
-	var node = {
-			name: this.tagName.toLowerCase(),
-			attrs: this.attrs
-		},
-		close = cfg.selfClosingTags[node.name];
-	if (this.options.nodes.length) node.type = 'node';
-	this.attrs = {};
-	if (!cfg.ignoreTags[node.name]) {
-		// 处理属性
-		var attrs = node.attrs,
-			style = this.CssHandler.match(node.name, attrs, node) + (attrs.style || ''),
-			styleObj = {};
-		if (attrs.id) {
-			if (this.options.compress & 1) attrs.id = void 0;
-			else if (this.options.useAnchor) this.bubble();
-		}
-		if ((this.options.compress & 2) && attrs.class) attrs.class = void 0;
-		switch (node.name) {
-			case 'a':
-			case 'ad': // #ifdef APP-PLUS
-			case 'iframe':
-				// #endif
-				this.bubble();
-				break;
-			case 'font':
-				if (attrs.color) {
-					styleObj['color'] = attrs.color;
-					attrs.color = void 0;
-				}
-				if (attrs.face) {
-					styleObj['font-family'] = attrs.face;
-					attrs.face = void 0;
-				}
-				if (attrs.size) {
-					var size = parseInt(attrs.size);
-					if (size < 1) size = 1;
-					else if (size > 7) size = 7;
-					var map = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'];
-					styleObj['font-size'] = map[size - 1];
-					attrs.size = void 0;
-				}
-				break;
-			case 'embed':
-				// #ifndef APP-PLUS
-				var src = node.attrs.src || '',
-					type = node.attrs.type || '';
-				if (type.includes('video') || src.includes('.mp4') || src.includes('.3gp') || src.includes('.m3u8'))
-					node.name = 'video';
-				else if (type.includes('audio') || src.includes('.m4a') || src.includes('.wav') || src.includes('.mp3') || src.includes(
-						'.aac'))
-					node.name = 'audio';
-				else break;
-				if (node.attrs.autostart)
-					node.attrs.autoplay = 'T';
-				node.attrs.controls = 'T';
-				// #endif
-				// #ifdef APP-PLUS
-				this.bubble();
-				break;
-				// #endif
-			case 'video':
-			case 'audio':
-				if (!attrs.id) attrs.id = node.name + (++this[`${node.name}Num`]);
-				else this[`${node.name}Num`]++;
-				if (node.name == 'video') {
-					if (this.videoNum > 3)
-						node.lazyLoad = 1;
-					if (attrs.width) {
-						styleObj.width = parseFloat(attrs.width) + (attrs.width.includes('%') ? '%' : 'px');
-						attrs.width = void 0;
-					}
-					if (attrs.height) {
-						styleObj.height = parseFloat(attrs.height) + (attrs.height.includes('%') ? '%' : 'px');
-						attrs.height = void 0;
-					}
-				}
-				if (!attrs.controls && !attrs.autoplay) attrs.controls = 'T';
-				attrs.source = [];
-				if (attrs.src) {
-					attrs.source.push(attrs.src);
-					attrs.src = void 0;
-				}
-				this.bubble();
-				break;
-			case 'td':
-			case 'th':
-				if (attrs.colspan || attrs.rowspan)
-					for (var k = this.STACK.length, item; item = this.STACK[--k];)
-						if (item.name == 'table') {
-							item.flag = 1;
-							break;
-						}
-		}
-		if (attrs.align) {
-			if (node.name == 'table') {
-				if (attrs.align == 'center') styleObj['margin-inline-start'] = styleObj['margin-inline-end'] = 'auto';
-				else styleObj['float'] = attrs.align;
-			} else styleObj['text-align'] = attrs.align;
-			attrs.align = void 0;
-		}
-		// 压缩 style
-		var styles = style.split(';');
-		style = '';
-		for (var i = 0, len = styles.length; i < len; i++) {
-			var info = styles[i].split(':');
-			if (info.length < 2) continue;
-			let key = info[0].trim().toLowerCase(),
-				value = info.slice(1).join(':').trim();
-			if (value[0] == '-' || value.includes('safe'))
-				style += `;${key}:${value}`;
-			else if (!styleObj[key] || value.includes('import') || !styleObj[key].includes('import'))
-				styleObj[key] = value;
-		}
-		if (node.name == 'img') {
-			if (attrs.src && !attrs.ignore) {
-				if (this.bubble())
-					attrs.i = (this.imgNum++).toString();
-				else attrs.ignore = 'T';
-			}
-			if (attrs.ignore) {
-				style += ';-webkit-touch-callout:none';
-				styleObj['max-width'] = '100%';
-			}
-			var width;
-			if (styleObj.width) width = styleObj.width;
-			else if (attrs.width) width = attrs.width.includes('%') ? attrs.width : parseFloat(attrs.width) + 'px';
-			if (width) {
-				styleObj.width = width;
-				attrs.width = '100%';
-				if (parseInt(width) > windowWidth) {
-					styleObj.height = '';
-					if (attrs.height) attrs.height = void 0;
-				}
-			}
-			if (styleObj.height) {
-				attrs.height = styleObj.height;
-				styleObj.height = '';
-			} else if (attrs.height && !attrs.height.includes('%'))
-				attrs.height = parseFloat(attrs.height) + 'px';
-		}
-		for (var key in styleObj) {
-			var value = styleObj[key];
-			if (!value) continue;
-			if (key.includes('flex') || key == 'order' || key == 'self-align') node.c = 1;
-			// 填充链接
-			if (value.includes('url')) {
-				var j = value.indexOf('(');
-				if (j++ != -1) {
-					while (value[j] == '"' || value[j] == "'" || blankChar[value[j]]) j++;
-					value = value.substr(0, j) + this.getUrl(value.substr(j));
-				}
-			}
-			// 转换 rpx
-			else if (value.includes('rpx'))
-				value = value.replace(/[0-9.]+\s*rpx/g, $ => parseFloat($) * windowWidth / 750 + 'px');
-			else if (key == 'white-space' && value.includes('pre') && !close)
-				this.pre = node.pre = true;
-			style += `;${key}:${value}`;
-		}
-		style = style.substr(1);
-		if (style) attrs.style = style;
-		if (!close) {
-			node.children = [];
-			if (node.name == 'pre' && cfg.highlight) {
-				this.remove(node);
-				this.pre = node.pre = true;
-			}
-			this.siblings().push(node);
-			this.STACK.push(node);
-		} else if (!cfg.filter || cfg.filter(node, this) != false)
-			this.siblings().push(node);
-	} else {
-		if (!close) this.remove(node);
-		else if (node.name == 'source') {
-			var parent = this.parent();
-			if (parent && (parent.name == 'video' || parent.name == 'audio') && node.attrs.src)
-				parent.attrs.source.push(node.attrs.src);
-		} else if (node.name == 'base' && !this.domain) this.domain = node.attrs.href;
-	}
-	if (this.data[this.i] == '/') this.i++;
-	this.start = this.i + 1;
-	this.state = this.Text;
-}
-// 移除标签
-MpHtmlParser.prototype.remove = function(node) {
-	var name = node.name,
-		j = this.i;
-	// 处理 svg
-	var handleSvg = () => {
-		var src = this.data.substring(j, this.i + 1);
-		node.attrs.xmlns = 'http://www.w3.org/2000/svg';
-		for (var key in node.attrs) {
-			if (key == 'viewbox') src = ` viewBox="${node.attrs.viewbox}"` + src;
-			else if (key != 'style') src = ` ${key}="${node.attrs[key]}"` + src;
-		}
-		src = '<svg' + src;
-		var parent = this.parent();
-		if (node.attrs.width == '100%' && parent && (parent.attrs.style || '').includes('inline'))
-			parent.attrs.style = 'width:300px;max-width:100%;' + parent.attrs.style;
-		this.siblings().push({
-			name: 'img',
-			attrs: {
-				src: 'data:image/svg+xml;utf8,' + src.replace(/#/g, '%23'),
-				style: node.attrs.style,
-				ignore: 'T'
-			}
-		})
-	}
-	if (node.name == 'svg' && this.data[j] == '/') return handleSvg(this.i++);
-	while (1) {
-		if ((this.i = this.data.indexOf('</', this.i + 1)) == -1) {
-			if (name == 'pre' || name == 'svg') this.i = j;
-			else this.i = this.data.length;
-			return;
-		}
-		this.start = (this.i += 2);
-		while (!blankChar[this.data[this.i]] && !this.isClose()) this.i++;
-		if (this.section().toLowerCase() == name) {
-			// 代码块高亮
-			if (name == 'pre') {
-				this.data = this.data.substr(0, j + 1) + cfg.highlight(this.data.substring(j + 1, this.i - 5), node.attrs) + this.data
-					.substr(this.i - 5);
-				return this.i = j;
-			} else if (name == 'style')
-				this.CssHandler.getStyle(this.data.substring(j + 1, this.i - 7));
-			else if (name == 'title')
-				this.DOM.title = this.data.substring(j + 1, this.i - 7);
-			if ((this.i = this.data.indexOf('>', this.i)) == -1) this.i = this.data.length;
-			if (name == 'svg') handleSvg();
-			return;
-		}
-	}
-}
-// 节点出栈处理
-MpHtmlParser.prototype.popNode = function(node) {
-	// 空白符处理
-	if (node.pre) {
-		node.pre = this.pre = void 0;
-		for (let i = this.STACK.length; i--;)
-			if (this.STACK[i].pre)
-				this.pre = true;
-	}
-	var siblings = this.siblings(),
-		len = siblings.length,
-		childs = node.children;
-	if (node.name == 'head' || (cfg.filter && cfg.filter(node, this) == false))
-		return siblings.pop();
-	var attrs = node.attrs;
-	// 替换一些标签名
-	if (cfg.blockTags[node.name]) node.name = 'div';
-	else if (!cfg.trustTags[node.name]) node.name = 'span';
-	// 处理列表
-	if (node.c && (node.name == 'ul' || node.name == 'ol')) {
-		if ((node.attrs.style || '').includes('list-style:none')) {
-			for (let i = 0, child; child = childs[i++];)
-				if (child.name == 'li')
-					child.name = 'div';
-		} else if (node.name == 'ul') {
-			var floor = 1;
-			for (let i = this.STACK.length; i--;)
-				if (this.STACK[i].name == 'ul') floor++;
-			if (floor != 1)
-				for (let i = childs.length; i--;)
-					childs[i].floor = floor;
-		} else {
-			for (let i = 0, num = 1, child; child = childs[i++];)
-				if (child.name == 'li') {
-					child.type = 'ol';
-					child.num = ((num, type) => {
-						if (type == 'a') return String.fromCharCode(97 + (num - 1) % 26);
-						if (type == 'A') return String.fromCharCode(65 + (num - 1) % 26);
-						if (type == 'i' || type == 'I') {
-							num = (num - 1) % 99 + 1;
-							var one = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'],
-								ten = ['X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'],
-								res = (ten[Math.floor(num / 10) - 1] || '') + (one[num % 10 - 1] || '');
-							if (type == 'i') return res.toLowerCase();
-							return res;
-						}
-						return num;
-					})(num++, attrs.type) + '.';
-				}
-		}
-	}
-	// 处理表格
-	if (node.name == 'table') {
-		var padding = parseFloat(attrs.cellpadding),
-			spacing = parseFloat(attrs.cellspacing),
-			border = parseFloat(attrs.border);
-		if (node.c) {
-			if (isNaN(padding)) padding = 2;
-			if (isNaN(spacing)) spacing = 2;
-		}
-		if (border) attrs.style = `border:${border}px solid gray;${attrs.style || ''}`;
-		if (node.flag && node.c) {
-			// 有 colspan 或 rowspan 且含有链接的表格转为 grid 布局实现
-			attrs.style = `${attrs.style || ''};${spacing ? `;grid-gap:${spacing}px` : ';border-left:0;border-top:0'}`;
-			var row = 1,
-				col = 1,
-				colNum,
-				trs = [],
-				children = [],
-				map = {};
-			(function f(ns) {
-				for (var i = 0; i < ns.length; i++) {
-					if (ns[i].name == 'tr') trs.push(ns[i]);
-					else f(ns[i].children || []);
-				}
-			})(node.children)
-			for (let i = 0; i < trs.length; i++) {
-				for (let j = 0, td; td = trs[i].children[j]; j++) {
-					if (td.name == 'td' || td.name == 'th') {
-						while (map[row + '.' + col]) col++;
-						var cell = {
-							name: 'div',
-							c: 1,
-							attrs: {
-								style: (td.attrs.style || '') + (border ? `;border:${border}px solid gray` + (spacing ? '' :
-									';border-right:0;border-bottom:0') : '') + (padding ? `;padding:${padding}px` : '')
-							},
-							children: td.children
-						}
-						if (td.attrs.colspan) {
-							cell.attrs.style += ';grid-column-start:' + col + ';grid-column-end:' + (col + parseInt(td.attrs.colspan));
-							if (!td.attrs.rowspan) cell.attrs.style += ';grid-row-start:' + row + ';grid-row-end:' + (row + 1);
-							col += parseInt(td.attrs.colspan) - 1;
-						}
-						if (td.attrs.rowspan) {
-							cell.attrs.style += ';grid-row-start:' + row + ';grid-row-end:' + (row + parseInt(td.attrs.rowspan));
-							if (!td.attrs.colspan) cell.attrs.style += ';grid-column-start:' + col + ';grid-column-end:' + (col + 1);
-							for (var k = 1; k < td.attrs.rowspan; k++) map[(row + k) + '.' + col] = 1;
-						}
-						children.push(cell);
-						col++;
-					}
-				}
-				if (!colNum) {
-					colNum = col - 1;
-					attrs.style += `;grid-template-columns:repeat(${colNum},auto)`
-				}
-				col = 1;
-				row++;
-			}
-			node.children = children;
-		} else {
-			attrs.style = `border-spacing:${spacing}px;${attrs.style || ''}`;
-			if (border || padding)
-				(function f(ns) {
-					for (var i = 0, n; n = ns[i]; i++) {
-						if (n.name == 'th' || n.name == 'td') {
-							if (border) n.attrs.style = `border:${border}px solid gray;${n.attrs.style || ''}`;
-							if (padding) n.attrs.style = `padding:${padding}px;${n.attrs.style || ''}`;
-						} else f(n.children || []);
-					}
-				})(childs)
-		}
-		if (this.options.autoscroll) {
-			var table = Object.assign({}, node);
-			node.name = 'div';
-			node.attrs = {
-				style: 'overflow:scroll'
-			}
-			node.children = [table];
-		}
-	}
-	this.CssHandler.pop && this.CssHandler.pop(node);
-	// 自动压缩
-	if (node.name == 'div' && !Object.keys(attrs).length && childs.length == 1 && childs[0].name == 'div')
-		siblings[len - 1] = childs[0];
-}
-// 状态机
-MpHtmlParser.prototype.Text = function(c) {
-	if (c == '<') {
-		var next = this.data[this.i + 1],
-			isLetter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
-		if (isLetter(next)) {
-			this.setText();
-			this.start = this.i + 1;
-			this.state = this.TagName;
-		} else if (next == '/') {
-			this.setText();
-			if (isLetter(this.data[++this.i + 1])) {
-				this.start = this.i + 1;
-				this.state = this.EndTag;
-			} else this.Comment();
-		} else if (next == '!' || next == '?') {
-			this.setText();
-			this.Comment();
-		}
-	}
-}
-MpHtmlParser.prototype.Comment = function() {
-	var key;
-	if (this.data.substring(this.i + 2, this.i + 4) == '--') key = '-->';
-	else if (this.data.substring(this.i + 2, this.i + 9) == '[CDATA[') key = ']]>';
-	else key = '>';
-	if ((this.i = this.data.indexOf(key, this.i + 2)) == -1) this.i = this.data.length;
-	else this.i += key.length - 1;
-	this.start = this.i + 1;
-	this.state = this.Text;
-}
-MpHtmlParser.prototype.TagName = function(c) {
-	if (blankChar[c]) {
-		this.tagName = this.section();
-		while (blankChar[this.data[this.i]]) this.i++;
-		if (this.isClose()) this.setNode();
-		else {
-			this.start = this.i;
-			this.state = this.AttrName;
-		}
-	} else if (this.isClose()) {
-		this.tagName = this.section();
-		this.setNode();
-	}
-}
-MpHtmlParser.prototype.AttrName = function(c) {
-	if (c == '=' || blankChar[c] || this.isClose()) {
-		this.attrName = this.section();
-		if (blankChar[c])
-			while (blankChar[this.data[++this.i]]);
-		if (this.data[this.i] == '=') {
-			while (blankChar[this.data[++this.i]]);
-			this.start = this.i--;
-			this.state = this.AttrValue;
-		} else this.setAttr();
-	}
-}
-MpHtmlParser.prototype.AttrValue = function(c) {
-	if (c == '"' || c == "'") {
-		this.start++;
-		if ((this.i = this.data.indexOf(c, this.i + 1)) == -1) return this.i = this.data.length;
-		this.attrVal = this.section();
-		this.i++;
-	} else {
-		for (; !blankChar[this.data[this.i]] && !this.isClose(); this.i++);
-		this.attrVal = this.section();
-	}
-	this.setAttr();
-}
-MpHtmlParser.prototype.EndTag = function(c) {
-	if (blankChar[c] || c == '>' || c == '/') {
-		var name = this.section().toLowerCase();
-		for (var i = this.STACK.length; i--;)
-			if (this.STACK[i].name == name) break;
-		if (i != -1) {
-			var node;
-			while ((node = this.STACK.pop()).name != name) this.popNode(node);
-			this.popNode(node);
-		} else if (name == 'p' || name == 'br')
-			this.siblings().push({
-				name,
-				attrs: {}
-			});
-		this.i = this.data.indexOf('>', this.i);
-		this.start = this.i + 1;
-		if (this.i == -1) this.i = this.data.length;
-		else this.state = this.Text;
-	}
-}
-module.exports = MpHtmlParser;

+ 0 - 80
uview-ui/components/u-parse/libs/config.js

@@ -1,80 +0,0 @@
-/* 配置文件 */
-var cfg = {
-	// 出错占位图
-	errorImg: null,
-	// 过滤器函数
-	filter: null,
-	// 代码高亮函数
-	highlight: null,
-	// 文本处理函数
-	onText: null,
-	// 实体编码列表
-	entities: {
-		quot: '"',
-		apos: "'",
-		semi: ';',
-		nbsp: '\xA0',
-		ensp: '\u2002',
-		emsp: '\u2003',
-		ndash: '–',
-		mdash: '—',
-		middot: '·',
-		lsquo: '‘',
-		rsquo: '’',
-		ldquo: '“',
-		rdquo: '”',
-		bull: '•',
-		hellip: '…'
-	},
-	blankChar: makeMap(' ,\xA0,\t,\r,\n,\f'),
-	boolAttrs: makeMap('allowfullscreen,autoplay,autostart,controls,ignore,loop,muted'),
-	// 块级标签,将被转为 div
-	blockTags: makeMap('address,article,aside,body,caption,center,cite,footer,header,html,nav,pre,section'),
-	// 将被移除的标签
-	ignoreTags: makeMap('area,base,canvas,frame,iframe,input,link,map,meta,param,script,source,style,svg,textarea,title,track,wbr'),
-	// 只能被 rich-text 显示的标签
-	richOnlyTags: makeMap('a,colgroup,fieldset,legend'),
-	// 自闭合的标签
-	selfClosingTags: makeMap('area,base,br,col,circle,ellipse,embed,frame,hr,img,input,line,link,meta,param,path,polygon,rect,source,track,use,wbr'),
-	// 信任的标签
-	trustTags: makeMap('a,abbr,ad,audio,b,blockquote,br,code,col,colgroup,dd,del,dl,dt,div,em,fieldset,h1,h2,h3,h4,h5,h6,hr,i,img,ins,label,legend,li,ol,p,q,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,ul,video'),
-	// 默认的标签样式
-	userAgentStyles: {
-		address: 'font-style:italic',
-		big: 'display:inline;font-size:1.2em',
-		blockquote: 'background-color:#f6f6f6;border-left:3px solid #dbdbdb;color:#6c6c6c;padding:5px 0 5px 10px',
-		caption: 'display:table-caption;text-align:center',
-		center: 'text-align:center',
-		cite: 'font-style:italic',
-		dd: 'margin-left:40px',
-		mark: 'background-color:yellow',
-		pre: 'font-family:monospace;white-space:pre;overflow:scroll',
-		s: 'text-decoration:line-through',
-		small: 'display:inline;font-size:0.8em',
-		u: 'text-decoration:underline'
-	}
-}
-
-function makeMap(str) {
-	var map = Object.create(null),
-		list = str.split(',');
-	for (var i = list.length; i--;)
-		map[list[i]] = true;
-	return map;
-}
-
-// #ifdef MP-WEIXIN
-if (wx.canIUse('editor')) {
-	cfg.blockTags.pre = void 0;
-	cfg.ignoreTags.rp = true;
-	Object.assign(cfg.richOnlyTags, makeMap('bdi,bdo,caption,rt,ruby'));
-	Object.assign(cfg.trustTags, makeMap('bdi,bdo,caption,pre,rt,ruby'));
-}
-// #endif
-
-// #ifdef APP-PLUS
-cfg.ignoreTags.iframe = void 0;
-Object.assign(cfg.trustTags, makeMap('embed,iframe'));
-// #endif
-
-module.exports = cfg;

+ 0 - 22
uview-ui/components/u-parse/libs/handler.wxs

@@ -1,22 +0,0 @@
-var inline = {
-	abbr: 1,
-	b: 1,
-	big: 1,
-	code: 1,
-	del: 1,
-	em: 1,
-	i: 1,
-	ins: 1,
-	label: 1,
-	q: 1,
-	small: 1,
-	span: 1,
-	strong: 1,
-	sub: 1,
-	sup: 1
-}
-module.exports = {
-	use: function(item) {
-		return !item.c && !inline[item.name] && (item.attrs.style || '').indexOf('display:inline') == -1
-	}
-}

+ 0 - 505
uview-ui/components/u-parse/libs/trees.vue

@@ -1,505 +0,0 @@
-<template>
-	<view :class="'interlayer '+(c||'')" :style="s">
-		<block v-for="(n, i) in nodes" v-bind:key="i">
-			<!--图片-->
-			<view v-if="n.name=='img'" :class="'_img '+n.attrs.class" :style="n.attrs.style" :data-attrs="n.attrs" @tap.stop="imgtap">
-				<rich-text v-if="ctrl[i]!=0" :nodes="[{attrs:{src:loading&&(ctrl[i]||0)<2?loading:(lazyLoad&&!ctrl[i]?placeholder:(ctrl[i]==3?errorImg:n.attrs.src||'')),alt:n.attrs.alt||'',width:n.attrs.width||'',style:'-webkit-touch-callout:none;max-width:100%;display:block'+(n.attrs.height?';height:'+n.attrs.height:'')},name:'img'}]" />
-				<image class="_image" :src="lazyLoad&&!ctrl[i]?placeholder:n.attrs.src" :lazy-load="lazyLoad"
-				 :show-menu-by-longpress="!n.attrs.ignore" :data-i="i" :data-index="n.attrs.i" data-source="img" @load="loadImg"
-				 @error="error" />
-			</view>
-			<!--文本-->
-			<text v-else-if="n.type=='text'" decode>{{n.text}}</text>
-			<!--#ifndef MP-BAIDU-->
-			<text v-else-if="n.name=='br'">\n</text>
-			<!--#endif-->
-			<!--视频-->
-			<view v-else-if="((n.lazyLoad&&!n.attrs.autoplay)||(n.name=='video'&&!loadVideo))&&ctrl[i]==undefined" :id="n.attrs.id"
-			 :class="'_video '+(n.attrs.class||'')" :style="n.attrs.style" :data-i="i" @tap.stop="_loadVideo" />
-			<video v-else-if="n.name=='video'" :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :autoplay="n.attrs.autoplay||ctrl[i]==0"
-			 :controls="n.attrs.controls" :loop="n.attrs.loop" :muted="n.attrs.muted" :poster="n.attrs.poster" :src="n.attrs.source[ctrl[i]||0]"
-			 :unit-id="n.attrs['unit-id']" :data-id="n.attrs.id" :data-i="i" data-source="video" @error="error" @play="play" />
-			<!--音频-->
-			<audio v-else-if="n.name=='audio'" :ref="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :author="n.attrs.author"
-			 :autoplay="n.attrs.autoplay" :controls="n.attrs.controls" :loop="n.attrs.loop" :name="n.attrs.name" :poster="n.attrs.poster"
-			 :src="n.attrs.source[ctrl[i]||0]" :data-i="i" :data-id="n.attrs.id" data-source="audio" @error.native="error"
-			 @play.native="play" />
-			<!--链接-->
-			<view v-else-if="n.name=='a'" :id="n.attrs.id" :class="'_a '+(n.attrs.class||'')" hover-class="_hover" :style="n.attrs.style"
-			 :data-attrs="n.attrs" @tap.stop="linkpress">
-				<trees class="_span" c="_span" :nodes="n.children" />
-			</view>
-			<!--广告-->
-			<!--<ad v-else-if="n.name=='ad'" :class="n.attrs.class" :style="n.attrs.style" :unit-id="n.attrs['unit-id']" :appid="n.attrs.appid" :apid="n.attrs.apid" :type="n.attrs.type" :adpid="n.attrs.adpid" data-source="ad" @error="error" />-->
-			<!--列表-->
-			<view v-else-if="n.name=='li'" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:flex;flex-direction:row'">
-				<view v-if="n.type=='ol'" class="_ol-bef">{{n.num}}</view>
-				<view v-else class="_ul-bef">
-					<view v-if="n.floor%3==0" class="_ul-p1">█</view>
-					<view v-else-if="n.floor%3==2" class="_ul-p2" />
-					<view v-else class="_ul-p1" style="border-radius:50%">█</view>
-				</view>
-				<trees class="_li" c="_li" :nodes="n.children" :lazyLoad="lazyLoad" :loading="loading" />
-			</view>
-			<!--表格-->
-			<view v-else-if="n.name=='table'&&n.c&&n.flag" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:grid'">
-				<trees v-for="(cell,n) in n.children" v-bind:key="n" :class="cell.attrs.class" :c="cell.attrs.class" :style="cell.attrs.style"
-				 :s="cell.attrs.style" :nodes="cell.children" />
-			</view>
-			<view v-else-if="n.name=='table'&&n.c" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:table'">
-				<view v-for="(tbody, o) in n.children" v-bind:key="o" :class="tbody.attrs.class" :style="(tbody.attrs.style||'')+(tbody.name[0]=='t'?';display:table-'+(tbody.name=='tr'?'row':'row-group'):'')">
-					<view v-for="(tr, p) in tbody.children" v-bind:key="p" :class="tr.attrs.class" :style="(tr.attrs.style||'')+(tr.name[0]=='t'?';display:table-'+(tr.name=='tr'?'row':'cell'):'')">
-						<trees v-if="tr.name=='td'" :nodes="tr.children" />
-						<trees v-else v-for="(td, q) in tr.children" v-bind:key="q" :class="td.attrs.class" :c="td.attrs.class" :style="(td.attrs.style||'')+(td.name[0]=='t'?';display:table-'+(td.name=='tr'?'row':'cell'):'')"
-						 :s="(td.attrs.style||'')+(td.name[0]=='t'?';display:table-'+(td.name=='tr'?'row':'cell'):'')" :nodes="td.children" />
-					</view>
-				</view>
-			</view>
-			<!--#ifdef APP-PLUS-->
-			<iframe v-else-if="n.name=='iframe'" :style="n.attrs.style" :allowfullscreen="n.attrs.allowfullscreen" :frameborder="n.attrs.frameborder"
-			 :width="n.attrs.width" :height="n.attrs.height" :src="n.attrs.src" />
-			<embed v-else-if="n.name=='embed'" :style="n.attrs.style" :width="n.attrs.width" :height="n.attrs.height" :src="n.attrs.src" />
-			<!--#endif-->
-			<!--富文本-->
-			<!--#ifdef MP-WEIXIN || MP-QQ || APP-PLUS-->
-			<rich-text v-else-if="handler.use(n)" :id="n.attrs.id" :class="'_p __'+n.name" :nodes="[n]" />
-			<!--#endif-->
-			<!--#ifndef MP-WEIXIN || MP-QQ || APP-PLUS-->
-			<rich-text v-else-if="!n.c" :id="n.attrs.id" :nodes="[n]" style="display:inline" />
-			<!--#endif-->
-			<trees v-else :class="(n.attrs.id||'')+' _'+n.name+' '+(n.attrs.class||'')" :c="(n.attrs.id||'')+' _'+n.name+' '+(n.attrs.class||'')"
-			 :style="n.attrs.style" :s="n.attrs.style" :nodes="n.children" :lazyLoad="lazyLoad" :loading="loading" />
-		</block>
-	</view>
-</template>
-<script module="handler" lang="wxs" src="./handler.wxs"></script>
-<script>
-	global.Parser = {};
-	import trees from './trees'
-	const errorImg = require('../libs/config.js').errorImg;
-	export default {
-		components: {
-			trees
-		},
-		name: 'trees',
-		data() {
-			return {
-				ctrl: [],
-				placeholder: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="300" height="225"/>',
-				errorImg,
-				loadVideo: typeof plus == 'undefined',
-				// #ifndef MP-ALIPAY
-				c: '',
-				s: ''
-				// #endif
-			}
-		},
-		props: {
-			nodes: Array,
-			lazyLoad: Boolean,
-			loading: String,
-			// #ifdef MP-ALIPAY
-			c: String,
-			s: String
-			// #endif
-		},
-		mounted() {
-			for (this.top = this.$parent; this.top.$options.name != 'parser'; this.top = this.top.$parent);
-			this.init();
-		},
-		// #ifdef APP-PLUS
-		beforeDestroy() {
-			this.observer && this.observer.disconnect();
-		},
-		// #endif
-		methods: {
-			init() {
-				for (var i = this.nodes.length, n; n = this.nodes[--i];) {
-					if (n.name == 'img') {
-						this.top.imgList.setItem(n.attrs.i, n.attrs['original-src'] || n.attrs.src);
-						// #ifdef APP-PLUS
-						if (this.lazyLoad && !this.observer) {
-							this.observer = uni.createIntersectionObserver(this).relativeToViewport({
-								top: 500,
-								bottom: 500
-							});
-							setTimeout(() => {
-								this.observer.observe('._img', res => {
-									if (res.intersectionRatio) {
-										for (var j = this.nodes.length; j--;)
-											if (this.nodes[j].name == 'img')
-												this.$set(this.ctrl, j, 1);
-										this.observer.disconnect();
-									}
-								})
-							}, 0)
-						}
-						// #endif
-					} else if (n.name == 'video' || n.name == 'audio') {
-						var ctx;
-						if (n.name == 'video') {
-							ctx = uni.createVideoContext(n.attrs.id
-								// #ifndef MP-BAIDU
-								, this
-								// #endif
-							);
-						} else if (this.$refs[n.attrs.id])
-							ctx = this.$refs[n.attrs.id][0];
-						if (ctx) {
-							ctx.id = n.attrs.id;
-							this.top.videoContexts.push(ctx);
-						}
-					}
-				}
-				// #ifdef APP-PLUS
-				// APP 上避免 video 错位需要延时渲染
-				setTimeout(() => {
-					this.loadVideo = true;
-				}, 1000)
-				// #endif
-			},
-			play(e) {
-				var contexts = this.top.videoContexts;
-				if (contexts.length > 1 && this.top.autopause)
-					for (var i = contexts.length; i--;)
-						if (contexts[i].id != e.currentTarget.dataset.id)
-							contexts[i].pause();
-			},
-			imgtap(e) {
-				var attrs = e.currentTarget.dataset.attrs;
-				if (!attrs.ignore) {
-					var preview = true,
-						data = {
-							id: e.target.id,
-							src: attrs.src,
-							ignore: () => preview = false
-						};
-					global.Parser.onImgtap && global.Parser.onImgtap(data);
-					this.top.$emit('imgtap', data);
-					if (preview) {
-						var urls = this.top.imgList,
-							current = urls[attrs.i] ? parseInt(attrs.i) : (urls = [attrs.src], 0);
-						uni.previewImage({
-							current,
-							urls
-						})
-					}
-				}
-			},
-			loadImg(e) {
-				var i = e.currentTarget.dataset.i;
-				if (this.lazyLoad && !this.ctrl[i]) {
-					// #ifdef QUICKAPP-WEBVIEW
-					this.$set(this.ctrl, i, 0);
-					this.$nextTick(function() {
-						// #endif
-						// #ifndef APP-PLUS
-						this.$set(this.ctrl, i, 1);
-						// #endif
-						// #ifdef QUICKAPP-WEBVIEW
-					})
-					// #endif
-				} else if (this.loading && this.ctrl[i] != 2) {
-					// #ifdef QUICKAPP-WEBVIEW
-					this.$set(this.ctrl, i, 0);
-					this.$nextTick(function() {
-						// #endif
-						this.$set(this.ctrl, i, 2);
-						// #ifdef QUICKAPP-WEBVIEW
-					})
-					// #endif
-				}
-			},
-			linkpress(e) {
-				var jump = true,
-					attrs = e.currentTarget.dataset.attrs;
-				attrs.ignore = () => jump = false;
-				global.Parser.onLinkpress && global.Parser.onLinkpress(attrs);
-				this.top.$emit('linkpress', attrs);
-				if (jump) {
-					// #ifdef MP
-					if (attrs['app-id']) {
-						return uni.navigateToMiniProgram({
-							appId: attrs['app-id'],
-							path: attrs.path
-						})
-					}
-					// #endif
-					if (attrs.href) {
-						if (attrs.href[0] == '#') {
-							if (this.top.useAnchor)
-								this.top.navigateTo({
-									id: attrs.href.substring(1)
-								})
-						} else if (attrs.href.indexOf('http') == 0 || attrs.href.indexOf('//') == 0) {
-							// #ifdef APP-PLUS
-							plus.runtime.openWeb(attrs.href);
-							// #endif
-							// #ifndef APP-PLUS
-							uni.setClipboardData({
-								data: attrs.href,
-								success: () =>
-									uni.showToast({
-										title: '链接已复制'
-									})
-							})
-							// #endif
-						} else
-							uni.navigateTo({
-								url: attrs.href,
-								fail() {
-									uni.switchTab({
-										url: attrs.href,
-									})
-								}
-							})
-					}
-				}
-			},
-			error(e) {
-				var target = e.currentTarget,
-					source = target.dataset.source,
-					i = target.dataset.i;
-				if (source == 'video' || source == 'audio') {
-					// 加载其他 source
-					var index = this.ctrl[i] ? this.ctrl[i].i + 1 : 1;
-					if (index < this.nodes[i].attrs.source.length)
-						this.$set(this.ctrl, i, index);
-					if (e.detail.__args__)
-						e.detail = e.detail.__args__[0];
-				} else if (errorImg && source == 'img') {
-					this.top.imgList.setItem(target.dataset.index, errorImg);
-					this.$set(this.ctrl, i, 3);
-				}
-				this.top && this.top.$emit('error', {
-					source,
-					target,
-					errMsg: e.detail.errMsg
-				});
-			},
-			_loadVideo(e) {
-				this.$set(this.ctrl, e.target.dataset.i, 0);
-			}
-		}
-	}
-</script>
-
-<style>
-	/* 在这里引入自定义样式 */
-
-	/* 链接和图片效果 */
-	._a {
-		display: inline;
-		padding: 1.5px 0 1.5px 0;
-		color: #366092;
-		word-break: break-all;
-	}
-
-	._hover {
-		text-decoration: underline;
-		opacity: 0.7;
-	}
-
-	._img {
-		display: inline-block;
-		max-width: 100%;
-		overflow: hidden;
-	}
-
-	/* #ifdef MP-WEIXIN */
-	:host {
-		display: inline;
-	}
-
-	/* #endif */
-
-	/* #ifndef MP-ALIPAY || APP-PLUS */
-	.interlayer {
-		display: inherit;
-		flex-direction: inherit;
-		flex-wrap: inherit;
-		align-content: inherit;
-		align-items: inherit;
-		justify-content: inherit;
-		width: 100%;
-		white-space: inherit;
-	}
-
-	/* #endif */
-
-	._b,
-	._strong {
-		font-weight: bold;
-	}
-
-	/* #ifndef MP-ALIPAY */
-	._blockquote,
-	._div,
-	._p,
-	._ol,
-	._ul,
-	._li {
-		display: block;
-	}
-
-	/* #endif */
-
-	._code {
-		font-family: monospace;
-	}
-
-	._del {
-		text-decoration: line-through;
-	}
-
-	._em,
-	._i {
-		font-style: italic;
-	}
-
-	._h1 {
-		font-size: 2em;
-	}
-
-	._h2 {
-		font-size: 1.5em;
-	}
-
-	._h3 {
-		font-size: 1.17em;
-	}
-
-	._h5 {
-		font-size: 0.83em;
-	}
-
-	._h6 {
-		font-size: 0.67em;
-	}
-
-	._h1,
-	._h2,
-	._h3,
-	._h4,
-	._h5,
-	._h6 {
-		display: block;
-		font-weight: bold;
-	}
-
-	._image {
-		display: block;
-		width: 100%;
-		height: 360px;
-		margin-top: -360px;
-		opacity: 0;
-	}
-
-	._ins {
-		text-decoration: underline;
-	}
-
-	._li {
-		flex: 1;
-		width: 0;
-	}
-
-	._ol-bef {
-		width: 36px;
-		margin-right: 5px;
-		text-align: right;
-	}
-
-	._ul-bef {
-		display: block;
-		margin: 0 12px 0 23px;
-		line-height: normal;
-	}
-
-	._ol-bef,
-	._ul-bef {
-		flex: none;
-		user-select: none;
-	}
-
-	._ul-p1 {
-		display: inline-block;
-		width: 0.3em;
-		height: 0.3em;
-		overflow: hidden;
-		line-height: 0.3em;
-	}
-
-	._ul-p2 {
-		display: inline-block;
-		width: 0.23em;
-		height: 0.23em;
-		border: 0.05em solid black;
-		border-radius: 50%;
-	}
-
-	._q::before {
-		content: '"';
-	}
-
-	._q::after {
-		content: '"';
-	}
-
-	._sub {
-		font-size: smaller;
-		vertical-align: sub;
-	}
-
-	._sup {
-		font-size: smaller;
-		vertical-align: super;
-	}
-
-	/* #ifdef MP-ALIPAY || APP-PLUS || QUICKAPP-WEBVIEW */
-	._abbr,
-	._b,
-	._code,
-	._del,
-	._em,
-	._i,
-	._ins,
-	._label,
-	._q,
-	._span,
-	._strong,
-	._sub,
-	._sup {
-		display: inline;
-	}
-
-	/* #endif */
-
-	/* #ifdef MP-WEIXIN || MP-QQ */
-	.__bdo,
-	.__bdi,
-	.__ruby,
-	.__rt {
-		display: inline-block;
-	}
-
-	/* #endif */
-	._video {
-		position: relative;
-		display: inline-block;
-		width: 300px;
-		height: 225px;
-		background-color: black;
-	}
-
-	._video::after {
-		position: absolute;
-		top: 50%;
-		left: 50%;
-		margin: -15px 0 0 -15px;
-		content: '';
-		border-color: transparent transparent transparent white;
-		border-style: solid;
-		border-width: 15px 0 15px 30px;
-	}
-</style>

+ 3 - 3
uview-ui/components/u-parse/node/node.vue

@@ -201,7 +201,7 @@ export default {
       // #ifdef H5 || APP-PLUS
       node.attrs.src = node.attrs.src || node.attrs['data-src']
       // #endif
-      this.root.$emit('imgtap', node.attrs)
+      this.root.$emit('imgTap', node.attrs)
       // 自动预览图片
       if (this.root.previewImg)
         uni.previewImage({
@@ -262,7 +262,7 @@ export default {
     linkTap(e) {
       var attrs = e.currentTarget ? this.childs[e.currentTarget.dataset.i].attrs : e,
         href = attrs.href
-      this.root.$emit('linktap', attrs)
+      this.root.$emit('linkTap', attrs)
       if (href) {
         // 跳转锚点
         if (href[0] == '#')
@@ -496,4 +496,4 @@ export default {
   height: 225px;
 }
 /* #endif */
-</style>
+</style>

+ 6 - 6
uview-ui/components/u-picker/props.js

@@ -50,11 +50,6 @@ export default {
             type: String,
             default: uni.$u.props.picker.confirmColor
         },
-        // 选择器只有一列时,默认选中项的索引,从0开始
-        singleIndex: {
-            type: [String, Number],
-            default: uni.$u.props.picker.singleIndex
-        },
         // 每列中可见选项的数量
         visibleItemCount: {
             type: [String, Number],
@@ -74,6 +69,11 @@ export default {
         defaultIndex: {
             type: Array,
             default: uni.$u.props.picker.defaultIndex
-        }
+        },
+		// 是否在手指松开时立即触发 change 事件。若不开启则会在滚动动画结束后触发 change 事件,只在微信2.21.1及以上有效
+		immediateChange: {
+			type: Boolean,
+			default: uni.$u.props.picker.immediateChange
+		}
     }
 }

+ 3 - 2
uview-ui/components/u-picker/u-picker.vue

@@ -18,6 +18,7 @@
 				class="u-picker__view"
 				:indicatorStyle="`height: ${$u.addUnit(itemHeight)}`"
 				:value="innerIndex"
+				:immediateChange="immediateChange"
 				:style="{
 					height: `${$u.addUnit(visibleItemCount * itemHeight)}`
 				}"
@@ -65,11 +66,11 @@
  * @property {String}			confirmText			确认按钮的文字(默认 '确定' )
  * @property {String}			cancelColor			取消按钮的颜色(默认 '#909193' )
  * @property {String}			confirmColor		确认按钮的颜色(默认 '#3c9cff' )
- * @property {Array}			singleIndex			选择器只有一列时,默认选中项的索引,从0开始(默认 0 )
  * @property {String | Number}	visibleItemCount	每列中可见选项的数量(默认 5 )
  * @property {String}			keyName				选项对象中,需要展示的属性键名(默认 'text' )
  * @property {Boolean}			closeOnClickOverlay	是否允许点击遮罩关闭选择器(默认 false )
  * @property {Array}			defaultIndex		各列的默认索引
+ * @property {Boolean}			immediateChange		是否在手指松开时立即触发change事件(默认 false )
  * @event {Function} close		关闭选择器时触发
  * @event {Function} cancel		点击取消按钮触发
  * @event {Function} change		当选择值变化时触发
@@ -159,7 +160,7 @@ export default {
 			this.setIndexs(value)
 
 			this.$emit('change', {
-				// #ifndef MP-WEIXIN
+				// #ifndef MP-WEIXIN || MP-LARK
 				// 微信小程序不能传递this,会因为循环引用而报错
 				picker: this,
 				// #endif

+ 6 - 3
uview-ui/components/u-popup/u-popup.vue

@@ -4,7 +4,7 @@
 			:show="show"
 			@click="overlayClick"
 			v-if="overlay"
-			:duration="duration"
+			:duration="overlayDuration"
 			:customStyle="overlayStyle"
 			:opacity="overlayOpacity"
 		></u-overlay>
@@ -13,7 +13,7 @@
 			:customStyle="transitionStyle"
 			:mode="position"
 			:duration="duration"
-			@after-enter="afterEnter"
+			@afterEnter="afterEnter"
 			@click="clickHandler"
 		>
 			<view
@@ -55,6 +55,7 @@
 	 * @property {Boolean}			overlay				是否显示遮罩 (默认 true )
 	 * @property {String}			mode				弹出方向(默认 'bottom' )
 	 * @property {String | Number}	duration			动画时长,单位ms (默认 300 )
+	 * @property {String | Number}	overlayDuration			遮罩层动画时长,单位ms (默认 350 )
 	 * @property {Boolean}			closeable			是否显示关闭图标(默认 false )
 	 * @property {Object | String}	overlayStyle		自定义遮罩的样式
 	 * @property {String | Number}	overlayOpacity		遮罩透明度,0-1之间(默认 0.5)
@@ -74,7 +75,9 @@
 		name: 'u-popup',
 		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
 		data() {
-			return {}
+			return {
+				overlayDuration: this.duration + 50
+			}
 		},
 		watch: {
 			show(newValue, oldValue) {

+ 11 - 9
uview-ui/components/u-radio/u-radio.vue

@@ -20,15 +20,17 @@
 				/>
 			</slot>
 		</view>
-		<text
-			class="u-radio__text"
-		    @tap.stop="labelClickHandler"
-		    :style="{
-				color: elDisabled ? elInactiveColor : elLabelColor,
-				fontSize: elLabelSize,
-				lineHeight: elLabelSize
-			}"
-		>{{label}}</text>
+		<slot>
+			<text
+				class="u-radio__text"
+				@tap.stop="labelClickHandler"
+				:style="{
+					color: elDisabled ? elInactiveColor : elLabelColor,
+					fontSize: elLabelSize,
+					lineHeight: elLabelSize
+				}"
+			>{{label}}</text>
+		</slot>
 	</view>
 </template>
 

+ 5 - 0
uview-ui/components/u-rate/props.js

@@ -15,6 +15,11 @@ export default {
             type: Boolean,
             default: uni.$u.props.rate.disabled
         },
+        // 是否只读
+        readonly: {
+            type: Boolean,
+            default: uni.$u.props.rate.readonly
+        },
         // 星星的大小,单位px
         size: {
             type: [String, Number],

+ 6 - 3
uview-ui/components/u-rate/u-rate.vue

@@ -35,7 +35,8 @@
                                 : inactiveColor
                         "
                         :custom-style="{
-                            padding: `0 ${$u.addUnit(gutter / 2)}`,
+                            'padding-left': $u.addUnit(gutter / 2),
+							'padding-right': $u.addUnit(gutter / 2)
                         }"
                         :size="size"
                     ></u-icon>
@@ -63,7 +64,8 @@
                                 : inactiveColor
                         "
                         :custom-style="{
-                            padding: `0 ${$u.addUnit(gutter / 2)}`
+							'padding-left': $u.addUnit(gutter / 2),
+							'padding-right': $u.addUnit(gutter / 2)
                         }"
                         :size="size"
                     ></u-icon>
@@ -86,6 +88,7 @@
 	 * @property {String | Number}	value			用于v-model双向绑定选中的星星数量 (默认 1 )
 	 * @property {String | Number}	count			最多可选的星星数量 (默认 5 )
 	 * @property {Boolean}			disabled		是否禁止用户操作 (默认 false )
+	 * @property {Boolean}			readonly		是否只读 (默认 false )
 	 * @property {String | Number}	size			星星的大小,单位px (默认 18 )
 	 * @property {String}			inactiveColor	未选中星星的颜色 (默认 '#b2b2b2' )
 	 * @property {String}			activeColor		选中的星星颜色 (默认 '#FA3534' )
@@ -206,7 +209,7 @@
 			},
 			// 获取当前激活的评分图标
 			getActiveIndex(x,isClick = false) {
-				if (this.disabled) {
+				if (this.disabled || this.readonly) {
 					return;
 				}
 				// 判断当前操作的点的x坐标值,是否在允许的边界范围内

+ 29 - 5
uview-ui/components/u-row-notice/u-row-notice.vue

@@ -19,11 +19,17 @@
 			class="u-notice__content"
 			ref="u-notice__content"
 		>
-			<text
+			<view
 				ref="u-notice__content__text"
 				class="u-notice__content__text"
-				:style="[textStyle]"
-			>{{text}}</text>
+				:style="[animationStyle]"
+			>
+				<text
+					v-for="(item, index) in innerText"
+					:key="index"
+					:style="[textStyle]"
+				>{{item}}</text>
+			</view>
 		</view>
 		<view
 			class="u-notice__right-icon"
@@ -97,7 +103,7 @@
 				}
 			},
 			fontSize() {
-				t // #ifdef APP-NVUE
+				// #ifdef APP-NVUE
 				this.nvueInit = true
 				// #endif
 				// #ifndef APP-NVUE
@@ -118,11 +124,28 @@
 			textStyle() {
 				let style = {}
 				style.color = this.color
+				style.fontSize = uni.$u.addUnit(this.fontSize)
+				return style
+			},
+			animationStyle() {
+				let style = {}
 				style.animationDuration = this.animationDuration
 				style.animationPlayState = this.animationPlayState
-				style.fontSize = uni.$u.addUnit(this.fontSize)
 				return style
 			},
+			// 内部对用户传入的数据进一步分割,放到多个text标签循环,否则如果用户传入的字符串很长(100个字符以上)
+			// 放在一个text标签中进行滚动,在低端安卓机上,动画可能会出现抖动现象,需要分割到多个text中可解决此问题
+			innerText() {
+				let result = [],
+					// 每组text标签的字符长度
+					len = 20
+				const textArr = this.text.split('')
+				for (let i = 0; i < textArr.length; i += len) {
+					// 对拆分的后的text进行slice分割,得到的为数组再进行join拼接为字符串
+					result.push(textArr.slice(i, i + len).join(''))
+				}
+				return result
+			}
 		},
 		mounted() {
 			// #ifdef APP-PLUS
@@ -289,6 +312,7 @@
 				white-space: nowrap;
 				animation: u-loop-animation 10s linear infinite both;
 				/* #endif */
+				@include flex(row);
 			}
 		}
 

+ 0 - 2
uview-ui/components/u-scroll-list/u-scroll-list.vue

@@ -72,13 +72,11 @@
 	</view>
 </template>
 
-<!-- #ifndef APP-NVUE || MP-WEIXIN || H5 || APP-VUE || MP-QQ -->
 <script
 	src="./scrollWxs.wxs"
 	module="wxs"
 	lang="wxs"
 ></script>
-<!-- #endif -->
 
 <script>
 /**

+ 4 - 0
uview-ui/components/u-search/props.js

@@ -80,6 +80,10 @@ export default {
             type: String,
             default: uni.$u.props.search.searchIcon
         },
+        searchIconSize: {
+            type: [Number, String],
+            default: uni.$u.props.search.searchIconSize
+        },
         // 组件与其他上下左右元素之间的距离,带单位的字符串形式,如"30px"、"30px 20px"等写法
         margin: {
             type: String,

Some files were not shown because too many files changed in this diff