Roebin 2 rokov pred
rodič
commit
ea290f396b
100 zmenil súbory, kde vykonal 8501 pridanie a 22 odobranie
  1. 16 0
      .hbuilderx/launch.json
  2. 114 2
      App.vue
  3. 75 0
      common/common.js
  4. 55 0
      componet/calllips/calllips.vue
  5. 212 0
      componet/tabbar/tabbar.vue
  6. 307 0
      componet/up-load-image/up-load-image.vue
  7. 1 1
      http/baseUrl.js
  8. 8 0
      http/new_file.vue
  9. 3 2
      http/request.js
  10. 49 15
      main.js
  11. 4 2
      manifest.json
  12. 2 0
      node_modules/@vue/devtools-api/lib/cjs/api/api.js
  13. 2 0
      node_modules/@vue/devtools-api/lib/cjs/api/app.js
  14. 2 0
      node_modules/@vue/devtools-api/lib/cjs/api/component.js
  15. 2 0
      node_modules/@vue/devtools-api/lib/cjs/api/context.js
  16. 2 0
      node_modules/@vue/devtools-api/lib/cjs/api/hooks.js
  17. 22 0
      node_modules/@vue/devtools-api/lib/cjs/api/index.js
  18. 2 0
      node_modules/@vue/devtools-api/lib/cjs/api/util.js
  19. 5 0
      node_modules/@vue/devtools-api/lib/cjs/const.js
  20. 17 0
      node_modules/@vue/devtools-api/lib/cjs/env.js
  21. 44 0
      node_modules/@vue/devtools-api/lib/cjs/index.js
  22. 2 0
      node_modules/@vue/devtools-api/lib/cjs/plugin.js
  23. 111 0
      node_modules/@vue/devtools-api/lib/cjs/proxy.js
  24. 28 0
      node_modules/@vue/devtools-api/lib/cjs/time.js
  25. 108 0
      node_modules/@vue/devtools-api/lib/esm/api/api.d.ts
  26. 1 0
      node_modules/@vue/devtools-api/lib/esm/api/api.js
  27. 1 0
      node_modules/@vue/devtools-api/lib/esm/api/app.d.ts
  28. 1 0
      node_modules/@vue/devtools-api/lib/esm/api/app.js
  29. 77 0
      node_modules/@vue/devtools-api/lib/esm/api/component.d.ts
  30. 1 0
      node_modules/@vue/devtools-api/lib/esm/api/component.js
  31. 5 0
      node_modules/@vue/devtools-api/lib/esm/api/context.d.ts
  32. 1 0
      node_modules/@vue/devtools-api/lib/esm/api/context.js
  33. 179 0
      node_modules/@vue/devtools-api/lib/esm/api/hooks.d.ts
  34. 1 0
      node_modules/@vue/devtools-api/lib/esm/api/hooks.js
  35. 6 0
      node_modules/@vue/devtools-api/lib/esm/api/index.d.ts
  36. 6 0
      node_modules/@vue/devtools-api/lib/esm/api/index.js
  37. 4 0
      node_modules/@vue/devtools-api/lib/esm/api/util.d.ts
  38. 1 0
      node_modules/@vue/devtools-api/lib/esm/api/util.js
  39. 2 0
      node_modules/@vue/devtools-api/lib/esm/const.d.ts
  40. 2 0
      node_modules/@vue/devtools-api/lib/esm/const.js
  41. 15 0
      node_modules/@vue/devtools-api/lib/esm/env.d.ts
  42. 12 0
      node_modules/@vue/devtools-api/lib/esm/env.js
  43. 18 0
      node_modules/@vue/devtools-api/lib/esm/index.d.ts
  44. 26 0
      node_modules/@vue/devtools-api/lib/esm/index.js
  45. 47 0
      node_modules/@vue/devtools-api/lib/esm/plugin.d.ts
  46. 1 0
      node_modules/@vue/devtools-api/lib/esm/plugin.js
  47. 20 0
      node_modules/@vue/devtools-api/lib/esm/proxy.d.ts
  48. 107 0
      node_modules/@vue/devtools-api/lib/esm/proxy.js
  49. 2 0
      node_modules/@vue/devtools-api/lib/esm/time.d.ts
  50. 23 0
      node_modules/@vue/devtools-api/lib/esm/time.js
  51. 67 0
      node_modules/@vue/devtools-api/package.json
  52. 21 0
      node_modules/uview-ui/LICENSE
  53. 104 0
      node_modules/uview-ui/README.md
  54. 326 0
      node_modules/uview-ui/changelog.md
  55. 78 0
      node_modules/uview-ui/components/u--form/u--form.vue
  56. 47 0
      node_modules/uview-ui/components/u--image/u--image.vue
  57. 72 0
      node_modules/uview-ui/components/u--input/u--input.vue
  58. 44 0
      node_modules/uview-ui/components/u--text/u--text.vue
  59. 47 0
      node_modules/uview-ui/components/u--textarea/u--textarea.vue
  60. 54 0
      node_modules/uview-ui/components/u-action-sheet/props.js
  61. 278 0
      node_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue
  62. 59 0
      node_modules/uview-ui/components/u-album/props.js
  63. 259 0
      node_modules/uview-ui/components/u-album/u-album.vue
  64. 44 0
      node_modules/uview-ui/components/u-alert/props.js
  65. 243 0
      node_modules/uview-ui/components/u-alert/u-alert.vue
  66. 52 0
      node_modules/uview-ui/components/u-avatar-group/props.js
  67. 103 0
      node_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue
  68. 78 0
      node_modules/uview-ui/components/u-avatar/props.js
  69. 58 0
      node_modules/uview-ui/components/u-avatar/u-avatar.vue
  70. 54 0
      node_modules/uview-ui/components/u-back-top/props.js
  71. 129 0
      node_modules/uview-ui/components/u-back-top/u-back-top.vue
  72. 72 0
      node_modules/uview-ui/components/u-badge/props.js
  73. 171 0
      node_modules/uview-ui/components/u-badge/u-badge.vue
  74. 46 0
      node_modules/uview-ui/components/u-button/nvue.scss
  75. 161 0
      node_modules/uview-ui/components/u-button/props.js
  76. 490 0
      node_modules/uview-ui/components/u-button/u-button.vue
  77. 80 0
      node_modules/uview-ui/components/u-button/vue.scss
  78. 99 0
      node_modules/uview-ui/components/u-calendar/header.vue
  79. 579 0
      node_modules/uview-ui/components/u-calendar/month.vue
  80. 144 0
      node_modules/uview-ui/components/u-calendar/props.js
  81. 383 0
      node_modules/uview-ui/components/u-calendar/u-calendar.vue
  82. 85 0
      node_modules/uview-ui/components/u-calendar/util.js
  83. 14 0
      node_modules/uview-ui/components/u-car-keyboard/props.js
  84. 311 0
      node_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue
  85. 14 0
      node_modules/uview-ui/components/u-cell-group/props.js
  86. 61 0
      node_modules/uview-ui/components/u-cell-group/u-cell-group.vue
  87. 110 0
      node_modules/uview-ui/components/u-cell/props.js
  88. 229 0
      node_modules/uview-ui/components/u-cell/u-cell.vue
  89. 82 0
      node_modules/uview-ui/components/u-checkbox-group/props.js
  90. 103 0
      node_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue
  91. 69 0
      node_modules/uview-ui/components/u-checkbox/props.js
  92. 344 0
      node_modules/uview-ui/components/u-checkbox/u-checkbox.vue
  93. 8 0
      node_modules/uview-ui/components/u-circle-progress/props.js
  94. 198 0
      node_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue
  95. 74 0
      node_modules/uview-ui/components/u-code-input/props.js
  96. 251 0
      node_modules/uview-ui/components/u-code-input/u-code-input.vue
  97. 34 0
      node_modules/uview-ui/components/u-code/props.js
  98. 129 0
      node_modules/uview-ui/components/u-code/u-code.vue
  99. 29 0
      node_modules/uview-ui/components/u-col/props.js
  100. 162 0
      node_modules/uview-ui/components/u-col/u-col.vue

+ 16 - 0
.hbuilderx/launch.json

xqd
@@ -0,0 +1,16 @@
+{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
+  // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
+    "version": "0.0",
+    "configurations": [{
+     	"default" : 
+     	{
+     		"launchtype" : "local"
+     	},
+     	"mp-weixin" : 
+     	{
+     		"launchtype" : "local"
+     	},
+     	"type" : "uniCloud"
+     }
+    ]
+}

+ 114 - 2
App.vue

xqd
@@ -1,17 +1,129 @@
+
 <script>
 	export default {
 		onLaunch: function() {
+			// this.init()
 			console.log('App Launch')
 		},
 		onShow: function() {
+			this.init()
 			console.log('App Show')
 		},
+		onLoad() {
+			this.init()
+		},
 		onHide: function() {
 			console.log('App Hide')
+		},
+
+		methods: {
+			init() {
+				let state = this.$store.state.admin
+				// console.log(state, 778)
+				if (state == 0) {
+					uni.setTabBarItem({
+					 index: 0,
+						pagePath: "pages/index/index",
+						text: "合同列表",
+						iconPath: "/static/icon/home.png",
+						selectedIconPath: "/static/icon/achome.png",
+						visible: true
+					})
+					uni.setTabBarItem({
+						index: 1,
+					 pagePath: "pages/acceptor/acceptor",
+						text: "承兑人",
+						iconPath: "/static/icon/per.png",
+						selectedIconPath: "/static/icon/out.png",
+					})
+					uni.setTabBarItem({
+						index: 2,
+						pagePath: "pages/drawer/drawer",
+						text: "出票人",
+						iconPath: "/static/icon/acsip.png",
+						selectedIconPath: "/static/icon/biao.png",
+						visible: true
+					})
+					uni.setTabBarItem({
+						index: 3,
+						pagePath: "pages/supplier/supplier",
+						text: "供应商",
+						iconPath: "/static/icon/acsup.png",
+						selectedIconPath: "/static/icon/sup.png",
+						visible: false
+					})
+					uni.setTabBarItem({
+						index: 4,
+						pagePath: "pages/mine/mine",
+						text: "我的",
+						iconPath: "/static/icon/my.png",
+						selectedIconPath: "/static/icon/acmy.png",
+						visible: false
+					})
+				} else if (state == 1) {
+					uni.setTabBarItem({
+						index: 0,
+						pagePath: "pages/index/index",
+						text: "合同列表",
+						iconPath: "/static/icon/home.png",
+						selectedIconPath: "/static/icon/achome.png",
+						visible: true
+					})
+					uni.setTabBarItem({
+					  index: 1,
+					 pagePath: "pages/acceptor/acceptor",
+					 text: "承兑人",
+					 iconPath: "/static/icon/card-2x.png",
+					 selectedIconPath: "/static/icon/card_active-2x.png",
+					  visible:false
+					})
+					uni.setTabBarItem({
+					  index: 2,
+					pagePath: "pages/drawer/drawer",
+					text: "出票人",
+					iconPath: "/static/icon/counter-2x.png",
+					selectedIconPath: "/static/icon/counter_active-2x.png",
+					 visible:false
+					})
+					uni.setTabBarItem({
+					  index: 3,
+					pagePath: "pages/supplier/supplier",
+					text: "供应商",
+					iconPath: "/static/icon/record-2x.png",
+					selectedIconPath: "/static/icon/record_active-2x.png",
+					 visible:false
+					})
+					uni.setTabBarItem({
+						index:4,
+						pagePath: "pages/mine/mine",
+						text: "我的",
+						iconPath: "/static/icon/my.png",
+						selectedIconPath: "/static/icon/acmy.png",
+						visible: true
+					})
+				}
+			},
 		}
 	}
 </script>
+<style lang="scss">
+	page {
+		color: #1F242A;
+	}
+
+	@import 'uview-ui/theme.scss';
+	@import "@/static/css/flex.scss";
+
+	page {
+		font-family: Source Han Sans CN-Medium;
+	}
+	.safebt{
+		padding-bottom: 150rpx;
+	}
+	.statues_bar {
+		height: var(--status-bar-height);
+		width: 100%;
+	}
+
 
-<style>
-	/*每个页面公共css */
 </style>

+ 75 - 0
common/common.js

xqd
@@ -0,0 +1,75 @@
+import {
+	mainUrl
+} from '@/http/baseUrl.js';
+export default {
+	// 选择图片
+	chooseImage(Num) {
+		
+		var list=[]
+		console.log(Num)
+		var maxNum=Num
+		console.log(maxNum)
+		uni.chooseImage({
+			count: maxNum,
+			success: function(e) {
+				for (let i in e.tempFilePaths) {
+					if (i >= (maxNum - list.length)) {
+						break;
+					}
+					let fileName = '';
+					
+					// // #ifdef MP-BAIDU
+					// fileName = e.tempFilePaths[i].substr(e.tempFilePaths[i].lastIndexOf('/') + 1);
+					// // #endif
+					uni.uploadFile({
+						url:mainUrl+'/api/File',
+						filePath: e.tempFilePaths[i],
+						name: 'File',
+						fileType: 'image',
+						header:{
+							"User-Agent":"apifox/1.0.0 (https://www.apifox.cn)"
+						},
+						formData: {
+							File: JSON.stringify(e.tempFilePaths[i]),
+							// file_name: fileName,
+						},
+						success(re) {
+							let res=JSON.parse(re.data)
+							if (res.code == 200) {
+								console.log(res.data.file,2225)
+								var list=[]
+								list.push(res.data.file)
+								console.log(list,899)
+								
+							} else {
+								console.log(55)
+								uni.showModal({
+									title: '',
+									content: res.msg,
+									showCancel: false,
+								});
+							}
+						},
+						fail(e) {
+							if (e && e.msg) {
+								uni.showModal({
+									title: '错误',
+									content: e.msg,
+									showCancel: false,
+								});
+							}
+						},
+					});
+				}
+			
+			},
+			complete: function(e) {
+				// 触发事件 tabEvent
+				return []
+			}
+		})
+		return list
+	}
+	
+	
+	}

+ 55 - 0
componet/calllips/calllips.vue

xqd
@@ -0,0 +1,55 @@
+<template>
+     <el-select
+        v-model="value2"
+        allow-create
+                 filterable multiple collapse-tags
+        default-first-option
+        placeholder="请选择文章标签">
+        <el-option
+          v-for="item in options"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value">
+        </el-option>
+      </el-select>
+</li>
+    </div>
+</template>
+
+<script type="text/ecmascript-6">
+  export default {
+    data() {
+      return {
+         options: [{
+          value: 'HTML',
+          label: 'HTML'
+        }, {
+          value: 'CSS',
+          label: 'CSS'
+        }, {
+          value: 'JavaScript',
+          label: 'JavaScript'
+        }],
+        value2: ['HTML','CSS']
+
+      }
+    },
+    methods: {
+      arrowDown() {
+        this.isShowSelect = !this.isShowSelect;
+      },
+      select(item, index) {
+        this.isShowSelect = false;
+        console.log(item);
+        console.log(index);
+        this.unitModel = index;
+        this.unitName = item.value;
+      }
+    }
+  };
+</script>
+
+
+<style scoped>
+
+</style>

+ 212 - 0
componet/tabbar/tabbar.vue

xqd
@@ -0,0 +1,212 @@
+<template>
+	<view class="wh100 fixed" :style="{'padding-bottom':wagesheight+'rpx'}">
+		<view class="tabbar-box">
+			<view class="item" @tap="goPage('/pages/index/index','home')">
+				<view class="icon-box">
+					<image src="/static/icon/home.png" mode="aspectFit" v-if="checked!=='home'"></image>
+					<image src="/static/icon/achome.png" mode="aspectFit" v-if="checked=='home'"></image>
+				</view>
+				<text :class="checked=='home' ? 'active' : 'nomal'">合同列表</text>
+			</view>
+			<view class="item" @tap="goPage('/pages/acceptor/acceptor','acceptor')" v-if="state==0">
+				<view class="icon-box">
+					<image src="/static/icon/per.png" mode="aspectFit" v-if="checked!='acceptor'"></image>
+					<image src="/static/icon/out.png" mode="aspectFit" v-if="checked=='acceptor'"></image>
+				</view>
+				<text :class="checked=='acceptor' ? 'active' : 'nomal'">承兑人</text>
+			</view>
+			<view class="item" @tap="goPage('/pages/drawer/drawer','drawer')" v-if="state==0">
+				<view class="icon-box">
+					<image src="/static/icon/acsip.png" mode="aspectFit" v-if="checked!='drawer'"></image>
+					<image src="/static/icon/biao.png" mode="aspectFit" v-if="checked=='drawer'"></image>
+				</view>
+				<text :class="checked=='drawer' ? 'active' : 'nomal'">出票人</text>
+			</view>
+			<view class="item" @tap="goPage('/pages/supplier/supplier','supplier')" v-if="state==0">
+				<view class="icon-box">
+					<image src="/static/icon/acsup.png" mode="aspectFit" v-if="checked!='supplier'"></image>
+					<image src="/static/icon/sup.png" mode="aspectFit" v-if="checked=='supplier'"></image>
+				</view>
+				<text :class="checked=='supplier' ? 'active' : 'nomal'">供应商</text>
+			</view>
+			<view class="iconas" @tap="goContract('/pages/alldeatil/upcontract','upcontract')" v-if="state==1" >
+				<view class="plusicon" :style="{'bottom':wagesheight+'rpx'}">
+					
+					
+				</view>
+			</view>
+
+			<view class="item" @tap="goPage('/pages/mine/mine','my')">
+				<view class="icon-box2">
+					<image src="/static/icon/my.png" mode="aspectFit" v-if="checked!='my'"></image>
+					<image src="/static/icon/acmy.png" mode="aspectFit" v-if="checked=='my'"></image>
+				</view>
+				<text :class="checked=='my' ? 'active' : 'nomal'">我的</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	let that
+	export default {
+		name: 'tabbar',
+		data() {
+			return {
+				state: 0,
+				wagesheight:''
+			};
+		},
+		props: {
+			checked: {
+				type: String,
+				default: 'home'
+			}
+		},
+		mounted() {
+			that=this
+			that.state=that.$store.state.admin
+			console.log(that.state,888)
+			uni.getSystemInfo({
+				success: function(res) {
+					let bottom= res.safeArea.bottom
+					let height= res.safeArea.height
+					let cacl=bottom-height
+					that.wagesheight =cacl
+				}
+			})
+
+
+		},
+		methods: {
+			goContract(url, tab) {
+				if (this.checked == tab) return;
+				uni.navigateTo({
+					url: url,
+					animationType: 'slide-out-right',
+				})
+			},
+			goPage(url, tab) {
+				if (this.checked == tab) return;
+				uni.reLaunch({
+					url: url,
+					animationType: 'slide-out-right',
+				})
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.status_height {
+		padding-bottom: 80rpx;
+		// padding-bottom: env(safe-area-inset-bottom);
+		width: 100%;
+	}
+
+	.wh100 {
+		width: 100%;
+		height: 50px;
+		// padding-bottom:44rpx;
+		background-color: #fff;
+		// margin-bottom: 80rpx;
+		// background: url("@/static/img/tababr.png");
+		background-size: 100%;
+		// box-shadow: 0px -2px 10rpx 0px rgba(181, 181, 181, 0.5);
+	}
+
+	.fixed {
+		position: fixed;
+		z-index: 999;
+		bottom: 0;
+	}
+
+	.tabbar-box {
+		height: 100%;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		background-color: #fff;
+		border-top: solid 1px #f5f5f5;
+		
+		.item {
+			flex: 1;
+			font-size: 12px;
+			display: flex;
+			flex-direction: column;
+			justify-content: center;
+			align-items: center;
+			height: 100%;
+			text-align: center;
+
+			.icon-box {
+				width: 24px;
+				height: 24px;
+				
+				image {
+					width: 100%;
+					height: 100%;
+				}
+			}
+
+			.icon-box2 {
+				width: 20px;
+				height: 20px;
+
+				image {
+					width: 100%;
+					height: 100%;
+				}
+			}
+
+			.active {
+				font-weight: bold;
+				color: $theme-color;
+			}
+
+			.nomal {
+				font-weight: 500;
+				color: #393939;
+			}
+		}
+
+		.jy {
+			// margin-bottom: 20px;
+			.icon-box {
+				width: 40px;
+				height: 40px;
+				// background: #fff;
+				border-radius: 50%;
+				line-height: 40px;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				padding: 8rpx;
+				box-sizing: border-box;
+				// box-shadow: 0px -2px 10rpx 0px rgba(181, 181, 181, 0.5);
+				// box-shadow: 0px -2px 20px 0px rgba(181, 181, 181, 0.5);
+
+				image {
+					width: 40px;
+					height: 40px;
+				}
+			}
+
+		}
+	}
+	.iconas{
+		width: 180rpx;
+	}
+	.plusicon{
+		position: fixed;
+		left: 0;
+		right: 0;
+		margin: 0 auto;
+		bottom:-20rpx;
+		width: 150rpx;
+		height: 150rpx;
+		background: url("@/static/img/plusicon.png") no-repeat;
+		background-size: 100%;
+	}
+	
+</style>

+ 307 - 0
componet/up-load-image/up-load-image.vue

xqd
@@ -0,0 +1,307 @@
+<template>
+    <view class="app-upload-image">
+        <view class='upload-box' :style="{'background':backgroundColor}">
+            <view class='flex-wrap'>
+                <view v-for='(item, index) in imageList' :key='item.id' class='img-box'>
+                    <view mode="aspectFill" @click='remove(index)' class='remove cross-center main-center'>x</view>
+                    <image @click='previewImage(index)' :src='item' mode="aspectFill" class='img'></image>
+                </view>
+                <view @click='chooseImage'>
+                    <view v-if='isAddImg' :style="{'margin':margin + 'rpx','background-color':bgUp}" :class="{'other-border': diy ? true : false}" class="add-img dir-top-nowrap cross-center main-center" >
+                        <image mode="aspectFill" class='add-img-icon' :src='defaultImg'></image>
+                        <text class='text'>{{text}}</text>
+                        <text class='text' v-if="showNumber">(最多{{maxNum}}张)</text>
+                    </view>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+<script>
+import uploadFile from '@/core/upload.js';
+
+export default {
+    name: 'app-upload-image',
+    props: {
+        value: {
+            default: null,
+        },
+        defaultImg: {
+            // 添加图片的默认背景图片
+            type: String,
+            default: 'https://shop.9026.com/web/statics/image/mall/static/icon/icon-image.png'
+        },
+        maxNum: {
+            // 可添加最大图片数量
+            type: [Number, String],
+            default: 3
+        },
+        // 标记
+        // 当组件用于循环时使用
+        sign: {
+            type: String,
+            default: ''
+        },
+        backgroundColor: {
+            type: String,
+            default: '#f7f7f7',
+        },
+		bgUp: {
+		    type: String,
+		    // default: '#000',
+		},
+        margin: {
+            type: String,
+            default: '10'
+        },
+        diy: {
+            type: Boolean,
+            default: false
+        },
+        showNumber: {
+            type: Boolean,
+            default: true,
+        },
+        text: {
+            type: String,
+            default: '上传图片',
+        },
+        count: {
+            type: Number,
+            default: 9
+        }
+    },
+    data() {
+        return {
+            imageList: this.value ? this.value : [],
+            isAddImg: true
+        }
+    },
+    methods: {
+        // 上传最大图片数量
+        checkMaxNum() {
+            let status = this.imageList.length >= this.maxNum ? false : true;
+            this.isAddImg = status;
+        },
+        // 移除图片
+        remove(index) {
+            let imageList = this.imageList;
+            let data = imageList.splice(index, 1);
+            this.imageList = imageList;
+            this.checkMaxNum();
+
+            // 触发事件 tabEvent
+            this.$emit('imageEvent', {
+                imageList: imageList,
+                sign: this.sign
+            })
+        },
+        // 选择图片
+        chooseImage() {
+            let self = this;
+            let imageList = self.imageList;
+            // #ifdef MP
+            uni.chooseImage({
+                count: self.maxNum,
+                success: function(e) {
+                    for (let i in e.tempFilePaths) {
+                        if (i >= (self.maxNum - imageList.length)) {
+                            break;
+                        }
+                        let fileName = '';
+                        // #ifdef MP-BAIDU
+                        fileName = e.tempFilePaths[i].substr(e.tempFilePaths[i].lastIndexOf('/') + 1);
+                        // #endif
+                        uni.uploadFile({
+                            url: self.$api.upload.file,
+                            filePath: e.tempFilePaths[i],
+                            name: 'file',
+                            fileType: 'image',
+                            formData: {
+                                file: e.tempFilePaths[i],
+                                file_name: fileName,
+                            },
+                            success(res) {
+                                const data = res.data;
+                                let result = null;
+                                if (typeof data === 'string') {
+                                    result = JSON.parse(data);
+                                } else {
+                                    result = data;
+                                }
+                                if (result.code == 0) {
+                                    imageList.push(result.data.url)
+                                    self.imageList = imageList;
+                                    self.checkMaxNum();
+                                    self.$emit('imageEvent', {
+                                        imageList: imageList,
+                                        sign: self.sign
+                                    });
+                                } else {
+                                    uni.showModal({
+                                        title: '',
+                                        content: result.msg,
+                                        showCancel: false,
+                                    });
+                                }
+                            },
+                            fail(e) {
+                                if (e && e.errMsg) {
+                                    uni.showModal({
+                                        title: '错误',
+                                        content: e.errMsg,
+                                        showCancel: false,
+                                    });
+                                }
+                            },
+                        });
+                    }
+                },
+                complete: function(e) {
+                    // 触发事件 tabEvent
+                    self.$emit('imageEvent', {
+                        imageList: imageList,
+                        sign: self.sign
+                    })
+                }
+            })
+            // #endif
+
+
+
+            // #ifdef H5
+            uni.chooseImage({
+                count: Number(self.maxNum),
+                success: function(e) {
+                    for (let i in e.tempFilePaths) {
+                        if (i >= (self.maxNum - imageList.length)) {
+                            break;
+                        }
+                        let image = new Image();
+                        image.src = e.tempFilePaths[i];
+                        image.onload = () => {
+                            let canvas = document.createElement("canvas");
+                            canvas.width = image.width;
+                            canvas.height = image.height;
+                            let ctx = canvas.getContext("2d");
+                            ctx.drawImage(image, 0, 0, image.width, image.height);
+                            let ext = image.src.substring(image.src.lastIndexOf(".") + 1).toLowerCase();
+                            let dataURL = canvas.toDataURL("image/" + ext);
+                            uploadFile({
+                                url: self.$api.upload.file,
+                                maxNum: self.maxNum,
+                                success: function({res, header}) {
+                                    self.$request({
+                                        url: self.$api.upload.file + '&name=base64',
+                                        header: header,
+                                        method: 'post',
+                                        data: {
+                                            database: dataURL
+                                        }
+                                    }).then(res => {
+                                        if (res.code === 0) {
+                                            self.imageList.push(res.data.url);
+                                            self.checkMaxNum();
+                                            self.$emit('imageEvent', {
+                                                imageList: self.imageList,
+                                                sign: self.sign
+                                            });
+                                        } else {
+                                            uni.showModal({
+                                                title: '',
+                                                content: res.msg,
+                                                showCancel: false,
+                                            });
+                                        }
+                                    })
+                                }
+                            });
+                        };
+                    }
+                },
+                complete: function(e) {
+                    // 触发事件 tabEvent
+                    self.$emit('imageEvent', {
+                        imageList: imageList,
+                        sign: self.sign
+                    })
+                }
+            });
+            // #endif
+
+        },
+        // 图片预览
+        previewImage(index) {
+            let imageList = this.imageList;
+            uni.previewImage({
+                current: imageList[index],
+                urls: imageList
+            })
+        },
+        createObjectURL(blob) {
+            return (window.URL) ? window.URL.createObjectURL(blob) : window.webkitURL.createObjectURL(blob);
+        }
+    },
+    created() {
+        this.checkMaxNum();
+    }
+}
+</script>
+<style lang="scss" scoped>
+.upload-box {
+    background-color: #fff;
+}
+
+.upload-box .title {
+    padding: 15#{rpx} 0 15#{rpx} 20#{rpx};
+}
+
+.upload-box .img {
+    width: 188#{rpx};
+    height: 188#{rpx};
+    margin: 10#{rpx};
+    display: block;
+}
+
+.upload-box .add-img {
+    width: 188#{rpx};
+    height: 188#{rpx};
+    // border: 1#{rpx} dotted $uni-weak-color-one;
+    background-color: #ECECEC;
+}
+
+.upload-box .add-img .text {
+    color: $uni-general-color-two;
+    font-size: $uni-font-size-weak-two;
+}
+
+.upload-box .add-img-icon {
+    width: 56#{rpx};
+    height: 56#{rpx};
+    margin-bottom: 10#{rpx};
+}
+
+.upload-box .img-box {
+    position: relative;
+}
+
+
+.upload-box .remove {
+    width: 40#{rpx};
+    height: 40#{rpx};
+    position: absolute;
+    right: 0;
+    top: 0;
+    background: rgba($color: #000000, $alpha: 0.5);
+    color: #fff;
+	border-radius: 0 10rpx 0 10rpx;
+    // border-radius: 50%;
+    padding-bottom: 8#{rpx};
+    font-size: 24#{rpx};
+    z-index: 968;
+}
+
+.upload-box .add-img.other-border {
+    border: 1#{rpx} solid $uni-weak-color-one
+}
+</style>

+ 1 - 1
http/baseUrl.js

xqd
@@ -7,4 +7,4 @@ export const baseUrl = 'http://o2o.cn/api/'
 //export const imageUrl = 'http://t28.9026.com/'
 //export const baseUrl = 'http://t28.9026.com/api/'
 // export const mainUrl = 'http://t7.9026.com'
-export const mainUrl = 'https://t38.9026.com'
+export const mainUrl = 'http://123.207.180.167:8700'

+ 8 - 0
http/new_file.vue

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

+ 3 - 2
http/request.js

xqd
@@ -16,10 +16,11 @@ module.exports = (vm) => {
 	uni.$u.http.interceptors.request.use((config) => { // 可使用async await 做异步操作
 	let token=uni.getStorageSync("token")
 		config.header = {
-			
+				// "User-Agent":"apifox/1.0.0 (https://www.apifox.cn)",
+				"Content-Type": "application/json",
 				// ...config.header,
 				// Authorization: `Bearer ${vm.$store.state.token}`
-				Authorization: `Bearer ${token}`
+				Authorization: token
 			}
 		return config
 	}, config => { // 可使用async await 做异步操作

+ 49 - 15
main.js

xqd
@@ -1,21 +1,55 @@
+import Vue from 'vue'
 import App from './App'
 
-// #ifndef VUE3
-import Vue from 'vue'
+import store from './store'
+
+Vue.prototype.$store = store
+import util from './common/util.js'
+Vue.prototype.$util = util;
+import common from './common/common.js'
+Vue.prototype.$common = common;
+import uView from "uview-ui";
+Vue.use(uView);
+
 Vue.config.productionTip = false
 App.mpType = 'app'
+
+Vue.prototype.$toast = function(msg, callback = false) {
+	uni.showToast({
+		icon: 'none',
+		title: msg,
+	})
+	if (callback !== false) {
+		setTimeout(() => {
+			callback()
+		}, 2000)
+	}
+}
+Vue.prototype.$load = function(msg, callback = false) {
+	uni.showLoading({
+		title:msg,
+		mask:true
+	})
+	if (callback !== false) {
+		setTimeout(() => {
+			callback()
+		}, 2000)
+	}
+}
+Vue.prototype.$back = function() {
+	uni.navigateBack({
+		delta: 1
+	})
+}
+
+
+
 const app = new Vue({
-    ...App
+	store,
+	...App
 })
-app.$mount()
-// #endif
-
-// #ifdef VUE3
-import { createSSRApp } from 'vue'
-export function createApp() {
-  const app = createSSRApp(App)
-  return {
-    app
-  }
-}
-// #endif
+
+// 引入请求封装,将app参数传递到配置中
+require('./http/request.js')(app)
+
+app.$mount()

+ 4 - 2
manifest.json

xqd
@@ -50,9 +50,11 @@
     "quickapp" : {},
     /* 小程序特有相关 */
     "mp-weixin" : {
-        "appid" : "",
+        "appid" : "wx55637849acebb7e7",
         "setting" : {
-            "urlCheck" : false
+            "urlCheck" : false,
+            "minified" : true,
+            "es6" : false
         },
         "usingComponents" : true
     },

+ 2 - 0
node_modules/@vue/devtools-api/lib/cjs/api/api.js

xqd
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });

+ 2 - 0
node_modules/@vue/devtools-api/lib/cjs/api/app.js

xqd
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });

+ 2 - 0
node_modules/@vue/devtools-api/lib/cjs/api/component.js

xqd
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });

+ 2 - 0
node_modules/@vue/devtools-api/lib/cjs/api/context.js

xqd
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });

+ 2 - 0
node_modules/@vue/devtools-api/lib/cjs/api/hooks.js

xqd
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });

+ 22 - 0
node_modules/@vue/devtools-api/lib/cjs/api/index.js

xqd
@@ -0,0 +1,22 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    var desc = Object.getOwnPropertyDescriptor(m, k);
+    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+      desc = { enumerable: true, get: function() { return m[k]; } };
+    }
+    Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./api"), exports);
+__exportStar(require("./app"), exports);
+__exportStar(require("./component"), exports);
+__exportStar(require("./context"), exports);
+__exportStar(require("./hooks"), exports);
+__exportStar(require("./util"), exports);

+ 2 - 0
node_modules/@vue/devtools-api/lib/cjs/api/util.js

xqd
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });

+ 5 - 0
node_modules/@vue/devtools-api/lib/cjs/const.js

xqd
@@ -0,0 +1,5 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.HOOK_PLUGIN_SETTINGS_SET = exports.HOOK_SETUP = void 0;
+exports.HOOK_SETUP = 'devtools-plugin:setup';
+exports.HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set';

+ 17 - 0
node_modules/@vue/devtools-api/lib/cjs/env.js

xqd
@@ -0,0 +1,17 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.isProxyAvailable = exports.getTarget = exports.getDevtoolsGlobalHook = void 0;
+function getDevtoolsGlobalHook() {
+    return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;
+}
+exports.getDevtoolsGlobalHook = getDevtoolsGlobalHook;
+function getTarget() {
+    // @ts-ignore
+    return (typeof navigator !== 'undefined' && typeof window !== 'undefined')
+        ? window
+        : typeof global !== 'undefined'
+            ? global
+            : {};
+}
+exports.getTarget = getTarget;
+exports.isProxyAvailable = typeof Proxy === 'function';

+ 44 - 0
node_modules/@vue/devtools-api/lib/cjs/index.js

xqd
@@ -0,0 +1,44 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    var desc = Object.getOwnPropertyDescriptor(m, k);
+    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+      desc = { enumerable: true, get: function() { return m[k]; } };
+    }
+    Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.setupDevtoolsPlugin = void 0;
+const env_1 = require("./env");
+const const_1 = require("./const");
+const proxy_1 = require("./proxy");
+__exportStar(require("./api"), exports);
+__exportStar(require("./plugin"), exports);
+__exportStar(require("./time"), exports);
+function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
+    const descriptor = pluginDescriptor;
+    const target = (0, env_1.getTarget)();
+    const hook = (0, env_1.getDevtoolsGlobalHook)();
+    const enableProxy = env_1.isProxyAvailable && descriptor.enableEarlyProxy;
+    if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
+        hook.emit(const_1.HOOK_SETUP, pluginDescriptor, setupFn);
+    }
+    else {
+        const proxy = enableProxy ? new proxy_1.ApiProxy(descriptor, hook) : null;
+        const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
+        list.push({
+            pluginDescriptor: descriptor,
+            setupFn,
+            proxy,
+        });
+        if (proxy)
+            setupFn(proxy.proxiedTarget);
+    }
+}
+exports.setupDevtoolsPlugin = setupDevtoolsPlugin;

+ 2 - 0
node_modules/@vue/devtools-api/lib/cjs/plugin.js

xqd
@@ -0,0 +1,2 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });

+ 111 - 0
node_modules/@vue/devtools-api/lib/cjs/proxy.js

xqd
@@ -0,0 +1,111 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ApiProxy = void 0;
+const const_1 = require("./const");
+const time_1 = require("./time");
+class ApiProxy {
+    constructor(plugin, hook) {
+        this.target = null;
+        this.targetQueue = [];
+        this.onQueue = [];
+        this.plugin = plugin;
+        this.hook = hook;
+        const defaultSettings = {};
+        if (plugin.settings) {
+            for (const id in plugin.settings) {
+                const item = plugin.settings[id];
+                defaultSettings[id] = item.defaultValue;
+            }
+        }
+        const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
+        let currentSettings = Object.assign({}, defaultSettings);
+        try {
+            const raw = localStorage.getItem(localSettingsSaveId);
+            const data = JSON.parse(raw);
+            Object.assign(currentSettings, data);
+        }
+        catch (e) {
+            // noop
+        }
+        this.fallbacks = {
+            getSettings() {
+                return currentSettings;
+            },
+            setSettings(value) {
+                try {
+                    localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
+                }
+                catch (e) {
+                    // noop
+                }
+                currentSettings = value;
+            },
+            now() {
+                return (0, time_1.now)();
+            },
+        };
+        if (hook) {
+            hook.on(const_1.HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
+                if (pluginId === this.plugin.id) {
+                    this.fallbacks.setSettings(value);
+                }
+            });
+        }
+        this.proxiedOn = new Proxy({}, {
+            get: (_target, prop) => {
+                if (this.target) {
+                    return this.target.on[prop];
+                }
+                else {
+                    return (...args) => {
+                        this.onQueue.push({
+                            method: prop,
+                            args,
+                        });
+                    };
+                }
+            },
+        });
+        this.proxiedTarget = new Proxy({}, {
+            get: (_target, prop) => {
+                if (this.target) {
+                    return this.target[prop];
+                }
+                else if (prop === 'on') {
+                    return this.proxiedOn;
+                }
+                else if (Object.keys(this.fallbacks).includes(prop)) {
+                    return (...args) => {
+                        this.targetQueue.push({
+                            method: prop,
+                            args,
+                            resolve: () => { },
+                        });
+                        return this.fallbacks[prop](...args);
+                    };
+                }
+                else {
+                    return (...args) => {
+                        return new Promise(resolve => {
+                            this.targetQueue.push({
+                                method: prop,
+                                args,
+                                resolve,
+                            });
+                        });
+                    };
+                }
+            },
+        });
+    }
+    async setRealTarget(target) {
+        this.target = target;
+        for (const item of this.onQueue) {
+            this.target.on[item.method](...item.args);
+        }
+        for (const item of this.targetQueue) {
+            item.resolve(await this.target[item.method](...item.args));
+        }
+    }
+}
+exports.ApiProxy = ApiProxy;

+ 28 - 0
node_modules/@vue/devtools-api/lib/cjs/time.js

xqd
@@ -0,0 +1,28 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.now = exports.isPerformanceSupported = void 0;
+let supported;
+let perf;
+function isPerformanceSupported() {
+    var _a;
+    if (supported !== undefined) {
+        return supported;
+    }
+    if (typeof window !== 'undefined' && window.performance) {
+        supported = true;
+        perf = window.performance;
+    }
+    else if (typeof global !== 'undefined' && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) {
+        supported = true;
+        perf = global.perf_hooks.performance;
+    }
+    else {
+        supported = false;
+    }
+    return supported;
+}
+exports.isPerformanceSupported = isPerformanceSupported;
+function now() {
+    return isPerformanceSupported() ? perf.now() : Date.now();
+}
+exports.now = now;

+ 108 - 0
node_modules/@vue/devtools-api/lib/esm/api/api.d.ts

xqd
@@ -0,0 +1,108 @@
+import { ComponentBounds, Hookable } from './hooks';
+import { Context } from './context';
+import { ComponentInstance, ComponentState, StateBase } from './component';
+import { App } from './app';
+import { ID } from './util';
+export interface DevtoolsPluginApi<TSettings> {
+    on: Hookable<Context>;
+    notifyComponentUpdate(instance?: ComponentInstance): void;
+    addTimelineLayer(options: TimelineLayerOptions): void;
+    addTimelineEvent(options: TimelineEventOptions): void;
+    addInspector(options: CustomInspectorOptions): void;
+    sendInspectorTree(inspectorId: string): void;
+    sendInspectorState(inspectorId: string): void;
+    selectInspectorNode(inspectorId: string, nodeId: string): void;
+    getComponentBounds(instance: ComponentInstance): Promise<ComponentBounds>;
+    getComponentName(instance: ComponentInstance): Promise<string>;
+    getComponentInstances(app: App): Promise<ComponentInstance[]>;
+    highlightElement(instance: ComponentInstance): void;
+    unhighlightElement(): void;
+    getSettings(pluginId?: string): TSettings;
+    now(): number;
+    /**
+     * @private Not implemented yet
+     */
+    setSettings(values: TSettings): void;
+}
+export interface AppRecord {
+    id: string;
+    name: string;
+    instanceMap: Map<string, ComponentInstance>;
+    rootInstance: ComponentInstance;
+}
+export interface TimelineLayerOptions<TData = any, TMeta = any> {
+    id: string;
+    label: string;
+    color: number;
+    skipScreenshots?: boolean;
+    groupsOnly?: boolean;
+    ignoreNoDurationGroups?: boolean;
+    screenshotOverlayRender?: (event: TimelineEvent<TData, TMeta> & ScreenshotOverlayEvent, ctx: ScreenshotOverlayRenderContext) => ScreenshotOverlayRenderResult | Promise<ScreenshotOverlayRenderResult>;
+}
+export interface ScreenshotOverlayEvent {
+    layerId: string;
+    renderMeta: any;
+}
+export interface ScreenshotOverlayRenderContext<TData = any, TMeta = any> {
+    screenshot: ScreenshotData;
+    events: (TimelineEvent<TData, TMeta> & ScreenshotOverlayEvent)[];
+    index: number;
+}
+export declare type ScreenshotOverlayRenderResult = HTMLElement | string | false;
+export interface ScreenshotData {
+    time: number;
+}
+export interface TimelineEventOptions {
+    layerId: string;
+    event: TimelineEvent;
+    all?: boolean;
+}
+export interface TimelineEvent<TData = any, TMeta = any> {
+    time: number;
+    data: TData;
+    logType?: 'default' | 'warning' | 'error';
+    meta?: TMeta;
+    groupId?: ID;
+    title?: string;
+    subtitle?: string;
+}
+export interface TimelineMarkerOptions {
+    id: string;
+    time: number;
+    color: number;
+    label: string;
+    all?: boolean;
+}
+export interface CustomInspectorOptions {
+    id: string;
+    label: string;
+    icon?: string;
+    treeFilterPlaceholder?: string;
+    stateFilterPlaceholder?: string;
+    noSelectionText?: string;
+    actions?: {
+        icon: string;
+        tooltip?: string;
+        action: () => void | Promise<void>;
+    }[];
+    nodeActions?: {
+        icon: string;
+        tooltip?: string;
+        action: (nodeId: string) => void | Promise<void>;
+    }[];
+}
+export interface CustomInspectorNode {
+    id: string;
+    label: string;
+    children?: CustomInspectorNode[];
+    tags?: InspectorNodeTag[];
+}
+export interface InspectorNodeTag {
+    label: string;
+    textColor: number;
+    backgroundColor: number;
+    tooltip?: string;
+}
+export interface CustomInspectorState {
+    [key: string]: (StateBase | Omit<ComponentState, 'type'>)[];
+}

+ 1 - 0
node_modules/@vue/devtools-api/lib/esm/api/api.js

xqd
@@ -0,0 +1 @@
+export {};

+ 1 - 0
node_modules/@vue/devtools-api/lib/esm/api/app.d.ts

xqd
@@ -0,0 +1 @@
+export declare type App = any;

+ 1 - 0
node_modules/@vue/devtools-api/lib/esm/api/app.js

xqd
@@ -0,0 +1 @@
+export {};

+ 77 - 0
node_modules/@vue/devtools-api/lib/esm/api/component.d.ts

xqd
@@ -0,0 +1,77 @@
+import { InspectorNodeTag } from './api';
+import { ID } from './util';
+export declare type ComponentInstance = any;
+export interface ComponentTreeNode {
+    uid: ID;
+    id: string;
+    name: string;
+    renderKey: string | number;
+    inactive: boolean;
+    isFragment: boolean;
+    hasChildren: boolean;
+    children: ComponentTreeNode[];
+    domOrder?: number[];
+    consoleId?: string;
+    isRouterView?: boolean;
+    macthedRouteSegment?: string;
+    tags: InspectorNodeTag[];
+    meta?: any;
+}
+export interface InspectedComponentData {
+    id: string;
+    name: string;
+    file: string;
+    state: ComponentState[];
+    functional?: boolean;
+}
+export interface StateBase {
+    key: string;
+    value: any;
+    editable?: boolean;
+    objectType?: 'ref' | 'reactive' | 'computed' | 'other';
+    raw?: string;
+}
+export interface ComponentStateBase extends StateBase {
+    type: string;
+}
+export interface ComponentPropState extends ComponentStateBase {
+    meta?: {
+        type: string;
+        required: boolean;
+        /** Vue 1 only */
+        mode?: 'default' | 'sync' | 'once';
+    };
+}
+export declare type ComponentBuiltinCustomStateTypes = 'function' | 'map' | 'set' | 'reference' | 'component' | 'component-definition' | 'router' | 'store';
+export interface ComponentCustomState extends ComponentStateBase {
+    value: CustomState;
+}
+export declare type CustomState = {
+    _custom: {
+        type: ComponentBuiltinCustomStateTypes | string;
+        objectType?: string;
+        display?: string;
+        tooltip?: string;
+        value?: any;
+        abstract?: boolean;
+        file?: string;
+        uid?: number;
+        readOnly?: boolean;
+        /** Configure immediate child fields */
+        fields?: {
+            abstract?: boolean;
+        };
+        id?: any;
+        actions?: {
+            icon: string;
+            tooltip?: string;
+            action: () => void | Promise<void>;
+        }[];
+        /** internal */
+        _reviveId?: number;
+    };
+};
+export declare type ComponentState = ComponentStateBase | ComponentPropState | ComponentCustomState;
+export interface ComponentDevtoolsOptions {
+    hide?: boolean;
+}

+ 1 - 0
node_modules/@vue/devtools-api/lib/esm/api/component.js

xqd
@@ -0,0 +1 @@
+export {};

+ 5 - 0
node_modules/@vue/devtools-api/lib/esm/api/context.d.ts

xqd
@@ -0,0 +1,5 @@
+import { AppRecord } from './api';
+export interface Context {
+    currentTab: string;
+    currentAppRecord: AppRecord;
+}

+ 1 - 0
node_modules/@vue/devtools-api/lib/esm/api/context.js

xqd
@@ -0,0 +1 @@
+export {};

+ 179 - 0
node_modules/@vue/devtools-api/lib/esm/api/hooks.d.ts

xqd
@@ -0,0 +1,179 @@
+import { ComponentTreeNode, InspectedComponentData, ComponentInstance, ComponentDevtoolsOptions } from './component';
+import { App } from './app';
+import { CustomInspectorNode, CustomInspectorState, TimelineEvent } from './api';
+export declare const enum Hooks {
+    TRANSFORM_CALL = "transformCall",
+    GET_APP_RECORD_NAME = "getAppRecordName",
+    GET_APP_ROOT_INSTANCE = "getAppRootInstance",
+    REGISTER_APPLICATION = "registerApplication",
+    WALK_COMPONENT_TREE = "walkComponentTree",
+    VISIT_COMPONENT_TREE = "visitComponentTree",
+    WALK_COMPONENT_PARENTS = "walkComponentParents",
+    INSPECT_COMPONENT = "inspectComponent",
+    GET_COMPONENT_BOUNDS = "getComponentBounds",
+    GET_COMPONENT_NAME = "getComponentName",
+    GET_COMPONENT_INSTANCES = "getComponentInstances",
+    GET_ELEMENT_COMPONENT = "getElementComponent",
+    GET_COMPONENT_ROOT_ELEMENTS = "getComponentRootElements",
+    EDIT_COMPONENT_STATE = "editComponentState",
+    GET_COMPONENT_DEVTOOLS_OPTIONS = "getAppDevtoolsOptions",
+    GET_COMPONENT_RENDER_CODE = "getComponentRenderCode",
+    INSPECT_TIMELINE_EVENT = "inspectTimelineEvent",
+    TIMELINE_CLEARED = "timelineCleared",
+    GET_INSPECTOR_TREE = "getInspectorTree",
+    GET_INSPECTOR_STATE = "getInspectorState",
+    EDIT_INSPECTOR_STATE = "editInspectorState",
+    SET_PLUGIN_SETTINGS = "setPluginSettings"
+}
+export interface ComponentBounds {
+    left: number;
+    top: number;
+    width: number;
+    height: number;
+}
+export declare type HookPayloads = {
+    [Hooks.TRANSFORM_CALL]: {
+        callName: string;
+        inArgs: any[];
+        outArgs: any[];
+    };
+    [Hooks.GET_APP_RECORD_NAME]: {
+        app: App;
+        name: string;
+    };
+    [Hooks.GET_APP_ROOT_INSTANCE]: {
+        app: App;
+        root: ComponentInstance;
+    };
+    [Hooks.REGISTER_APPLICATION]: {
+        app: App;
+    };
+    [Hooks.WALK_COMPONENT_TREE]: {
+        componentInstance: ComponentInstance;
+        componentTreeData: ComponentTreeNode[];
+        maxDepth: number;
+        filter: string;
+    };
+    [Hooks.VISIT_COMPONENT_TREE]: {
+        app: App;
+        componentInstance: ComponentInstance;
+        treeNode: ComponentTreeNode;
+        filter: string;
+    };
+    [Hooks.WALK_COMPONENT_PARENTS]: {
+        componentInstance: ComponentInstance;
+        parentInstances: ComponentInstance[];
+    };
+    [Hooks.INSPECT_COMPONENT]: {
+        app: App;
+        componentInstance: ComponentInstance;
+        instanceData: InspectedComponentData;
+    };
+    [Hooks.GET_COMPONENT_BOUNDS]: {
+        componentInstance: ComponentInstance;
+        bounds: ComponentBounds;
+    };
+    [Hooks.GET_COMPONENT_NAME]: {
+        componentInstance: ComponentInstance;
+        name: string;
+    };
+    [Hooks.GET_COMPONENT_INSTANCES]: {
+        app: App;
+        componentInstances: ComponentInstance[];
+    };
+    [Hooks.GET_ELEMENT_COMPONENT]: {
+        element: HTMLElement | any;
+        componentInstance: ComponentInstance;
+    };
+    [Hooks.GET_COMPONENT_ROOT_ELEMENTS]: {
+        componentInstance: ComponentInstance;
+        rootElements: (HTMLElement | any)[];
+    };
+    [Hooks.EDIT_COMPONENT_STATE]: {
+        app: App;
+        componentInstance: ComponentInstance;
+        path: string[];
+        type: string;
+        state: EditStatePayload;
+        set: (object: any, path?: string | (string[]), value?: any, cb?: (object: any, field: string, value: any) => void) => void;
+    };
+    [Hooks.GET_COMPONENT_DEVTOOLS_OPTIONS]: {
+        componentInstance: ComponentInstance;
+        options: ComponentDevtoolsOptions;
+    };
+    [Hooks.GET_COMPONENT_RENDER_CODE]: {
+        componentInstance: ComponentInstance;
+        code: string;
+    };
+    [Hooks.INSPECT_TIMELINE_EVENT]: {
+        app: App;
+        layerId: string;
+        event: TimelineEvent;
+        all?: boolean;
+        data: any;
+    };
+    [Hooks.TIMELINE_CLEARED]: Record<string, never>;
+    [Hooks.GET_INSPECTOR_TREE]: {
+        app: App;
+        inspectorId: string;
+        filter: string;
+        rootNodes: CustomInspectorNode[];
+    };
+    [Hooks.GET_INSPECTOR_STATE]: {
+        app: App;
+        inspectorId: string;
+        nodeId: string;
+        state: CustomInspectorState;
+    };
+    [Hooks.EDIT_INSPECTOR_STATE]: {
+        app: App;
+        inspectorId: string;
+        nodeId: string;
+        path: string[];
+        type: string;
+        state: EditStatePayload;
+        set: (object: any, path?: string | (string[]), value?: any, cb?: (object: any, field: string, value: any) => void) => void;
+    };
+    [Hooks.SET_PLUGIN_SETTINGS]: {
+        app: App;
+        pluginId: string;
+        key: string;
+        newValue: any;
+        oldValue: any;
+        settings: any;
+    };
+};
+export declare type EditStatePayload = {
+    value: any;
+    newKey?: string | null;
+    remove?: undefined | false;
+} | {
+    value?: undefined;
+    newKey?: undefined;
+    remove: true;
+};
+export declare type HookHandler<TPayload, TContext> = (payload: TPayload, ctx: TContext) => void | Promise<void>;
+export interface Hookable<TContext> {
+    transformCall(handler: HookHandler<HookPayloads[Hooks.TRANSFORM_CALL], TContext>): any;
+    getAppRecordName(handler: HookHandler<HookPayloads[Hooks.GET_APP_RECORD_NAME], TContext>): any;
+    getAppRootInstance(handler: HookHandler<HookPayloads[Hooks.GET_APP_ROOT_INSTANCE], TContext>): any;
+    registerApplication(handler: HookHandler<HookPayloads[Hooks.REGISTER_APPLICATION], TContext>): any;
+    walkComponentTree(handler: HookHandler<HookPayloads[Hooks.WALK_COMPONENT_TREE], TContext>): any;
+    visitComponentTree(handler: HookHandler<HookPayloads[Hooks.VISIT_COMPONENT_TREE], TContext>): any;
+    walkComponentParents(handler: HookHandler<HookPayloads[Hooks.WALK_COMPONENT_PARENTS], TContext>): any;
+    inspectComponent(handler: HookHandler<HookPayloads[Hooks.INSPECT_COMPONENT], TContext>): any;
+    getComponentBounds(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_BOUNDS], TContext>): any;
+    getComponentName(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_NAME], TContext>): any;
+    getComponentInstances(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_INSTANCES], TContext>): any;
+    getElementComponent(handler: HookHandler<HookPayloads[Hooks.GET_ELEMENT_COMPONENT], TContext>): any;
+    getComponentRootElements(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_ROOT_ELEMENTS], TContext>): any;
+    editComponentState(handler: HookHandler<HookPayloads[Hooks.EDIT_COMPONENT_STATE], TContext>): any;
+    getComponentDevtoolsOptions(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_DEVTOOLS_OPTIONS], TContext>): any;
+    getComponentRenderCode(handler: HookHandler<HookPayloads[Hooks.GET_COMPONENT_RENDER_CODE], TContext>): any;
+    inspectTimelineEvent(handler: HookHandler<HookPayloads[Hooks.INSPECT_TIMELINE_EVENT], TContext>): any;
+    timelineCleared(handler: HookHandler<HookPayloads[Hooks.TIMELINE_CLEARED], TContext>): any;
+    getInspectorTree(handler: HookHandler<HookPayloads[Hooks.GET_INSPECTOR_TREE], TContext>): any;
+    getInspectorState(handler: HookHandler<HookPayloads[Hooks.GET_INSPECTOR_STATE], TContext>): any;
+    editInspectorState(handler: HookHandler<HookPayloads[Hooks.EDIT_INSPECTOR_STATE], TContext>): any;
+    setPluginSettings(handler: HookHandler<HookPayloads[Hooks.SET_PLUGIN_SETTINGS], TContext>): any;
+}

+ 1 - 0
node_modules/@vue/devtools-api/lib/esm/api/hooks.js

xqd
@@ -0,0 +1 @@
+export {};

+ 6 - 0
node_modules/@vue/devtools-api/lib/esm/api/index.d.ts

xqd
@@ -0,0 +1,6 @@
+export * from './api';
+export * from './app';
+export * from './component';
+export * from './context';
+export * from './hooks';
+export * from './util';

+ 6 - 0
node_modules/@vue/devtools-api/lib/esm/api/index.js

xqd
@@ -0,0 +1,6 @@
+export * from './api';
+export * from './app';
+export * from './component';
+export * from './context';
+export * from './hooks';
+export * from './util';

+ 4 - 0
node_modules/@vue/devtools-api/lib/esm/api/util.d.ts

xqd
@@ -0,0 +1,4 @@
+export declare type ID = number | string;
+export interface WithId {
+    id: ID;
+}

+ 1 - 0
node_modules/@vue/devtools-api/lib/esm/api/util.js

xqd
@@ -0,0 +1 @@
+export {};

+ 2 - 0
node_modules/@vue/devtools-api/lib/esm/const.d.ts

xqd
@@ -0,0 +1,2 @@
+export declare const HOOK_SETUP = "devtools-plugin:setup";
+export declare const HOOK_PLUGIN_SETTINGS_SET = "plugin:settings:set";

+ 2 - 0
node_modules/@vue/devtools-api/lib/esm/const.js

xqd
@@ -0,0 +1,2 @@
+export const HOOK_SETUP = 'devtools-plugin:setup';
+export const HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set';

+ 15 - 0
node_modules/@vue/devtools-api/lib/esm/env.d.ts

xqd
@@ -0,0 +1,15 @@
+import { PluginDescriptor, SetupFunction } from '.';
+import { ApiProxy } from './proxy';
+export interface PluginQueueItem {
+    pluginDescriptor: PluginDescriptor;
+    setupFn: SetupFunction;
+    proxy?: ApiProxy;
+}
+interface GlobalTarget {
+    __VUE_DEVTOOLS_PLUGINS__?: PluginQueueItem[];
+    __VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__?: boolean;
+}
+export declare function getDevtoolsGlobalHook(): any;
+export declare function getTarget(): GlobalTarget;
+export declare const isProxyAvailable: boolean;
+export {};

+ 12 - 0
node_modules/@vue/devtools-api/lib/esm/env.js

xqd
@@ -0,0 +1,12 @@
+export function getDevtoolsGlobalHook() {
+    return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;
+}
+export function getTarget() {
+    // @ts-ignore
+    return (typeof navigator !== 'undefined' && typeof window !== 'undefined')
+        ? window
+        : typeof global !== 'undefined'
+            ? global
+            : {};
+}
+export const isProxyAvailable = typeof Proxy === 'function';

+ 18 - 0
node_modules/@vue/devtools-api/lib/esm/index.d.ts

xqd
@@ -0,0 +1,18 @@
+import { DevtoolsPluginApi } from './api';
+import { PluginDescriptor, ExtractSettingsTypes, PluginSettingsItem } from './plugin';
+export * from './api';
+export * from './plugin';
+export * from './time';
+export { PluginQueueItem } from './env';
+declare type Cast<A, B> = A extends B ? A : B;
+declare type Narrowable = string | number | bigint | boolean;
+declare type Narrow<A> = Cast<A, [] | (A extends Narrowable ? A : never) | ({
+    [K in keyof A]: Narrow<A[K]>;
+})>;
+declare type Exact<C, T> = {
+    [K in keyof C]: K extends keyof T ? T[K] : never;
+};
+export declare type SetupFunction<TSettings = any> = (api: DevtoolsPluginApi<TSettings>) => void;
+export declare function setupDevtoolsPlugin<TDescriptor extends Exact<TDescriptor, PluginDescriptor>, TSettings = ExtractSettingsTypes<TDescriptor extends {
+    settings: infer S;
+} ? S extends Record<string, PluginSettingsItem> ? S : Record<string, PluginSettingsItem> : Record<string, PluginSettingsItem>>>(pluginDescriptor: Narrow<TDescriptor>, setupFn: SetupFunction<TSettings>): void;

+ 26 - 0
node_modules/@vue/devtools-api/lib/esm/index.js

xqd
@@ -0,0 +1,26 @@
+import { getTarget, getDevtoolsGlobalHook, isProxyAvailable } from './env';
+import { HOOK_SETUP } from './const';
+import { ApiProxy } from './proxy';
+export * from './api';
+export * from './plugin';
+export * from './time';
+export function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
+    const descriptor = pluginDescriptor;
+    const target = getTarget();
+    const hook = getDevtoolsGlobalHook();
+    const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy;
+    if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
+        hook.emit(HOOK_SETUP, pluginDescriptor, setupFn);
+    }
+    else {
+        const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null;
+        const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
+        list.push({
+            pluginDescriptor: descriptor,
+            setupFn,
+            proxy,
+        });
+        if (proxy)
+            setupFn(proxy.proxiedTarget);
+    }
+}

+ 47 - 0
node_modules/@vue/devtools-api/lib/esm/plugin.d.ts

xqd
@@ -0,0 +1,47 @@
+import { App } from './api';
+export interface PluginDescriptor {
+    id: string;
+    label: string;
+    app: App;
+    packageName?: string;
+    homepage?: string;
+    componentStateTypes?: string[];
+    logo?: string;
+    disableAppScope?: boolean;
+    disablePluginScope?: boolean;
+    /**
+     * Run the plugin setup and expose the api even if the devtools is not opened yet.
+     * Useful to record timeline events early.
+     */
+    enableEarlyProxy?: boolean;
+    settings?: Record<string, PluginSettingsItem>;
+}
+export declare type PluginSettingsItem = {
+    label: string;
+    description?: string;
+} & ({
+    type: 'boolean';
+    defaultValue: boolean;
+} | {
+    type: 'choice';
+    defaultValue: string | number;
+    options: {
+        value: string | number;
+        label: string;
+    }[];
+    component?: 'select' | 'button-group';
+} | {
+    type: 'text';
+    defaultValue: string;
+});
+declare type InferSettingsType<T extends PluginSettingsItem> = [T] extends [{
+    type: 'boolean';
+}] ? boolean : [T] extends [{
+    type: 'choice';
+}] ? T['options'][number]['value'] : [T] extends [{
+    type: 'text';
+}] ? string : unknown;
+export declare type ExtractSettingsTypes<O extends Record<string, PluginSettingsItem>> = {
+    [K in keyof O]: InferSettingsType<O[K]>;
+};
+export {};

+ 1 - 0
node_modules/@vue/devtools-api/lib/esm/plugin.js

xqd
@@ -0,0 +1 @@
+export {};

+ 20 - 0
node_modules/@vue/devtools-api/lib/esm/proxy.d.ts

xqd
@@ -0,0 +1,20 @@
+import { Context, DevtoolsPluginApi, Hookable } from './api';
+import { PluginDescriptor } from './plugin';
+interface QueueItem {
+    method: string;
+    args: any[];
+    resolve?: (value?: any) => void;
+}
+export declare class ApiProxy<TTarget extends DevtoolsPluginApi<any> = DevtoolsPluginApi<any>> {
+    target: TTarget | null;
+    targetQueue: QueueItem[];
+    proxiedTarget: TTarget;
+    onQueue: QueueItem[];
+    proxiedOn: Hookable<Context>;
+    plugin: PluginDescriptor;
+    hook: any;
+    fallbacks: Record<string, any>;
+    constructor(plugin: PluginDescriptor, hook: any);
+    setRealTarget(target: TTarget): Promise<void>;
+}
+export {};

+ 107 - 0
node_modules/@vue/devtools-api/lib/esm/proxy.js

xqd
@@ -0,0 +1,107 @@
+import { HOOK_PLUGIN_SETTINGS_SET } from './const';
+import { now } from './time';
+export class ApiProxy {
+    constructor(plugin, hook) {
+        this.target = null;
+        this.targetQueue = [];
+        this.onQueue = [];
+        this.plugin = plugin;
+        this.hook = hook;
+        const defaultSettings = {};
+        if (plugin.settings) {
+            for (const id in plugin.settings) {
+                const item = plugin.settings[id];
+                defaultSettings[id] = item.defaultValue;
+            }
+        }
+        const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
+        let currentSettings = Object.assign({}, defaultSettings);
+        try {
+            const raw = localStorage.getItem(localSettingsSaveId);
+            const data = JSON.parse(raw);
+            Object.assign(currentSettings, data);
+        }
+        catch (e) {
+            // noop
+        }
+        this.fallbacks = {
+            getSettings() {
+                return currentSettings;
+            },
+            setSettings(value) {
+                try {
+                    localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
+                }
+                catch (e) {
+                    // noop
+                }
+                currentSettings = value;
+            },
+            now() {
+                return now();
+            },
+        };
+        if (hook) {
+            hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
+                if (pluginId === this.plugin.id) {
+                    this.fallbacks.setSettings(value);
+                }
+            });
+        }
+        this.proxiedOn = new Proxy({}, {
+            get: (_target, prop) => {
+                if (this.target) {
+                    return this.target.on[prop];
+                }
+                else {
+                    return (...args) => {
+                        this.onQueue.push({
+                            method: prop,
+                            args,
+                        });
+                    };
+                }
+            },
+        });
+        this.proxiedTarget = new Proxy({}, {
+            get: (_target, prop) => {
+                if (this.target) {
+                    return this.target[prop];
+                }
+                else if (prop === 'on') {
+                    return this.proxiedOn;
+                }
+                else if (Object.keys(this.fallbacks).includes(prop)) {
+                    return (...args) => {
+                        this.targetQueue.push({
+                            method: prop,
+                            args,
+                            resolve: () => { },
+                        });
+                        return this.fallbacks[prop](...args);
+                    };
+                }
+                else {
+                    return (...args) => {
+                        return new Promise(resolve => {
+                            this.targetQueue.push({
+                                method: prop,
+                                args,
+                                resolve,
+                            });
+                        });
+                    };
+                }
+            },
+        });
+    }
+    async setRealTarget(target) {
+        this.target = target;
+        for (const item of this.onQueue) {
+            this.target.on[item.method](...item.args);
+        }
+        for (const item of this.targetQueue) {
+            item.resolve(await this.target[item.method](...item.args));
+        }
+    }
+}

+ 2 - 0
node_modules/@vue/devtools-api/lib/esm/time.d.ts

xqd
@@ -0,0 +1,2 @@
+export declare function isPerformanceSupported(): boolean;
+export declare function now(): number;

+ 23 - 0
node_modules/@vue/devtools-api/lib/esm/time.js

xqd
@@ -0,0 +1,23 @@
+let supported;
+let perf;
+export function isPerformanceSupported() {
+    var _a;
+    if (supported !== undefined) {
+        return supported;
+    }
+    if (typeof window !== 'undefined' && window.performance) {
+        supported = true;
+        perf = window.performance;
+    }
+    else if (typeof global !== 'undefined' && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) {
+        supported = true;
+        perf = global.perf_hooks.performance;
+    }
+    else {
+        supported = false;
+    }
+    return supported;
+}
+export function now() {
+    return isPerformanceSupported() ? perf.now() : Date.now();
+}

+ 67 - 0
node_modules/@vue/devtools-api/package.json

xqd
@@ -0,0 +1,67 @@
+{
+  "_from": "@vue/devtools-api@^6.0.0-beta.11",
+  "_id": "@vue/devtools-api@6.1.4",
+  "_inBundle": false,
+  "_integrity": "sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ==",
+  "_location": "/@vue/devtools-api",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "@vue/devtools-api@^6.0.0-beta.11",
+    "name": "@vue/devtools-api",
+    "escapedName": "@vue%2fdevtools-api",
+    "scope": "@vue",
+    "rawSpec": "^6.0.0-beta.11",
+    "saveSpec": null,
+    "fetchSpec": "^6.0.0-beta.11"
+  },
+  "_requiredBy": [
+    "/vuex"
+  ],
+  "_resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.1.4.tgz",
+  "_shasum": "b4aec2f4b4599e11ba774a50c67fa378c9824e53",
+  "_spec": "@vue/devtools-api@^6.0.0-beta.11",
+  "_where": "C:\\shop-program\\alhj\\alhj-wx\\node_modules\\vuex",
+  "author": {
+    "name": "Guillaume Chau"
+  },
+  "browser": "lib/esm/index.js",
+  "bugs": {
+    "url": "https://github.com/vuejs/vue-devtools/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "Interact with the Vue devtools from the page",
+  "devDependencies": {
+    "@types/node": "^13.9.1",
+    "@types/webpack-env": "^1.15.1",
+    "typescript": "^4.5.2"
+  },
+  "files": [
+    "lib/esm",
+    "lib/cjs"
+  ],
+  "homepage": "https://github.com/vuejs/vue-devtools#readme",
+  "license": "MIT",
+  "main": "lib/cjs/index.js",
+  "module": "lib/esm/index.js",
+  "name": "@vue/devtools-api",
+  "publishConfig": {
+    "access": "public"
+  },
+  "repository": {
+    "url": "git+https://github.com/vuejs/vue-devtools.git",
+    "type": "git",
+    "directory": "packages/api"
+  },
+  "scripts": {
+    "build": "rimraf lib && yarn build:esm && yarn build:cjs",
+    "build:cjs": "tsc --module commonjs --outDir lib/cjs",
+    "build:esm": "tsc --module es2015 --outDir lib/esm -d",
+    "build:watch": "yarn tsc --module es2015 --outDir lib/esm -d -w --sourceMap"
+  },
+  "sideEffects": false,
+  "types": "lib/esm/index.d.ts",
+  "version": "6.1.4"
+}

+ 21 - 0
node_modules/uview-ui/LICENSE

xqd
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 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
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+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.

+ 104 - 0
node_modules/uview-ui/README.md

xqd
@@ -0,0 +1,104 @@
+<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">多平台快速开发的UI框架</h3>
+
+## 说明
+
+uView UI,是[uni-app](https://uniapp.dcloud.io/)生态优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
+
+## 特性
+
+- 兼容安卓,iOS,微信小程序,H5,QQ小程序,百度小程序,支付宝小程序,头条小程序
+- 60+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用
+- 众多贴心的JS利器,让您飞镖在手,召之即来,百步穿杨
+- 众多的常用页面和布局,让您专注逻辑,事半功倍
+- 详尽的文档支持,现代化的演示效果
+- 按需引入,精简打包体积
+
+
+## 安装
+
+```bash
+# npm方式安装,插件市场导入无需执行此命令
+npm i uview-ui
+```
+
+## 快速上手
+
+1. `main.js`引入uView库
+```js
+// main.js
+import uView from 'uview-ui';
+Vue.use(uView);
+```
+
+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";
+```
+
+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": [
+		// ......
+	]
+}
+```
+
+请通过[快速上手](https://www.uviewui.com/components/quickstart.html)了解更详细的内容 
+
+## 使用方法
+配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
+
+```html
+<template>
+	<u-button text="按钮"></u-button>
+</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应用到您的产品中。

+ 326 - 0
node_modules/uview-ui/changelog.md

xqd
@@ -0,0 +1,326 @@
+## 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重磅发布,利剑出鞘,一统江湖
+
+1. 优化:form组件在用户设置rules的时候提示用户model必传
+2. 优化遗留的通过正则判断rpx单位的问题
+3. 修复微信小程序环境中tabbar组件开启safeAreaInsetBottom属性后,placeholder高度填充不正确
+4. 修复swiper在current指定非0时缩放有误
+5. 修复u-icon添加stop属性的时候报错
+6. 修复upload组件在accept=all的时候没有作用
+7. 修复在text组件mode为phone时call属性无效的问题
+8. 处理u-form clearValidate方法
+9. 其他修复
+## 2.0.20(2022-01-14)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复calendar默认会选择一个日期,如果直接点确定的话,无法取到值的问题
+2. 修复Slider缺少disabled props 还有注释
+3. 修复u-notice-bar点击事件无法拿到index索引值的问题
+4. 修复u-collapse-item在vue文件下,app端自定义插槽不生效的问题
+5. 优化头像为空时显示默认头像 
+6. 修复图片地址赋值后判断加载状态为完成问题
+7. 修复日历滚动到默认日期月份区域
+8. search组件暴露点击左边icon事件
+9. 修复u-form clearValidate方法不生效
+10. upload h5端增加返回文件参数(文件的name参数)
+11. 处理upload选择文件后url为blob类型无法预览的问题
+12. u-code-input 修复输入框没有往左移出一半屏幕
+13. 修复Upload上传 disabled为true时,控制台报hoverClass类型错误
+14. 临时处理ios app下grid点击坍塌问题
+15. 其他修复
+## 2.0.19(2021-12-29)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 优化微信小程序包体积可在微信中预览,请升级HbuilderX3.3.4,同时在“运行->运行到小程序模拟器”中勾选“运行时是否压缩代码”
+2. 优化微信小程序setData性能,处理某些方法如$u.route()无法在模板中使用的问题
+3. navbar添加autoBack参数
+4. 允许avatar组件的事件冒泡
+5. 修复cell组件报错问题
+6. 其他修复
+## 2.0.18(2021-12-28)
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复app端编译报错问题
+2. 重新处理微信小程序端setData过大的性能问题
+3. 修复边框问题
+4. 修复最大最小月份不大于0则没有数据出现的问题
+5. 修复SwipeAction微信小程序端无法上下滑动问题
+6. 修复input的placeholder在小程序端默认显示为true问题
+7. 修复divider组件click事件无效问题
+8. 修复u-code-input maxlength 属性值为 String 类型时显示异常
+9. 修复当 grid只有 1到2时 在小程序端algin设置无效的问题
+10. 处理form-item的label为top时,取消错误提示的左边距
+11. 其他修复
+## 2.0.17(2021-12-26)
+## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 解决HBuilderX3.3.3.20211225版本导致的样式问题
+2. calendar日历添加monthNum参数
+3. navbar添加center slot
+## 2.0.16(2021-12-25)
+## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 解决微信小程序setData性能问题
+2. 修复count-down组件change事件不触发问题
+## 2.0.15(2021-12-21)
+## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复Cell单元格titleWidth无效
+2. 修复cheakbox组件ischecked不更新
+3. 修复keyboard是否显示"."按键默认值问题
+4. 修复number-keyboard是否显示键盘的"."符号问题
+5. 修复Input输入框 readonly无效
+6. 修复u-avatar 导致打包app、H5时候报错问题
+7. 修复Upload上传deletable无效
+8. 修复upload当设置maxSize时无效的问题
+9. 修复tabs lineWidth传入带单位的字符串的时候偏移量计算错误问题
+10. 修复rate组件在有padding的view内,显示的星星位置和可触摸区域不匹配,无法正常选中星星
+## 2.0.13(2021-12-14)
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复配置默认单位为rpx可能会导致自定义导航栏高度异常的问题
+## 2.0.12(2021-12-14)
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复tabs组件在vue环境下划线消失的问题
+2. 修复upload组件在安卓小程序无法选择视频的问题
+3. 添加uni.$u.config.unit配置,用于配置参数默认单位,详见:[默认单位配置](https://www.uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
+4. 修复textarea组件在没绑定v-model时,字符统计不生效问题
+5. 修复nvue下控制是否出现滚动条失效问题
+## 2.0.11(2021-12-13)
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. text组件align参数无效的问题
+2. subsection组件添加keyName参数
+3. upload组件无法判断[Object file]类型的问题
+4. 处理notify层级过低问题
+5. codeInput组件添加disabledDot参数
+6. 处理actionSheet组件round参数无效的问题
+7. calendar组件添加round参数用于控制圆角值
+8. 处理swipeAction组件在vue环境下默认被打开的问题
+9. button组件的throttleTime节流参数无效的问题
+10. 解决u-notify手动关闭方法close()无效的问题
+11. input组件readonly不生效问题
+12. tag组件type参数为info不生效问题
+## 2.0.10(2021-12-08)
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复button sendMessagePath属性不生效
+2. 修复DatetimePicker选择器title无效
+3. 修复u-toast设置loading=true不生效
+4. 修复u-text金额模式传0报错
+5. 修复u-toast组件的icon属性配置不生效
+6. button的icon在特殊场景下的颜色优化
+7. IndexList优化,增加#
+## 2.0.9(2021-12-01)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 优化swiper的height支持100%值(仅vue有效),修复嵌入视频时click事件无法触发的问题
+2. 优化tabs组件对list值为空的判断,或者动态变化list时重新计算相关尺寸的问题
+3. 优化datetime-picker组件逻辑,让其后续打开的默认值为上一次的选中值,需要通过v-model绑定值才有效
+4. 修复upload内嵌在其他组件中,选择图片可能不会换行的问题
+## 2.0.8(2021-12-01)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复toast的position参数无效问题
+2. 处理input在ios nvue上无法获得焦点的问题
+3. avatar-group组件添加extraValue参数,让剩余展示数量可手动控制
+4. tabs组件添加keyName参数用于配置从对象中读取的键名
+5. 处理text组件名字脱敏默认配置无效的问题
+6. 处理picker组件item文本太长换行问题
+## 2.0.7(2021-11-30)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 修复radio和checkbox动态改变v-model无效的问题。
+2. 优化form规则validator在微信小程序用法
+3. 修复backtop组件mode参数在微信小程序无效的问题
+4. 处理Album的previewFullImage属性无效的问题
+5. 处理u-datetime-picker组件mode='time'在选择改变时间时,控制台报错的问题
+## 2.0.6(2021-11-27)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. 处理tag组件在vue下边框无效的问题。
+2. 处理popup组件圆角参数可能无效的问题。
+3. 处理tabs组件lineColor参数可能无效的问题。
+4. propgress组件在值很小时,显示异常的问题。
+## 2.0.5(2021-11-25)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. calendar在vue下显示异常问题。 
+2. form组件labelPosition和errorType参数无效的问题
+3. input组件inputAlign无效的问题
+4. 其他一些修复
+## 2.0.4(2021-11-23)
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+0. input组件缺失@confirm事件,以及subfix和prefix无效问题
+1. component.scss文件样式在vue下干扰全局布局问题
+2. 修复subsection在vue环境下表现异常的问题
+3. tag组件的bgColor等参数无效的问题
+4. upload组件不换行的问题
+5. 其他的一些修复处理
+## 2.0.3(2021-11-16)
+## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. uView2.0已实现全面兼容nvue
+2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
+3. 目前uView2.0为公测阶段,相关细节可能会有变动
+4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
+5. 处理modal的confirm回调事件拼写错误问题
+6. 处理input组件@input事件参数错误问题
+7. 其他一些修复
+## 2.0.2(2021-11-16)
+## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. uView2.0已实现全面兼容nvue
+2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
+3. 目前uView2.0为公测阶段,相关细节可能会有变动
+4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
+5. 修复input组件formatter参数缺失问题
+6. 优化loading-icon组件的scss写法问题,防止不兼容新版本scss
+## 2.0.0(2020-11-15)
+## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+# uView2.0重磅发布,利剑出鞘,一统江湖
+
+1. uView2.0已实现全面兼容nvue
+2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
+3. 目前uView2.0为公测阶段,相关细节可能会有变动
+4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
+5. 修复input组件formatter参数缺失问题
+
+

+ 78 - 0
node_modules/uview-ui/components/u--form/u--form.vue

xqd
@@ -0,0 +1,78 @@
+<template>
+	<uvForm
+		ref="uForm"
+		:model="model"
+		:rules="rules"
+		:errorType="errorType"
+		:borderBottom="borderBottom"
+		:labelPosition="labelPosition"
+		:labelWidth="labelWidth"
+		:labelAlign="labelAlign"
+		:labelStyle="labelStyle"
+		:customStyle="customStyle"
+	>
+		<slot />
+	</uvForm>
+</template>
+
+<script>
+	/**
+	 * 此组件存在的理由是,在nvue下,u-form被uni-app官方占用了,u-form在nvue中相当于form组件
+	 * 所以在nvue下,取名为u--form,内部其实还是u-form.vue,只不过做一层中转
+	 */
+	import uvForm from '../u-form/u-form.vue';
+	import props from '../u-form/props.js'
+	export default {
+		// #ifdef MP-WEIXIN
+		name: 'u-form',
+		// #endif
+		// #ifndef MP-WEIXIN
+		name: 'u--form',
+		// #endif
+		mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+		components: {
+			uvForm
+		},
+		created() {
+			this.children = []
+		},
+		methods: {
+			// 手动设置校验的规则,如果规则中有函数的话,微信小程序中会过滤掉,所以只能手动调用设置规则
+			setRules(rules) {
+				this.$refs.uForm.setRules(rules)
+			},
+			validate() {
+				/**
+				 * 在微信小程序中,通过this.$parent拿到的父组件是u--form,而不是其内嵌的u-form
+				 * 导致在u-form组件中,拿不到对应的children数组,从而校验无效,所以这里每次调用u-form组件中的
+				 * 对应方法的时候,在小程序中都先将u--form的children赋值给u-form中的children
+				 */
+				// #ifdef MP-WEIXIN
+				this.setMpData()
+				// #endif
+				return this.$refs.uForm.validate()
+			},
+			validateField(value, callback) {
+				// #ifdef MP-WEIXIN
+				this.setMpData()
+				// #endif
+				return this.$refs.uForm.validateField(value, callback)
+			},
+			resetFields() {
+				// #ifdef MP-WEIXIN
+				this.setMpData()
+				// #endif
+				return this.$refs.uForm.resetFields()
+			},
+			clearValidate(props) {
+				// #ifdef MP-WEIXIN
+				this.setMpData()
+				// #endif
+				return this.$refs.uForm.clearValidate(props)
+			},
+			setMpData() {
+				this.$refs.uForm.children = this.children
+			}
+		},
+	}
+</script>

+ 47 - 0
node_modules/uview-ui/components/u--image/u--image.vue

xqd
@@ -0,0 +1,47 @@
+<template>
+	<uvImage 
+		:src="src"
+		:mode="mode"
+		:width="width"
+		:height="height"
+		:shape="shape"
+		:radius="radius"
+		:lazyLoad="lazyLoad"
+		:showMenuByLongpress="showMenuByLongpress"
+		:loadingIcon="loadingIcon"
+		:errorIcon="errorIcon"
+		:showLoading="showLoading"
+		:showError="showError"
+		:fade="fade"
+		:webp="webp"
+		:duration="duration"
+		:bgColor="bgColor"
+		:customStyle="customStyle"
+		@click="$emit('click')"
+		@error="$emit('error')"
+		@load="$emit('load')"
+	>
+		<template v-slot:loading>
+			<slot name="loading"></slot>
+		</template>
+		<template v-slot:error>
+			<slot name="error"></slot>
+		</template>
+	</uvImage>
+</template>
+
+<script>
+	/**
+	 * 此组件存在的理由是,在nvue下,u-image被uni-app官方占用了,u-image在nvue中相当于image组件
+	 * 所以在nvue下,取名为u--image,内部其实还是u-iamge.vue,只不过做一层中转
+	 */
+	import uvImage from '../u-image/u-image.vue';
+	import props from '../u-image/props.js';
+	export default {
+		name: 'u--image',
+		mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+		components: {
+			uvImage
+		},
+	}
+</script>

+ 72 - 0
node_modules/uview-ui/components/u--input/u--input.vue

xqd
@@ -0,0 +1,72 @@
+<template>
+	<uvInput 
+		:value="value"
+		:type="type"
+		:fixed="fixed"
+		:disabled="disabled"
+		:disabledColor="disabledColor"
+		:clearable="clearable"
+		:password="password"
+		:maxlength="maxlength"
+		:placeholder="placeholder"
+		:placeholderClass="placeholderClass"
+		:placeholderStyle="placeholderStyle"
+		:showWordLimit="showWordLimit"
+		:confirmType="confirmType"
+		:confirmHold="confirmHold"
+		:holdKeyboard="holdKeyboard"
+		:focus="focus"
+		:autoBlur="autoBlur"
+		:disableDefaultPadding="disableDefaultPadding"
+		:cursor="cursor"
+		:cursorSpacing="cursorSpacing"
+		:selectionStart="selectionStart"
+		:selectionEnd="selectionEnd"
+		:adjustPosition="adjustPosition"
+		:inputAlign="inputAlign"
+		:fontSize="fontSize"
+		:color="color"
+		:prefixIcon="prefixIcon"
+		:suffixIcon="suffixIcon"
+		:suffixIconStyle="suffixIconStyle"
+		:prefixIconStyle="prefixIconStyle"
+		:border="border"
+		:readonly="readonly"
+		:shape="shape"
+		:customStyle="customStyle"
+		:formatter="formatter"
+		@focus="$emit('focus')"
+		@blur="$emit('blur')"
+		@keyboardheightchange="$emit('keyboardheightchange')"
+		@change="e => $emit('change', e)"
+		@input="e => $emit('input', e)"
+		@confirm="e => $emit('confirm', e)"
+		@clear="$emit('clear')"
+		@click="$emit('click')"
+	>
+		<!-- #ifdef MP -->
+		<slot name="prefix"></slot>
+		<slot name="suffix"></slot>
+		<!-- #endif -->
+		<!-- #ifndef MP -->
+		<slot name="prefix" slot="prefix"></slot>
+		<slot name="suffix" slot="suffix"></slot>
+		<!-- #endif -->
+	</uvInput>
+</template>
+
+<script>
+	/**
+	 * 此组件存在的理由是,在nvue下,u-input被uni-app官方占用了,u-input在nvue中相当于input组件
+	 * 所以在nvue下,取名为u--input,内部其实还是u-input.vue,只不过做一层中转
+	 */
+	import uvInput from '../u-input/u-input.vue';
+	import props from '../u-input/props.js'
+	export default {
+		name: 'u--input',
+		mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+		components: {
+			uvInput
+		},
+	}
+</script>

+ 44 - 0
node_modules/uview-ui/components/u--text/u--text.vue

xqd
@@ -0,0 +1,44 @@
+<template>
+    <uvText
+        :type="type"
+        :show="show"
+        :text="text"
+        :prefixIcon="prefixIcon"
+        :suffixIcon="suffixIcon"
+        :mode="mode"
+        :href="href"
+        :format="format"
+        :call="call"
+        :openType="openType"
+        :bold="bold"
+        :block="block"
+        :lines="lines"
+        :color="color"
+		:decoration="decoration"
+        :size="size"
+        :iconStyle="iconStyle"
+        :margin="margin"
+        :lineHeight="lineHeight"
+        :align="align"
+        :wordWrap="wordWrap"
+        :customStyle="customStyle"
+        @click="$emit('click')"
+    ></uvText>
+</template>
+
+<script>
+/**
+ * 此组件存在的理由是,在nvue下,u-text被uni-app官方占用了,u-text在nvue中相当于input组件
+ * 所以在nvue下,取名为u--input,内部其实还是u-text.vue,只不过做一层中转
+ * 不使用v-bind="$attrs",而是分开独立写传参,是因为微信小程序不支持此写法
+ */
+import uvText from "../u-text/u-text.vue";
+import props from "../u-text/props.js";
+export default {
+    name: "u--text",
+    mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+    components: {
+        uvText,
+    },
+};
+</script>

+ 47 - 0
node_modules/uview-ui/components/u--textarea/u--textarea.vue

xqd
@@ -0,0 +1,47 @@
+<template>
+	<uvTextarea
+		:value="value"
+		:placeholder="placeholder"
+		:height="height"
+		:confirmType="confirmType"
+		:disabled="disabled"
+		:count="count"
+		:focus="focus"
+		:autoHeight="autoHeight"
+		:fixed="fixed"
+		:cursorSpacing="cursorSpacing"
+		:cursor="cursor"
+		:showConfirmBar="showConfirmBar"
+		:selectionStart="selectionStart"
+		:selectionEnd="selectionEnd"
+		:adjustPosition="adjustPosition"
+		:disableDefaultPadding="disableDefaultPadding"
+		:holdKeyboard="holdKeyboard"
+		:maxlength="maxlength"
+		:border="border"
+		:customStyle="customStyle"
+		:formatter="formatter"
+		@focus="e => $emit('focus')"
+		@blur="e => $emit('blur')"
+		@linechange="e => $emit('linechange', e)"
+		@confirm="e => $emit('confirm')"
+		@input="e => $emit('input', e)"
+		@keyboardheightchange="e => $emit('keyboardheightchange')"
+	></uvTextarea>
+</template>
+
+<script>
+	/**
+	 * 此组件存在的理由是,在nvue下,u--textarea被uni-app官方占用了,u-textarea在nvue中相当于textarea组件
+	 * 所以在nvue下,取名为u--textarea,内部其实还是u-textarea.vue,只不过做一层中转
+	 */
+	import uvTextarea from '../u-textarea/u-textarea.vue';
+	import props from '../u-textarea/props.js'
+	export default {
+		name: 'u--textarea',
+		mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+		components: {
+			uvTextarea
+		},
+	}
+</script>

+ 54 - 0
node_modules/uview-ui/components/u-action-sheet/props.js

xqd
@@ -0,0 +1,54 @@
+export default {
+    props: {
+        // 操作菜单是否展示 (默认false)
+        show: {
+            type: Boolean,
+            default: uni.$u.props.actionSheet.show
+        },
+        // 标题
+        title: {
+            type: String,
+            default: uni.$u.props.actionSheet.title
+        },
+        // 选项上方的描述信息
+        description: {
+            type: String,
+            default: uni.$u.props.actionSheet.description
+        },
+        // 数据
+        actions: {
+            type: Array,
+            default: uni.$u.props.actionSheet.actions
+        },
+        // 取消按钮的文字,不为空时显示按钮
+        cancelText: {
+            type: String,
+            default: uni.$u.props.actionSheet.cancelText
+        },
+        // 点击某个菜单项时是否关闭弹窗
+        closeOnClickAction: {
+            type: Boolean,
+            default: uni.$u.props.actionSheet.closeOnClickAction
+        },
+        // 处理底部安全区(默认true)
+        safeAreaInsetBottom: {
+            type: Boolean,
+            default: uni.$u.props.actionSheet.safeAreaInsetBottom
+        },
+        // 小程序的打开方式
+        openType: {
+            type: String,
+            default: uni.$u.props.actionSheet.openType
+        },
+        // 点击遮罩是否允许关闭 (默认true)
+        closeOnClickOverlay: {
+            type: Boolean,
+            default: uni.$u.props.actionSheet.closeOnClickOverlay
+        },
+        // 圆角值
+        round: {
+            type: [Boolean, String, Number],
+            default: uni.$u.props.actionSheet.round
+        }
+    }
+}

+ 278 - 0
node_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue

xqd
@@ -0,0 +1,278 @@
+
+<template>
+	<u-popup
+	    :show="show"
+	    mode="bottom"
+	    @close="closeHandler"
+	    :safeAreaInsetBottom="safeAreaInsetBottom"
+	    :round="round"
+	>
+		<view class="u-action-sheet">
+			<view
+			    class="u-action-sheet__header"
+			    v-if="title"
+			>
+				<text class="u-action-sheet__header__title u-line-1">{{title}}</text>
+				<view
+				    class="u-action-sheet__header__icon-wrap"
+				    @tap.stop="cancel"
+				>
+					<u-icon
+					    name="close"
+					    size="17"
+					    color="#c8c9cc"
+					    bold
+					></u-icon>
+				</view>
+			</view>
+			<text
+			    class="u-action-sheet__description"
+				:style="[{
+					marginTop: `${title && description ? 0 : '18px'}`
+				}]"
+			    v-if="description"
+			>{{description}}</text>
+			<slot>
+				<u-line v-if="description"></u-line>
+				<view class="u-action-sheet__item-wrap">
+					<template v-for="(item, index) in actions">
+						<!-- #ifdef MP -->
+						<button
+						    :key="index"
+						    class="u-reset-button"
+						    :openType="item.openType"
+						    @getuserinfo="onGetUserInfo"
+						    @contact="onContact"
+						    @getphonenumber="onGetPhoneNumber"
+						    @error="onError"
+						    @launchapp="onLaunchApp"
+						    @opensetting="onOpenSetting"
+						    :lang="lang"
+						    :session-from="sessionFrom"
+						    :send-message-title="sendMessageTitle"
+						    :send-message-path="sendMessagePath"
+						    :send-message-img="sendMessageImg"
+						    :show-message-card="showMessageCard"
+						    :app-parameter="appParameter"
+						    @tap="selectHandler(index)"
+						    :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
+						>
+							<!-- #endif -->
+							<view
+							    class="u-action-sheet__item-wrap__item"
+							    @tap.stop="selectHandler(index)"
+							    :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
+							    :hover-stay-time="150"
+							>
+								<template v-if="!item.loading">
+									<text
+									    class="u-action-sheet__item-wrap__item__name"
+									    :style="[itemStyle(index)]"
+									>{{ item.name }}</text>
+									<text
+									    v-if="item.subname"
+									    class="u-action-sheet__item-wrap__item__subname"
+									>{{ item.subname }}</text>
+								</template>
+								<u-loading-icon
+								    v-else
+								    custom-class="van-action-sheet__loading"
+								    size="18"
+								    mode="circle"
+								/>
+							</view>
+							<!-- #ifdef MP -->
+						</button>
+						<!-- #endif -->
+						<u-line v-if="index !== actions.length - 1"></u-line>
+					</template>
+				</view>
+			</slot>
+			<u-gap
+			    bgColor="#eaeaec"
+			    height="6"
+			    v-if="cancelText"
+			></u-gap>
+			<view hover-class="u-action-sheet--hover">
+				<text
+				    @touchmove.stop.prevent
+				    :hover-stay-time="150"
+				    v-if="cancelText"
+				    class="u-action-sheet__cancel-text"
+				    @tap="cancel"
+				>{{cancelText}}</text>
+			</view>
+		</view>
+	</u-popup>
+</template>
+
+<script>
+	import openType from '../../libs/mixin/openType'
+	import button from '../../libs/mixin/button'
+	import props from './props.js';
+	/**
+	 * ActionSheet 操作菜单
+	 * @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
+	 * @tutorial https://www.uviewui.com/components/actionSheet.html
+	 * 
+	 * @property {Boolean}			show				操作菜单是否展示 (默认 false )
+	 * @property {String}			title				操作菜单标题
+	 * @property {String}			description			选项上方的描述信息
+	 * @property {Array<Object>}	actions				按钮的文字数组,见官方文档示例
+	 * @property {String}			cancelText			取消按钮的提示文字,不为空时显示按钮
+	 * @property {Boolean}			closeOnClickAction	点击某个菜单项时是否关闭弹窗 (默认 true )
+	 * @property {Boolean}			safeAreaInsetBottom	处理底部安全区 (默认 true )
+	 * @property {String}			openType			小程序的打开方式 (contact | launchApp | getUserInfo | openSetting |getPhoneNumber |error )
+	 * @property {Boolean}			closeOnClickOverlay	点击遮罩是否允许关闭  (默认 true )
+	 * @property {Number|String}	round				圆角值,默认无圆角  (默认 0 )
+	 * @property {String}			lang				指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文
+	 * @property {String}			sessionFrom			会话来源,openType="contact"时有效
+	 * @property {String}			sendMessageTitle	会话内消息卡片标题,openType="contact"时有效
+	 * @property {String}			sendMessagePath		会话内消息卡片点击跳转小程序路径,openType="contact"时有效
+	 * @property {String}			sendMessageImg		会话内消息卡片图片,openType="contact"时有效
+	 * @property {Boolean}			showMessageCard		是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效 (默认 false )
+	 * @property {String}			appParameter		打开 APP 时,向 APP 传递的参数,openType=launchApp 时有效
+	 * 
+	 * @event {Function} select			点击ActionSheet列表项时触发 
+	 * @event {Function} close			点击取消按钮时触发
+	 * @event {Function} getuserinfo	用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与 wx.getUserInfo 返回的一致,openType="getUserInfo"时有效
+	 * @event {Function} contact		客服消息回调,openType="contact"时有效
+	 * @event {Function} getphonenumber	获取用户手机号回调,openType="getPhoneNumber"时有效
+	 * @event {Function} error			当使用开放能力时,发生错误的回调,openType="error"时有效
+	 * @event {Function} launchapp		打开 APP 成功的回调,openType="launchApp"时有效
+	 * @event {Function} opensetting	在打开授权设置页后回调,openType="openSetting"时有效
+	 * @example <u-action-sheet :actions="list" :title="title" :show="show"></u-action-sheet>
+	 */
+	export default {
+		name: "u-action-sheet",
+		// 一些props参数和methods方法,通过mixin混入,因为其他文件也会用到
+		mixins: [openType, button, uni.$u.mixin, props],
+		data() {
+			return {
+
+			}
+		},
+		computed: {
+			// 操作项目的样式
+			itemStyle() {
+				return (index) => {
+					let style = {};
+					if (this.actions[index].color) style.color = this.actions[index].color
+					if (this.actions[index].fontSize) style.fontSize = uni.$u.addUnit(this.actions[index].fontSize)
+					// 选项被禁用的样式
+					if (this.actions[index].disabled) style.color = '#c0c4cc'
+					return style;
+				}
+			},
+		},
+		methods: {
+			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) {
+					this.$emit('select', item)
+					if (this.closeOnClickAction) {
+						this.$emit('close')
+					}
+				}
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+	$u-action-sheet-reset-button-width:100% !default;
+	$u-action-sheet-title-font-size: 16px !default;
+	$u-action-sheet-title-padding: 12px 30px !default;
+	$u-action-sheet-title-color: $u-main-color !default;
+	$u-action-sheet-header-icon-wrap-right:15px !default;
+	$u-action-sheet-header-icon-wrap-top:15px !default;
+	$u-action-sheet-description-font-size:13px !default;
+	$u-action-sheet-description-color:14px !default;
+	$u-action-sheet-description-margin: 18px 15px !default;
+	$u-action-sheet-item-wrap-item-padding:15px !default;
+	$u-action-sheet-item-wrap-name-font-size:16px !default;
+	$u-action-sheet-item-wrap-subname-font-size:13px !default;
+	$u-action-sheet-item-wrap-subname-color: #c0c4cc !default;
+	$u-action-sheet-item-wrap-subname-margin-top:10px !default;
+	$u-action-sheet-cancel-text-font-size:16px !default;
+	$u-action-sheet-cancel-text-color:$u-content-color !default;
+	$u-action-sheet-cancel-text-font-size:15px !default;
+	$u-action-sheet-cancel-text-hover-background-color:rgb(242, 243, 245) !default;
+
+	.u-reset-button {
+		width: $u-action-sheet-reset-button-width;
+	}
+
+	.u-action-sheet {
+		text-align: center;
+		&__header {
+			position: relative;
+			padding: $u-action-sheet-title-padding;
+			&__title {
+				font-size: $u-action-sheet-title-font-size;
+				color: $u-action-sheet-title-color;
+				font-weight: bold;
+				text-align: center;
+			}
+
+			&__icon-wrap {
+				position: absolute;
+				right: $u-action-sheet-header-icon-wrap-right;
+				top: $u-action-sheet-header-icon-wrap-top;
+			}
+		}
+
+		&__description {
+			font-size: $u-action-sheet-description-font-size;
+			color: $u-tips-color;
+			margin: $u-action-sheet-description-margin;
+			text-align: center;
+		}
+
+		&__item-wrap {
+
+			&__item {
+				padding: $u-action-sheet-item-wrap-item-padding;
+				@include flex;
+				align-items: center;
+				justify-content: center;
+				flex-direction: column;
+
+				&__name {
+					font-size: $u-action-sheet-item-wrap-name-font-size;
+					color: $u-main-color;
+					text-align: center;
+				}
+
+				&__subname {
+					font-size: $u-action-sheet-item-wrap-subname-font-size;
+					color: $u-action-sheet-item-wrap-subname-color;
+					margin-top: $u-action-sheet-item-wrap-subname-margin-top;
+					text-align: center;
+				}
+			}
+		}
+
+		&__cancel-text {
+			font-size: $u-action-sheet-cancel-text-font-size;
+			color: $u-action-sheet-cancel-text-color;
+			text-align: center;
+			padding: $u-action-sheet-cancel-text-font-size;
+		}
+
+		&--hover {
+			background-color: $u-action-sheet-cancel-text-hover-background-color;
+		}
+	}
+</style>

+ 59 - 0
node_modules/uview-ui/components/u-album/props.js

xqd
@@ -0,0 +1,59 @@
+export default {
+    props: {
+        // 图片地址,Array<String>|Array<Object>形式
+        urls: {
+            type: Array,
+            default: uni.$u.props.album.urls
+        },
+        // 指定从数组的对象元素中读取哪个属性作为图片地址
+        keyName: {
+            type: String,
+            default: uni.$u.props.album.keyName
+        },
+        // 单图时,图片长边的长度
+        singleSize: {
+            type: [String, Number],
+            default: uni.$u.props.album.singleSize
+        },
+        // 多图时,图片边长
+        multipleSize: {
+            type: [String, Number],
+            default: uni.$u.props.album.multipleSize
+        },
+        // 多图时,图片水平和垂直之间的间隔
+        space: {
+            type: [String, Number],
+            default: uni.$u.props.album.space
+        },
+        // 单图时,图片缩放裁剪的模式
+        singleMode: {
+            type: String,
+            default: uni.$u.props.album.singleMode
+        },
+        // 多图时,图片缩放裁剪的模式
+        multipleMode: {
+            type: String,
+            default: uni.$u.props.album.multipleMode
+        },
+        // 最多展示的图片数量,超出时最后一个位置将会显示剩余图片数量
+        maxCount: {
+            type: [String, Number],
+            default: uni.$u.props.album.maxCount
+        },
+        // 是否可以预览图片
+        previewFullImage: {
+            type: Boolean,
+            default: uni.$u.props.album.previewFullImage
+        },
+        // 每行展示图片数量,如设置,singleSize和multipleSize将会无效
+        rowCount: {
+            type: [String, Number],
+            default: uni.$u.props.album.rowCount
+        },
+        // 超出maxCount时是否显示查看更多的提示
+        showMore: {
+            type: Boolean,
+            default: uni.$u.props.album.showMore
+        }
+    }
+}

+ 259 - 0
node_modules/uview-ui/components/u-album/u-album.vue

xqd
@@ -0,0 +1,259 @@
+<template>
+    <view class="u-album">
+        <view
+            class="u-album__row"
+            ref="u-album__row"
+            v-for="(arr, index) in showUrls"
+            :forComputedUse="albumWidth"
+            :key="index"
+        >
+            <view
+                class="u-album__row__wrapper"
+                v-for="(item, index1) in arr"
+                :key="index1"
+                :style="[imageStyle(index + 1, index1 + 1)]"
+                @tap="previewFullImage ? onPreviewTap(getSrc(item)) : ''"
+            >
+                <image
+                    :src="getSrc(item)"
+                    :mode="
+                        urls.length === 1
+                            ? imageHeight > 0
+                                ? singleMode
+                                : 'widthFix'
+                            : multipleMode
+                    "
+                    :style="[
+                        {
+                            width: imageWidth,
+                            height: imageHeight
+                        }
+                    ]"
+                ></image>
+                <view
+                    v-if="
+                        showMore &&
+                        urls.length > rowCount * showUrls.length &&
+                        index === showUrls.length - 1 &&
+                        index1 === showUrls[showUrls.length - 1].length - 1
+                    "
+                    class="u-album__row__wrapper__text"
+                >
+                    <u--text
+                        :text="`+${urls.length - maxCount}`"
+                        color="#fff"
+                        :size="multipleSize * 0.3"
+                        align="center"
+                        customStyle="justify-content: center"
+                    ></u--text>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+import props from './props.js'
+// #ifdef APP-NVUE
+// 由于weex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度
+const dom = uni.requireNativePlugin('dom')
+// #endif
+
+/**
+ * Album 相册
+ * @description 本组件提供一个类似相册的功能,让开发者开发起来更加得心应手。减少重复的模板代码
+ * @tutorial https://www.uviewui.com/components/album.html
+ *
+ * @property {Array}           urls             图片地址列表 Array<String>|Array<Object>形式
+ * @property {String}          keyName          指定从数组的对象元素中读取哪个属性作为图片地址
+ * @property {String | Number} singleSize       单图时,图片长边的长度  (默认 180 )
+ * @property {String | Number} multipleSize     多图时,图片边长 (默认 70 )
+ * @property {String | Number} space            多图时,图片水平和垂直之间的间隔 (默认 6 )
+ * @property {String}          singleMode       单图时,图片缩放裁剪的模式 (默认 'scaleToFill' )
+ * @property {String}          multipleMode     多图时,图片缩放裁剪的模式 (默认 'aspectFill' )
+ * @property {String | Number} maxCount         取消按钮的提示文字 (默认 9 )
+ * @property {Boolean}         previewFullImage 是否可以预览图片 (默认 true )
+ * @property {String | Number} rowCount         每行展示图片数量,如设置,singleSize和multipleSize将会无效	(默认 3 )
+ * @property {Boolean}         showMore         超出maxCount时是否显示查看更多的提示 (默认 true )
+ *
+ * @event    {Function}        albumWidth       某些特殊的情况下,需要让文字与相册的宽度相等,这里事件的形式对外发送  (回调参数 width )
+ * @example <u-album :urls="urls2" @albumWidth="width => albumWidth = width" multipleSize="68" ></u-album>
+ */
+export default {
+    name: 'u-album',
+    mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+    data() {
+        return {
+            // 单图的宽度
+            singleWidth: 0,
+            // 单图的高度
+            singleHeight: 0,
+            // 单图时,如果无法获取图片的尺寸信息,让图片宽度默认为容器的一定百分比
+            singlePercent: 0.6
+        }
+    },
+    watch: {
+        urls: {
+            immediate: true,
+            handler(newVal) {
+                if (newVal.length === 1) {
+                    this.getImageRect()
+                }
+            }
+        }
+    },
+    computed: {
+        imageStyle() {
+            return (index1, index2) => {
+                const { space, rowCount, multipleSize, urls } = this,
+                    { addUnit, addStyle } = uni.$u,
+                    rowLen = this.showUrls.length,
+                    allLen = this.urls.length
+                const style = {
+                    marginRight: addUnit(space),
+                    marginBottom: addUnit(space)
+                }
+                // 如果为最后一行,则每个图片都无需下边框
+                if (index1 === rowLen) style.marginBottom = 0
+                // 每行的最右边一张和总长度的最后一张无需右边框
+                if (
+                    index2 === rowCount ||
+                    (index1 === rowLen &&
+                        index2 === this.showUrls[index1 - 1].length)
+                )
+                    style.marginRight = 0
+                return style
+            }
+        },
+        // 将数组划分为二维数组
+        showUrls() {
+            const arr = []
+            this.urls.map((item, index) => {
+                // 限制最大展示数量
+                if (index + 1 <= this.maxCount) {
+                    // 计算该元素为第几个素组内
+                    const itemIndex = Math.floor(index / this.rowCount)
+                    // 判断对应的索引是否存在
+                    if (!arr[itemIndex]) {
+                        arr[itemIndex] = []
+                    }
+                    arr[itemIndex].push(item)
+                }
+            })
+            return arr
+        },
+        imageWidth() {
+            return uni.$u.addUnit(
+                this.urls.length === 1 ? this.singleWidth : this.multipleSize
+            )
+        },
+        imageHeight() {
+            return uni.$u.addUnit(
+                this.urls.length === 1 ? this.singleHeight : this.multipleSize
+            )
+        },
+        // 此变量无实际用途,仅仅是为了利用computed特性,让其在urls长度等变化时,重新计算图片的宽度
+        // 因为用户在某些特殊的情况下,需要让文字与相册的宽度相等,所以这里事件的形式对外发送
+        albumWidth() {
+            let width = 0
+            if (this.urls.length === 1) {
+                width = this.singleWidth
+            } else {
+                width =
+                    this.showUrls[0].length * this.multipleSize +
+                    this.space * (this.showUrls[0].length - 1)
+            }
+            this.$emit('albumWidth', width)
+            return width
+        }
+    },
+    methods: {
+        // 预览图片
+        onPreviewTap(url) {
+            const urls = this.urls.map((item) => {
+                return this.getSrc(item)
+            })
+            uni.previewImage({
+                current: url,
+                urls
+            })
+        },
+        // 获取图片的路径
+        getSrc(item) {
+            return uni.$u.test.object(item)
+                ? (this.keyName && item[this.keyName]) || item.src
+                : item
+        },
+        // 单图时,获取图片的尺寸
+        // 在小程序中,需要将网络图片的的域名添加到小程序的download域名才可能获取尺寸
+        // 在没有添加的情况下,让单图宽度默认为盒子的一定宽度(singlePercent)
+        getImageRect() {
+            const src = this.getSrc(this.urls[0])
+            uni.getImageInfo({
+                src,
+                success: (res) => {
+                    // 判断图片横向还是竖向展示方式
+                    const isHorizotal = res.width >= res.height
+                    this.singleWidth = isHorizotal
+                        ? this.singleSize
+                        : (res.width / res.height) * this.singleSize
+                    this.singleHeight = !isHorizotal
+                        ? this.singleSize
+                        : (res.height / res.width) * this.singleWidth
+                },
+                fail: () => {
+                    this.getComponentWidth()
+                }
+            })
+        },
+        // 获取组件的宽度
+        async getComponentWidth() {
+            // 延时一定时间,以获取dom尺寸
+            await uni.$u.sleep(30)
+            // #ifndef APP-NVUE
+            this.$uGetRect('.u-album__row').then((size) => {
+                this.singleWidth = size.width * this.singlePercent
+            })
+            // #endif
+
+            // #ifdef APP-NVUE
+            // 这里ref="u-album__row"所在的标签为通过for循环出来,导致this.$refs['u-album__row']是一个数组
+            const ref = this.$refs['u-album__row'][0]
+            ref &&
+                dom.getComponentRect(ref, (res) => {
+                    this.singleWidth = res.size.width * this.singlePercent
+                })
+            // #endif
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../libs/css/components.scss';
+
+.u-album {
+    @include flex(column);
+
+    &__row {
+        @include flex(row);
+        flex-wrap: wrap;
+
+        &__wrapper {
+            position: relative;
+
+            &__text {
+                position: absolute;
+                top: 0;
+                left: 0;
+                right: 0;
+                bottom: 0;
+                background-color: rgba(0, 0, 0, 0.3);
+                @include flex(row);
+                justify-content: center;
+                align-items: center;
+            }
+        }
+    }
+}
+</style>

+ 44 - 0
node_modules/uview-ui/components/u-alert/props.js

xqd
@@ -0,0 +1,44 @@
+export default {
+    props: {
+        // 显示文字
+        title: {
+            type: String,
+            default: uni.$u.props.alert.title
+        },
+        // 主题,success/warning/info/error
+        type: {
+            type: String,
+            default: uni.$u.props.alert.type
+        },
+        // 辅助性文字
+        description: {
+            type: String,
+            default: uni.$u.props.alert.description
+        },
+        // 是否可关闭
+        closable: {
+            type: Boolean,
+            default: uni.$u.props.alert.closable
+        },
+        // 是否显示图标
+        showIcon: {
+            type: Boolean,
+            default: uni.$u.props.alert.showIcon
+        },
+        // 浅或深色调,light-浅色,dark-深色
+        effect: {
+            type: String,
+            default: uni.$u.props.alert.effect
+        },
+        // 文字是否居中
+        center: {
+            type: Boolean,
+            default: uni.$u.props.alert.center
+        },
+        // 字体大小
+        fontSize: {
+            type: [String, Number],
+            default: uni.$u.props.alert.fontSize
+        }
+    }
+}

+ 243 - 0
node_modules/uview-ui/components/u-alert/u-alert.vue

xqd
@@ -0,0 +1,243 @@
+<template>
+	<u-transition
+	    mode="fade"
+	    :show="show"
+	>
+		<view
+		    class="u-alert"
+		    :class="[`u-alert--${type}--${effect}`]"
+		    @tap.stop="clickHandler"
+		    :style="[$u.addStyle(customStyle)]"
+		>
+			<view
+			    class="u-alert__icon"
+			    v-if="showIcon"
+			>
+				<u-icon
+				    :name="iconName"
+				    size="18"
+				    :color="iconColor"
+				></u-icon>
+			</view>
+			<view
+			    class="u-alert__content"
+			    :style="[{
+					paddingRight: closable ? '20px' : 0
+				}]"
+			>
+				<text
+				    class="u-alert__content__title"
+				    v-if="title"
+					:style="[{
+						fontSize: $u.addUnit(fontSize),
+						textAlign: center ? 'center' : 'left'
+					}]"
+				    :class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
+				>{{ title }}</text>
+				<text
+				    class="u-alert__content__desc"
+					v-if="description"
+					:style="[{
+						fontSize: $u.addUnit(fontSize),
+						textAlign: center ? 'center' : 'left'
+					}]"
+				    :class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
+				>{{ description }}</text>
+			</view>
+			<view
+			    class="u-alert__close"
+			    v-if="closable"
+			    @tap.stop="closeHandler"
+			>
+				<u-icon
+				    name="close"
+				    :color="iconColor"
+				    size="15"
+				></u-icon>
+			</view>
+		</view>
+	</u-transition>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * Alert  警告提示
+	 * @description 警告提示,展现需要关注的信息。
+	 * @tutorial https://www.uviewui.com/components/alertTips.html
+	 * 
+	 * @property {String}			title       显示的文字 
+	 * @property {String}			type        使用预设的颜色  (默认 'warning' )
+	 * @property {String}			description 辅助性文字,颜色比title浅一点,字号也小一点,可选  
+	 * @property {Boolean}			closable    关闭按钮(默认为叉号icon图标)  (默认 false )
+	 * @property {Boolean}			showIcon    是否显示左边的辅助图标   ( 默认 false )
+	 * @property {String}			effect      多图时,图片缩放裁剪的模式  (默认 'light' )
+	 * @property {Boolean}			center		文字是否居中  (默认 false )
+	 * @property {String | Number}	fontSize    字体大小  (默认 14 )
+	 * @property {Object}			customStyle	定义需要用到的外部样式
+	 * @event    {Function}        click       点击组件时触发
+	 * @example  <u-alert :title="title"  type = "warning" :closable="closable" :description = "description"></u-alert>
+	 */
+	export default {
+		name: 'u-alert',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		data() {
+			return {
+				show: true
+			}
+		},
+		computed: {
+			iconColor() {
+				return this.effect === 'light' ? this.type : '#fff'
+			},
+			// 不同主题对应不同的图标
+			iconName() {
+				switch (this.type) {
+					case 'success':
+						return 'checkmark-circle-fill';
+						break;
+					case 'error':
+						return 'close-circle-fill';
+						break;
+					case 'warning':
+						return 'error-circle-fill';
+						break;
+					case 'info':
+						return 'info-circle-fill';
+						break;
+					case 'primary':
+						return 'more-circle-fill';
+						break;
+					default: 
+						return 'error-circle-fill';
+				}
+			}
+		},
+		methods: {
+			// 点击内容
+			clickHandler() {
+				this.$emit('click')
+			},
+			// 点击关闭按钮
+			closeHandler() {
+				this.show = false
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+
+	.u-alert {
+		position: relative;
+		background-color: $u-primary;
+		padding: 8px 10px;
+		@include flex(row);
+		align-items: center;
+		border-top-left-radius: 4px;
+		border-top-right-radius: 4px;
+		border-bottom-left-radius: 4px;
+		border-bottom-right-radius: 4px;
+
+		&--primary--dark {
+			background-color: $u-primary;
+		}
+
+		&--primary--light {
+			background-color: #ecf5ff;
+		}
+
+		&--error--dark {
+			background-color: $u-error;
+		}
+
+		&--error--light {
+			background-color: #FEF0F0;
+		}
+
+		&--success--dark {
+			background-color: $u-success;
+		}
+
+		&--success--light {
+			background-color: #f5fff0;
+		}
+
+		&--warning--dark {
+			background-color: $u-warning;
+		}
+
+		&--warning--light {
+			background-color: #FDF6EC;
+		}
+
+		&--info--dark {
+			background-color: $u-info;
+		}
+
+		&--info--light {
+			background-color: #f4f4f5;
+		}
+
+		&__icon {
+			margin-right: 5px;
+		}
+
+		&__content {
+			@include flex(column);
+			flex: 1;
+
+			&__title {
+				color: $u-main-color;
+				font-size: 14px;
+				font-weight: bold;
+				color: #fff;
+				margin-bottom: 2px;
+			}
+
+			&__desc {
+				color: $u-main-color;
+				font-size: 14px;
+				flex-wrap: wrap;
+				color: #fff;
+			}
+		}
+
+		&__title--dark,
+		&__desc--dark {
+			color: #FFFFFF;
+		}
+
+		&__text--primary--light,
+		&__text--primary--light {
+			color: $u-primary;
+		}
+
+		&__text--success--light,
+		&__text--success--light {
+			color: $u-success;
+		}
+
+		&__text--warning--light,
+		&__text--warning--light {
+			color: $u-warning;
+		}
+
+		&__text--error--light,
+		&__text--error--light {
+			color: $u-error;
+		}
+
+		&__text--info--light,
+		&__text--info--light {
+			color: $u-info;
+		}
+
+		&__close {
+			position: absolute;
+			top: 11px;
+			right: 10px;
+		}
+	}
+</style>

+ 52 - 0
node_modules/uview-ui/components/u-avatar-group/props.js

xqd
@@ -0,0 +1,52 @@
+export default {
+    props: {
+        // 头像图片组
+        urls: {
+            type: Array,
+            default: uni.$u.props.avatarGroup.urls
+        },
+        // 最多展示的头像数量
+        maxCount: {
+            type: [String, Number],
+            default: uni.$u.props.avatarGroup.maxCount
+        },
+        // 头像形状
+        shape: {
+            type: String,
+            default: uni.$u.props.avatarGroup.shape
+        },
+        // 图片裁剪模式
+        mode: {
+            type: String,
+            default: uni.$u.props.avatarGroup.mode
+        },
+        // 超出maxCount时是否显示查看更多的提示
+        showMore: {
+            type: Boolean,
+            default: uni.$u.props.avatarGroup.showMore
+        },
+        // 头像大小
+        size: {
+            type: [String, Number],
+            default: uni.$u.props.avatarGroup.size
+        },
+        // 指定从数组的对象元素中读取哪个属性作为图片地址
+        keyName: {
+            type: String,
+            default: uni.$u.props.avatarGroup.keyName
+        },
+		// 头像之间的遮挡比例
+        gap: {
+            type: [String, Number],
+            validator(value) {
+                return value >= 0 && value <= 1
+            },
+            default: uni.$u.props.avatarGroup.gap
+        },
+		// 需额外显示的值
+		extraValue: {
+			type: [Number, String],
+			default: uni.$u.props.avatarGroup.extraValue
+		}
+    }
+}

+ 103 - 0
node_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue

xqd
@@ -0,0 +1,103 @@
+<template>
+	<view class="u-avatar-group">
+		<view
+		    class="u-avatar-group__item"
+		    v-for="(item, index) in showUrl"
+		    :key="index"
+		    :style="{
+				marginLeft: index === 0 ? 0 : $u.addUnit(-size * gap)
+			}"
+		>
+			<u-avatar
+			    :size="size"
+			    :shape="shape"
+			    :mode="mode"
+			    :src="$u.test.object(item) ? keyName && item[keyName] || item.url : item"
+			></u-avatar>
+			<view
+			    class="u-avatar-group__item__show-more"
+			    v-if="showMore && index === showUrl.length - 1 && (urls.length > maxCount || extraValue > 0)"
+				@tap="clickHandler"
+			>
+				<u--text
+				    color="#ffffff"
+				    :size="size * 0.4"
+				    :text="`+${extraValue || urls.length - showUrl.length}`"
+					align="center"
+					customStyle="justify-content: center"
+				></u--text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * AvatarGroup  头像组
+	 * @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
+	 * @tutorial https://www.uviewui.com/components/avatar.html
+	 * 
+	 * @property {Array}           urls     头像图片组 (默认 [] )
+	 * @property {String | Number} maxCount 最多展示的头像数量 ( 默认 5 )
+	 * @property {String}          shape    头像形状( 'circle' (默认) | 'square' )
+	 * @property {String}          mode     图片裁剪模式(默认 'scaleToFill' )
+	 * @property {Boolean}         showMore 超出maxCount时是否显示查看更多的提示 (默认 true )
+	 * @property {String | Number} size      头像大小 (默认 40 )
+	 * @property {String}          keyName  指定从数组的对象元素中读取哪个属性作为图片地址 
+	 * @property {String | Number} gap      头像之间的遮挡比例(0.4代表遮挡40%)  (默认 0.5 )
+	 * @property {String | Number} extraValue  需额外显示的值
+	 * @event    {Function}        showMore 头像组更多点击
+	 * @example  <u-avatar-group:urls="urls" size="35" gap="0.4" ></u-avatar-group:urls=>
+	 */
+	export default {
+		name: 'u-avatar-group',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		data() {
+			return {
+
+			}
+		},
+		computed: {
+			showUrl() {
+				return this.urls.slice(0, this.maxCount)
+			}
+		},
+		methods: {
+			clickHandler() {
+				this.$emit('showMore')
+			}
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+
+	.u-avatar-group {
+		@include flex;
+
+		&__item {
+			margin-left: -10px;
+			position: relative;
+
+			&--no-indent {
+				// 如果你想质疑作者不会使用:first-child,说明你太年轻,因为nvue不支持
+				margin-left: 0;
+			}
+
+			&__show-more {
+				position: absolute;
+				top: 0;
+				bottom: 0;
+				left: 0;
+				right: 0;
+				background-color: rgba(0, 0, 0, 0.3);
+				@include flex;
+				align-items: center;
+				justify-content: center;
+				border-radius: 100px;
+			}
+		}
+	}
+</style>

+ 78 - 0
node_modules/uview-ui/components/u-avatar/props.js

xqd
@@ -0,0 +1,78 @@
+export default {
+    props: {
+        // 头像图片路径(不能为相对路径)
+        src: {
+            type: String,
+            default: uni.$u.props.avatar.src
+        },
+        // 头像形状,circle-圆形,square-方形
+        shape: {
+            type: String,
+            default: uni.$u.props.avatar.shape
+        },
+        // 头像尺寸
+        size: {
+            type: [String, Number],
+            default: uni.$u.props.avatar.size
+        },
+        // 裁剪模式
+        mode: {
+            type: String,
+            default: uni.$u.props.avatar.mode
+        },
+        // 显示的文字
+        text: {
+            type: String,
+            default: uni.$u.props.avatar.text
+        },
+        // 背景色
+        bgColor: {
+            type: String,
+            default: uni.$u.props.avatar.bgColor
+        },
+        // 文字颜色
+        color: {
+            type: String,
+            default: uni.$u.props.avatar.color
+        },
+        // 文字大小
+        fontSize: {
+            type: [String, Number],
+            default: uni.$u.props.avatar.fontSize
+        },
+        // 显示的图标
+        icon: {
+            type: String,
+            default: uni.$u.props.avatar.icon
+        },
+        // 显示小程序头像,只对百度,微信,QQ小程序有效
+        mpAvatar: {
+            type: Boolean,
+            default: uni.$u.props.avatar.mpAvatar
+        },
+        // 是否使用随机背景色
+        randomBgColor: {
+            type: Boolean,
+            default: uni.$u.props.avatar.randomBgColor
+        },
+        // 加载失败的默认头像(组件有内置默认图片)
+        defaultUrl: {
+            type: String,
+            default: uni.$u.props.avatar.defaultUrl
+        },
+        // 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
+        colorIndex: {
+            type: [String, Number],
+            // 校验参数规则,索引在0-19之间
+            validator(n) {
+                return uni.$u.test.range(n, [0, 19]) || n === ''
+            },
+            default: uni.$u.props.avatar.colorIndex
+        },
+        // 组件标识符
+        name: {
+            type: String,
+            default: uni.$u.props.avatar.name
+        }
+    }
+}

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 58 - 0
node_modules/uview-ui/components/u-avatar/u-avatar.vue


+ 54 - 0
node_modules/uview-ui/components/u-back-top/props.js

xqd
@@ -0,0 +1,54 @@
+export default {
+    props: {
+        // 返回顶部的形状,circle-圆形,square-方形
+        mode: {
+            type: String,
+            default: uni.$u.props.backtop.mode
+        },
+        // 自定义图标
+        icon: {
+            type: String,
+            default: uni.$u.props.backtop.icon
+        },
+        // 提示文字
+        text: {
+            type: String,
+            default: uni.$u.props.backtop.text
+        },
+        // 返回顶部滚动时间
+        duration: {
+            type: [String, Number],
+            default: uni.$u.props.backtop.duration
+        },
+        // 滚动距离
+        scrollTop: {
+            type: [String, Number],
+            default: uni.$u.props.backtop.scrollTop
+        },
+        // 距离顶部多少距离显示,单位px
+        top: {
+            type: [String, Number],
+            default: uni.$u.props.backtop.top
+        },
+        // 返回顶部按钮到底部的距离,单位px
+        bottom: {
+            type: [String, Number],
+            default: uni.$u.props.backtop.bottom
+        },
+        // 返回顶部按钮到右边的距离,单位px
+        right: {
+            type: [String, Number],
+            default: uni.$u.props.backtop.right
+        },
+        // 层级
+        zIndex: {
+            type: [String, Number],
+            default: uni.$u.props.backtop.zIndex
+        },
+        // 图标的样式,对象形式
+        iconStyle: {
+            type: Object,
+            default: uni.$u.props.backtop.iconStyle
+        }
+    }
+}

+ 129 - 0
node_modules/uview-ui/components/u-back-top/u-back-top.vue

xqd
@@ -0,0 +1,129 @@
+<template>
+	<u-transition
+	    mode="fade"
+	    :customStyle="backTopStyle"
+	    :show="show"
+	>
+		<view
+		    class="u-back-top"
+			:style="[contentStyle]"
+		    v-if="!$slots.default && !$slots.$default"
+			@click="backToTop"
+		>
+			<u-icon
+			    :name="icon"
+			    :custom-style="iconStyle"
+			></u-icon>
+			<text
+			    v-if="text"
+			    class="u-back-top__text"
+			>{{text}}</text>
+		</view>
+		<slot v-else />
+	</u-transition>
+</template>
+
+<script>
+	import props from './props.js';
+	// #ifdef APP-NVUE
+	const dom = weex.requireModule('dom')
+	// #endif
+	/**
+	 * backTop 返回顶部
+	 * @description 本组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。
+	 * @tutorial https://uviewui.com/components/backTop.html
+	 * 
+	 * @property {String}			mode  		返回顶部的形状,circle-圆形,square-方形 (默认 'circle' )
+	 * @property {String} 			icon 		自定义图标 (默认 'arrow-upward' ) 见官方文档示例
+	 * @property {String} 			text 		提示文字 
+	 * @property {String | Number}  duration	返回顶部滚动时间 (默认 100)
+	 * @property {String | Number}  scrollTop	滚动距离 (默认 0 )
+	 * @property {String | Number}  top  		距离顶部多少距离显示,单位px (默认 400 )
+	 * @property {String | Number}  bottom  	返回顶部按钮到底部的距离,单位px (默认 100 )
+	 * @property {String | Number}  right  		返回顶部按钮到右边的距离,单位px (默认 20 )
+	 * @property {String | Number}  zIndex 		层级   (默认 9 )
+	 * @property {Object<Object>}  	iconStyle 	图标的样式,对象形式   (默认 {color: '#909399',fontSize: '19px'})
+	 * @property {Object}			customStyle	定义需要用到的外部样式
+	 * 
+	 * @example <u-back-top :scrollTop="scrollTop"></u-back-top>
+	 */
+	export default {
+		name: 'u-back-top',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+		computed: {
+			backTopStyle() {
+				// 动画组件样式
+				const style = {
+					bottom: uni.$u.addUnit(this.bottom),
+					right: uni.$u.addUnit(this.right),
+					width: '40px',
+					height: '40px',
+					position: 'fixed',
+					zIndex: 10,
+				}
+				return style
+			},
+			show() {
+				return uni.$u.getPx(this.scrollTop) > uni.$u.getPx(this.top)
+			},
+			contentStyle() {
+				const style = {}
+				let radius = 0
+				// 是否圆形
+				if(this.mode === 'circle') {
+					radius = '100px'
+				} else {
+					radius = '4px'
+				}
+				// 为了兼容安卓nvue,只能这么分开写
+				style.borderTopLeftRadius = radius
+				style.borderTopRightRadius = radius
+				style.borderBottomLeftRadius = radius
+				style.borderBottomRightRadius = radius
+				return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+			}
+		},
+		methods: {
+			backToTop() {
+				// #ifdef APP-NVUE
+				if (!this.$parent.$refs['u-back-top']) {
+					uni.$u.error(`nvue页面需要给页面最外层元素设置"ref='u-back-top'`)
+				}
+				dom.scrollToElement(this.$parent.$refs['u-back-top'], {
+					offset: 0
+				})
+				// #endif
+				
+				// #ifndef APP-NVUE
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: this.duration
+				});
+				// #endif
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import '../../libs/css/components.scss';
+     $u-back-top-flex:1 !default;
+     $u-back-top-height:100% !default;
+     $u-back-top-background-color:#E1E1E1 !default;
+     $u-back-top-tips-font-size:12px !default;
+	.u-back-top {
+		@include flex;
+		flex-direction: column;
+		align-items: center;
+		flex:$u-back-top-flex;
+		height: $u-back-top-height;
+		justify-content: center;
+		background-color: $u-back-top-background-color;
+
+		&__tips {
+			font-size:$u-back-top-tips-font-size;
+			transform: scale(0.8);
+		}
+	}
+</style>

+ 72 - 0
node_modules/uview-ui/components/u-badge/props.js

xqd
@@ -0,0 +1,72 @@
+export default {
+    props: {
+        // 是否显示圆点
+        isDot: {
+            type: Boolean,
+            default: uni.$u.props.badge.isDot
+        },
+        // 显示的内容
+        value: {
+            type: [Number, String],
+            default: uni.$u.props.badge.value
+        },
+        // 是否显示
+        show: {
+            type: Boolean,
+            default: uni.$u.props.badge.show
+        },
+        // 最大值,超过最大值会显示 '{max}+'
+        max: {
+            type: [Number, String],
+            default: uni.$u.props.badge.max
+        },
+        // 主题类型,error|warning|success|primary
+        type: {
+            type: String,
+            default: uni.$u.props.badge.type
+        },
+        // 当数值为 0 时,是否展示 Badge
+        showZero: {
+            type: Boolean,
+            default: uni.$u.props.badge.showZero
+        },
+        // 背景颜色,优先级比type高,如设置,type参数会失效
+        bgColor: {
+            type: [String, null],
+            default: uni.$u.props.badge.bgColor
+        },
+        // 字体颜色
+        color: {
+            type: [String, null],
+            default: uni.$u.props.badge.color
+        },
+        // 徽标形状,circle-四角均为圆角,horn-左下角为直角
+        shape: {
+            type: String,
+            default: uni.$u.props.badge.shape
+        },
+        // 设置数字的显示方式,overflow|ellipsis|limit
+        // overflow会根据max字段判断,超出显示`${max}+`
+        // ellipsis会根据max判断,超出显示`${max}...`
+        // limit会依据1000作为判断条件,超出1000,显示`${value/1000}K`,比如2.2k、3.34w,最多保留2位小数
+        numberType: {
+            type: String,
+            default: uni.$u.props.badge.numberType
+        },
+        // 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效
+        offset: {
+            type: Array,
+            default: uni.$u.props.badge.offset
+        },
+        // 是否反转背景和字体颜色
+        inverted: {
+            type: Boolean,
+            default: uni.$u.props.badge.inverted
+        },
+        // 是否绝对定位
+        absolute: {
+            type: Boolean,
+            default: uni.$u.props.badge.absolute
+        }
+    }
+}

+ 171 - 0
node_modules/uview-ui/components/u-badge/u-badge.vue

xqd
@@ -0,0 +1,171 @@
+<template>
+	<text
+		v-if="show && ((Number(value) === 0 ? showZero : true) || isDot)"
+		:class="[isDot ? 'u-badge--dot' : 'u-badge--not-dot', inverted && 'u-badge--inverted', shape === 'horn' && 'u-badge--horn', `u-badge--${type}${inverted ? '--inverted' : ''}`]"
+		:style="[$u.addStyle(customStyle), badgeStyle]"
+		class="u-badge"
+	>{{ isDot ? '' :showValue }}</text>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * badge 徽标数
+	 * @description 该组件一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。
+	 * @tutorial https://uviewui.com/components/badge.html
+	 * 
+	 * @property {Boolean} 			isDot 		是否显示圆点 (默认 false )
+	 * @property {String | Number} 	value 		显示的内容
+	 * @property {Boolean} 			show 		是否显示 (默认 true )
+	 * @property {String | Number} 	max 		最大值,超过最大值会显示 '{max}+'  (默认999)
+	 * @property {String} 			type 		主题类型,error|warning|success|primary (默认 'error' )
+	 * @property {Boolean} 			showZero	当数值为 0 时,是否展示 Badge (默认 false )
+	 * @property {String} 			bgColor 	背景颜色,优先级比type高,如设置,type参数会失效
+	 * @property {String} 			color 		字体颜色 (默认 '#ffffff' )
+	 * @property {String} 			shape 		徽标形状,circle-四角均为圆角,horn-左下角为直角 (默认 'circle' )
+	 * @property {String} 			numberType	设置数字的显示方式,overflow|ellipsis|limit  (默认 'overflow' )
+	 * @property {Array}} 			offset		设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效
+	 * @property {Boolean} 			inverted	是否反转背景和字体颜色(默认 false )
+	 * @property {Boolean} 			absolute	是否绝对定位(默认 false )
+	 * @property {Object}			customStyle	定义需要用到的外部样式
+	 * @example <u-badge :type="type" :count="count"></u-badge>
+	 */
+	export default {
+		name: 'u-badge',
+		mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
+		computed: {
+			// 是否将badge中心与父组件右上角重合
+			boxStyle() {
+				let style = {};
+				return style;
+			},
+			// 整个组件的样式
+			badgeStyle() {
+				const style = {}
+				if(this.color) {
+					style.color = this.color
+				}
+				if (this.bgColor && !this.inverted) {
+					style.backgroundColor = this.bgColor
+				}
+				if (this.absolute) {
+					style.position = 'absolute'
+					// 如果有设置offset参数
+					if(this.offset.length) {
+						// top和right分为为offset的第一个和第二个值,如果没有第二个值,则right等于top
+						const top = this.offset[0]
+						const right = this.offset[1] || top
+						style.top = uni.$u.addUnit(top)
+						style.right = uni.$u.addUnit(right)
+					}
+				}
+				return style
+			},
+			showValue() {
+				switch (this.numberType) {
+					case "overflow":
+						return Number(this.value) > Number(this.max) ? this.max + "+" : this.value
+						break;
+					case "ellipsis":
+						return Number(this.value) > Number(this.max) ? "..." : this.value
+						break;
+					case "limit":
+						return Number(this.value) > 999 ? Number(this.value) >= 9999 ?
+							Math.floor(this.value / 1e4 * 100) / 100 + "w" : Math.floor(this.value /
+								1e3 * 100) / 100 + "k" : this.value
+						break;
+					default:
+						return Number(this.value)
+				}
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+
+	$u-badge-primary: $u-primary !default;
+	$u-badge-error: $u-error !default;
+	$u-badge-success: $u-success !default;
+	$u-badge-info: $u-info !default;
+	$u-badge-warning: $u-warning !default;
+	$u-badge-dot-radius: 100px !default;
+	$u-badge-dot-size: 8px !default;
+	$u-badge-dot-right: 4px !default;
+	$u-badge-dot-top: 0 !default;
+	$u-badge-text-font-size: 11px !default;
+	$u-badge-text-right: 10px !default;
+	$u-badge-text-padding: 2px 5px !default;
+	$u-badge-text-align: center !default;
+	$u-badge-text-color: #FFFFFF !default;
+
+	.u-badge {
+		border-top-right-radius: $u-badge-dot-radius;
+		border-top-left-radius: $u-badge-dot-radius;
+		border-bottom-left-radius: $u-badge-dot-radius;
+		border-bottom-right-radius: $u-badge-dot-radius;
+		@include flex;
+		line-height: $u-badge-text-font-size;
+		text-align: $u-badge-text-align;
+		font-size: $u-badge-text-font-size;
+		color: $u-badge-text-color;
+
+		&--dot {
+			height: $u-badge-dot-size;
+			width: $u-badge-dot-size;
+		}
+		
+		&--inverted {
+			font-size: 13px;
+		}
+		
+		&--not-dot {
+			padding: $u-badge-text-padding;
+		}
+
+		&--horn {
+			border-bottom-left-radius: 0;
+		}
+
+		&--primary {
+			background-color: $u-badge-primary;
+		}
+		
+		&--primary--inverted {
+			color: $u-badge-primary;
+		}
+
+		&--error {
+			background-color: $u-badge-error;
+		}
+		
+		&--error--inverted {
+			color: $u-badge-error;
+		}
+
+		&--success {
+			background-color: $u-badge-success;
+		}
+		
+		&--success--inverted {
+			color: $u-badge-success;
+		}
+
+		&--info {
+			background-color: $u-badge-info;
+		}
+		
+		&--info--inverted {
+			color: $u-badge-info;
+		}
+
+		&--warning {
+			background-color: $u-badge-warning;
+		}
+		
+		&--warning--inverted {
+			color: $u-badge-warning;
+		}
+	}
+</style>

+ 46 - 0
node_modules/uview-ui/components/u-button/nvue.scss

xqd
@@ -0,0 +1,46 @@
+$u-button-active-opacity:0.75 !default;
+$u-button-loading-text-margin-left:4px !default;
+$u-button-text-color: #FFFFFF !default;
+$u-button-text-plain-error-color:$u-error !default;
+$u-button-text-plain-warning-color:$u-warning !default;
+$u-button-text-plain-success-color:$u-success !default;
+$u-button-text-plain-info-color:$u-info !default;
+$u-button-text-plain-primary-color:$u-primary !default;
+.u-button {
+	&--active {
+		opacity: $u-button-active-opacity;
+	}
+	
+	&--active--plain {
+		background-color: rgb(217, 217, 217);
+	}
+	
+	&__loading-text {
+		margin-left:$u-button-loading-text-margin-left;
+	}
+	
+	&__text,
+	&__loading-text {
+		color:$u-button-text-color;
+	}
+	
+	&__text--plain--error {
+		color:$u-button-text-plain-error-color;
+	}
+	
+	&__text--plain--warning {
+		color:$u-button-text-plain-warning-color;
+	}
+	
+	&__text--plain--success{
+		color:$u-button-text-plain-success-color;
+	}
+	
+	&__text--plain--info {
+		color:$u-button-text-plain-info-color;
+	}
+	
+	&__text--plain--primary {
+		color:$u-button-text-plain-primary-color;
+	}
+}

+ 161 - 0
node_modules/uview-ui/components/u-button/props.js

xqd
@@ -0,0 +1,161 @@
+/*
+ * @Author       : LQ
+ * @Description  :
+ * @version      : 1.0
+ * @Date         : 2021-08-16 10:04:04
+ * @LastAuthor   : LQ
+ * @lastTime     : 2021-08-16 10:04:24
+ * @FilePath     : /u-view2.0/uview-ui/components/u-button/props.js
+ */
+export default {
+    props: {
+        // 是否细边框
+        hairline: {
+            type: Boolean,
+            default: uni.$u.props.button.hairline
+        },
+        // 按钮的预置样式,info,primary,error,warning,success
+        type: {
+            type: String,
+            default: uni.$u.props.button.type
+        },
+        // 按钮尺寸,large,normal,small,mini
+        size: {
+            type: String,
+            default: uni.$u.props.button.size
+        },
+        // 按钮形状,circle(两边为半圆),square(带圆角)
+        shape: {
+            type: String,
+            default: uni.$u.props.button.shape
+        },
+        // 按钮是否镂空
+        plain: {
+            type: Boolean,
+            default: uni.$u.props.button.plain
+        },
+        // 是否禁止状态
+        disabled: {
+            type: Boolean,
+            default: uni.$u.props.button.disabled
+        },
+        // 是否加载中
+        loading: {
+            type: Boolean,
+            default: uni.$u.props.button.loading
+        },
+        // 加载中提示文字
+        loadingText: {
+            type: [String, Number],
+            default: uni.$u.props.button.loadingText
+        },
+        // 加载状态图标类型
+        loadingMode: {
+            type: String,
+            default: uni.$u.props.button.loadingMode
+        },
+        // 加载图标大小
+        loadingSize: {
+            type: [String, Number],
+            default: uni.$u.props.button.loadingSize
+        },
+        // 开放能力,具体请看uniapp稳定关于button组件部分说明
+        // https://uniapp.dcloud.io/component/button
+        openType: {
+            type: String,
+            default: uni.$u.props.button.openType
+        },
+        // 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件
+        // 取值为submit(提交表单),reset(重置表单)
+        formType: {
+            type: String,
+            default: uni.$u.props.button.formType
+        },
+        // 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效
+        // 只微信小程序、QQ小程序有效
+        appParameter: {
+            type: String,
+            default: uni.$u.props.button.appParameter
+        },
+        // 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效
+        hoverStopPropagation: {
+            type: Boolean,
+            default: uni.$u.props.button.hoverStopPropagation
+        },
+        // 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效
+        lang: {
+            type: String,
+            default: uni.$u.props.button.lang
+        },
+        // 会话来源,open-type="contact"时有效。只微信小程序有效
+        sessionFrom: {
+            type: String,
+            default: uni.$u.props.button.sessionFrom
+        },
+        // 会话内消息卡片标题,open-type="contact"时有效
+        // 默认当前标题,只微信小程序有效
+        sendMessageTitle: {
+            type: String,
+            default: uni.$u.props.button.sendMessageTitle
+        },
+        // 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效
+        // 默认当前分享路径,只微信小程序有效
+        sendMessagePath: {
+            type: String,
+            default: uni.$u.props.button.sendMessagePath
+        },
+        // 会话内消息卡片图片,open-type="contact"时有效
+        // 默认当前页面截图,只微信小程序有效
+        sendMessageImg: {
+            type: String,
+            default: uni.$u.props.button.sendMessageImg
+        },
+        // 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,
+        // 用户点击后可以快速发送小程序消息,open-type="contact"时有效
+        showMessageCard: {
+            type: Boolean,
+            default: uni.$u.props.button.showMessageCard
+        },
+        // 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
+        dataName: {
+            type: String,
+            default: uni.$u.props.button.dataName
+        },
+        // 节流,一定时间内只能触发一次
+        throttleTime: {
+            type: [String, Number],
+            default: uni.$u.props.button.throttleTime
+        },
+        // 按住后多久出现点击态,单位毫秒
+        hoverStartTime: {
+            type: [String, Number],
+            default: uni.$u.props.button.hoverStartTime
+        },
+        // 手指松开后点击态保留时间,单位毫秒
+        hoverStayTime: {
+            type: [String, Number],
+            default: uni.$u.props.button.hoverStayTime
+        },
+        // 按钮文字,之所以通过props传入,是因为slot传入的话
+        // nvue中无法控制文字的样式
+        text: {
+            type: [String, Number],
+            default: uni.$u.props.button.text
+        },
+        // 按钮图标
+        icon: {
+            type: String,
+            default: uni.$u.props.button.icon
+        },
+        // 按钮图标
+        iconColor: {
+            type: String,
+            default: uni.$u.props.button.icon
+        },
+        // 按钮颜色,支持传入linear-gradient渐变色
+        color: {
+            type: String,
+            default: uni.$u.props.button.color
+        }
+    }
+}

+ 490 - 0
node_modules/uview-ui/components/u-button/u-button.vue

xqd
@@ -0,0 +1,490 @@
+<template>
+    <!-- #ifndef APP-NVUE -->
+    <button
+        :hover-start-time="Number(hoverStartTime)"
+        :hover-stay-time="Number(hoverStayTime)"
+        :form-type="formType"
+        :open-type="openType"
+        :app-parameter="appParameter"
+        :hover-stop-propagation="hoverStopPropagation"
+        :send-message-title="sendMessageTitle"
+        :send-message-path="sendMessagePath"
+        :lang="lang"
+        :data-name="dataName"
+        :session-from="sessionFrom"
+        :send-message-img="sendMessageImg"
+        :show-message-card="showMessageCard"
+        @getphonenumber="getphonenumber"
+        @getuserinfo="getuserinfo"
+        @error="error"
+        @opensetting="opensetting"
+        @launchapp="launchapp"
+        :hover-class="!disabled && !loading ? 'u-button--active' : ''"
+        class="u-button u-reset-button"
+        :style="[baseColor, $u.addStyle(customStyle)]"
+        @tap="clickHandler"
+        :class="bemClass"
+    >
+        <template v-if="loading">
+            <u-loading-icon
+                :mode="loadingMode"
+                :size="textSize * 1.15"
+                :color="loadingColor"
+            ></u-loading-icon>
+            <text
+                class="u-button__loading-text"
+                :style="[{ fontSize: textSize + 'px' }]"
+                >{{ loadingText || text }}</text
+            >
+        </template>
+        <template v-else>
+            <u-icon
+                v-if="icon"
+                :name="icon"
+                :color="iconColorCom"
+                :size="textSize * 1.35"
+                :customStyle="{ marginRight: '2px' }"
+            ></u-icon>
+            <slot>
+                <text
+                    class="u-button__text"
+                    :style="[{ fontSize: textSize + 'px' }]"
+                    >{{ text }}</text
+                >
+            </slot>
+        </template>
+    </button>
+    <!-- #endif -->
+
+    <!-- #ifdef APP-NVUE -->
+    <view
+        :hover-start-time="Number(hoverStartTime)"
+        :hover-stay-time="Number(hoverStayTime)"
+        class="u-button"
+        :hover-class="
+            !disabled && !loading && !color && (plain || type === 'info')
+                ? 'u-button--active--plain'
+                : !disabled && !loading && !plain
+                ? 'u-button--active'
+                : ''
+        "
+        @tap="clickHandler"
+        :class="bemClass"
+        :style="[baseColor, $u.addStyle(customStyle)]"
+    >
+        <template v-if="loading">
+            <u-loading-icon
+                :mode="loadingMode"
+                :size="textSize * 1.15"
+                :color="loadingColor"
+            ></u-loading-icon>
+            <text
+                class="u-button__loading-text"
+                :style="[nvueTextStyle]"
+                :class="[plain && `u-button__text--plain--${type}`]"
+                >{{ loadingText || text }}</text
+            >
+        </template>
+        <template v-else>
+            <u-icon
+                v-if="icon"
+                :name="icon"
+                :color="iconColorCom"
+                :size="textSize * 1.35"
+            ></u-icon>
+            <text
+                class="u-button__text"
+                :style="[
+                    {
+                        marginLeft: icon ? '2px' : 0,
+                    },
+                    nvueTextStyle,
+                ]"
+                :class="[plain && `u-button__text--plain--${type}`]"
+                >{{ text }}</text
+            >
+        </template>
+    </view>
+    <!-- #endif -->
+</template>
+
+<script>
+import button from "../../libs/mixin/button.js";
+import openType from "../../libs/mixin/openType.js";
+import props from "./props.js";
+/**
+ * button 按钮
+ * @description Button 按钮
+ * @tutorial https://www.uviewui.com/components/button.html
+ *
+ * @property {Boolean}			hairline				是否显示按钮的细边框 (默认 true )
+ * @property {String}			type					按钮的预置样式,info,primary,error,warning,success (默认 'info' )
+ * @property {String}			size					按钮尺寸,large,normal,mini (默认 normal)
+ * @property {String}			shape					按钮形状,circle(两边为半圆),square(带圆角) (默认 'square' )
+ * @property {Boolean}			plain					按钮是否镂空,背景色透明 (默认 false)
+ * @property {Boolean}			disabled				是否禁用 (默认 false)
+ * @property {Boolean}			loading					按钮名称前是否带 loading 图标(App-nvue 平台,在 ios 上为雪花,Android上为圆圈) (默认 false)
+ * @property {String | Number}	loadingText				加载中提示文字
+ * @property {String}			loadingMode				加载状态图标类型 (默认 'spinner' )
+ * @property {String | Number}	loadingSize				加载图标大小 (默认 15 )
+ * @property {String}			openType				开放能力,具体请看uniapp稳定关于button组件部分说明
+ * @property {String}			formType				用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件
+ * @property {String}			appParameter			打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 (注:只微信小程序、QQ小程序有效)
+ * @property {Boolean}			hoverStopPropagation	指定是否阻止本节点的祖先节点出现点击态,微信小程序有效(默认 true )
+ * @property {String}			lang					指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文(默认 en )
+ * @property {String}			sessionFrom				会话来源,openType="contact"时有效
+ * @property {String}			sendMessageTitle		会话内消息卡片标题,openType="contact"时有效
+ * @property {String}			sendMessagePath			会话内消息卡片点击跳转小程序路径,openType="contact"时有效
+ * @property {String}			sendMessageImg			会话内消息卡片图片,openType="contact"时有效
+ * @property {Boolean}			showMessageCard			是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效(默认false)
+ * @property {String}			dataName				额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
+ * @property {String | Number}	throttleTime			节流,一定时间内只能触发一次 (默认 0 )
+ * @property {String | Number}	hoverStartTime			按住后多久出现点击态,单位毫秒 (默认 0 )
+ * @property {String | Number}	hoverStayTime			手指松开后点击态保留时间,单位毫秒 (默认 200 )
+ * @property {String | Number}	text					按钮文字,之所以通过props传入,是因为slot传入的话(注:nvue中无法控制文字的样式)
+ * @property {String}			icon					按钮图标
+ * @property {String}			iconColor				按钮图标颜色
+ * @property {String}			color					按钮颜色,支持传入linear-gradient渐变色
+ * @property {Object}			customStyle				定义需要用到的外部样式
+ *
+ * @event {Function}	click			非禁止并且非加载中,才能点击
+ * @event {Function}	getphonenumber	open-type="getPhoneNumber"时有效
+ * @event {Function}	getuserinfo		用户点击该按钮时,会返回获取到的用户信息,从返回参数的detail中获取到的值同uni.getUserInfo
+ * @event {Function}	error			当使用开放能力时,发生错误的回调
+ * @event {Function}	opensetting		在打开授权设置页并关闭后回调
+ * @event {Function}	launchapp		打开 APP 成功的回调
+ * @example <u-button>月落</u-button>
+ */
+export default {
+    name: "u-button",
+    // #ifdef MP
+    mixins: [uni.$u.mpMixin, uni.$u.mixin, button, openType, props],
+    // #endif
+    // #ifndef MP
+    mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+    // #endif
+    data() {
+        return {};
+    },
+    computed: {
+        // 生成bem风格的类名
+        bemClass() {
+            // this.bem为一个computed变量,在mixin中
+            if (!this.color) {
+                return this.bem(
+                    "button",
+                    ["type", "shape", "size"],
+                    ["disabled", "plain", "hairline"]
+                );
+            } else {
+                // 由于nvue的原因,在有color参数时,不需要传入type,否则会生成type相关的类型,影响最终的样式
+                return this.bem(
+                    "button",
+                    ["shape", "size"],
+                    ["disabled", "plain", "hairline"]
+                );
+            }
+        },
+        loadingColor() {
+            if (this.plain) {
+                // 如果有设置color值,则用color值,否则使用type主题颜色
+                return this.color
+                    ? this.color
+                    : uni.$u.config.color[`u-${this.type}`];
+            }
+            if (this.type === "info") {
+                return "#c9c9c9";
+            }
+            return "rgb(200, 200, 200)";
+        },
+        iconColorCom() {
+            // 如果是镂空状态,设置了color就用color值,否则使用主题颜色,
+            // u-icon的color能接受一个主题颜色的值
+			if (this.iconColor) return this.iconColor;
+			if (this.plain) {
+                return this.color ? this.color : this.type;
+            } else {
+                return this.type === "info" ? "#000000" : "#ffffff";
+            }
+        },
+        baseColor() {
+            let style = {};
+            if (this.color) {
+                // 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
+                style.color = this.plain ? this.color : "white";
+                if (!this.plain) {
+                    // 非镂空,背景色使用自定义的颜色
+                    style["background-color"] = this.color;
+                }
+                if (this.color.indexOf("gradient") !== -1) {
+                    // 如果自定义的颜色为渐变色,不显示边框,以及通过backgroundImage设置渐变色
+                    // weex文档说明可以写borderWidth的形式,为什么这里需要分开写?
+                    // 因为weex是阿里巴巴为了部门业绩考核而做的你懂的东西,所以需要这么写才有效
+                    style.borderTopWidth = 0;
+                    style.borderRightWidth = 0;
+                    style.borderBottomWidth = 0;
+                    style.borderLeftWidth = 0;
+                    if (!this.plain) {
+                        style.backgroundImage = this.color;
+                    }
+                } else {
+                    // 非渐变色,则设置边框相关的属性
+                    style.borderColor = this.color;
+                    style.borderWidth = "1px";
+                    style.borderStyle = "solid";
+                }
+            }
+            return style;
+        },
+        // nvue版本按钮的字体不会继承父组件的颜色,需要对每一个text组件进行单独的设置
+        nvueTextStyle() {
+            let style = {};
+            // 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
+            if (this.type === "info") {
+                style.color = "#323233";
+            }
+            if (this.color) {
+                style.color = this.plain ? this.color : "white";
+            }
+            style.fontSize = this.textSize + "px";
+            return style;
+        },
+        // 字体大小
+        textSize() {
+            let fontSize = 14,
+                { size } = this;
+            if (size === "large") fontSize = 16;
+            if (size === "normal") fontSize = 14;
+            if (size === "small") fontSize = 12;
+            if (size === "mini") fontSize = 10;
+            return fontSize;
+        },
+    },
+    methods: {
+        clickHandler() {
+            // 非禁止并且非加载中,才能点击
+            if (!this.disabled && !this.loading) {
+				// 进行节流控制,每this.throttle毫秒内,只在开始处执行
+				uni.$u.throttle(() => {
+					this.$emit("click");
+				}, this.throttleTime);
+            }
+        },
+        // 下面为对接uniapp官方按钮开放能力事件回调的对接
+        getphonenumber(res) {
+            this.$emit("getphonenumber", res);
+        },
+        getuserinfo(res) {
+            this.$emit("getuserinfo", res);
+        },
+        error(res) {
+            this.$emit("error", res);
+        },
+        opensetting(res) {
+            this.$emit("opensetting", res);
+        },
+        launchapp(res) {
+            this.$emit("launchapp", res);
+        },
+    },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "../../libs/css/components.scss";
+
+/* #ifndef APP-NVUE */
+@import "./vue.scss";
+/* #endif */
+
+/* #ifdef APP-NVUE */
+@import "./nvue.scss";
+/* #endif */
+
+$u-button-u-button-height: 40px !default;
+$u-button-text-font-size: 15px !default;
+$u-button-loading-text-font-size: 15px !default;
+$u-button-loading-text-margin-left: 4px !default;
+$u-button-large-width: 100% !default;
+$u-button-large-height: 50px !default;
+$u-button-normal-padding: 0 12px !default;
+$u-button-large-padding: 0 15px !default;
+$u-button-normal-font-size: 14px !default;
+$u-button-small-min-width: 60px !default;
+$u-button-small-height: 30px !default;
+$u-button-small-padding: 0px 8px !default;
+$u-button-mini-padding: 0px 8px !default;
+$u-button-small-font-size: 12px !default;
+$u-button-mini-height: 22px !default;
+$u-button-mini-font-size: 10px !default;
+$u-button-mini-min-width: 50px !default;
+$u-button-disabled-opacity: 0.5 !default;
+$u-button-info-color: #323233 !default;
+$u-button-info-background-color: #fff !default;
+$u-button-info-border-color: #ebedf0 !default;
+$u-button-info-border-width: 1px !default;
+$u-button-info-border-style: solid !default;
+$u-button-success-color: #fff !default;
+$u-button-success-background-color: $u-success !default;
+$u-button-success-border-color: $u-button-success-background-color !default;
+$u-button-success-border-width: 1px !default;
+$u-button-success-border-style: solid !default;
+$u-button-primary-color: #fff !default;
+$u-button-primary-background-color: $u-primary !default;
+$u-button-primary-border-color: $u-button-primary-background-color !default;
+$u-button-primary-border-width: 1px !default;
+$u-button-primary-border-style: solid !default;
+$u-button-error-color: #fff !default;
+$u-button-error-background-color: $u-error !default;
+$u-button-error-border-color: $u-button-error-background-color !default;
+$u-button-error-border-width: 1px !default;
+$u-button-error-border-style: solid !default;
+$u-button-warning-color: #fff !default;
+$u-button-warning-background-color: $u-warning !default;
+$u-button-warning-border-color: $u-button-warning-background-color !default;
+$u-button-warning-border-width: 1px !default;
+$u-button-warning-border-style: solid !default;
+$u-button-block-width: 100% !default;
+$u-button-circle-border-top-right-radius: 100px !default;
+$u-button-circle-border-top-left-radius: 100px !default;
+$u-button-circle-border-bottom-left-radius: 100px !default;
+$u-button-circle-border-bottom-right-radius: 100px !default;
+$u-button-square-border-top-right-radius: 3px !default;
+$u-button-square-border-top-left-radius: 3px !default;
+$u-button-square-border-bottom-left-radius: 3px !default;
+$u-button-square-border-bottom-right-radius: 3px !default;
+$u-button-icon-min-width: 1em !default;
+$u-button-plain-background-color: #fff !default;
+$u-button-hairline-border-width: 0.5px !default;
+
+.u-button {
+    height: $u-button-u-button-height;
+    position: relative;
+    align-items: center;
+    justify-content: center;
+    @include flex;
+    /* #ifndef APP-NVUE */
+    box-sizing: border-box;
+    /* #endif */
+    flex-direction: row;
+
+    &__text {
+        font-size: $u-button-text-font-size;
+    }
+
+    &__loading-text {
+        font-size: $u-button-loading-text-font-size;
+        margin-left: $u-button-loading-text-margin-left;
+    }
+
+    &--large {
+        /* #ifndef APP-NVUE */
+        width: $u-button-large-width;
+        /* #endif */
+        height: $u-button-large-height;
+        padding: $u-button-large-padding;
+    }
+
+    &--normal {
+        padding: $u-button-normal-padding;
+        font-size: $u-button-normal-font-size;
+    }
+
+    &--small {
+        /* #ifndef APP-NVUE */
+        min-width: $u-button-small-min-width;
+        /* #endif */
+        height: $u-button-small-height;
+        padding: $u-button-small-padding;
+        font-size: $u-button-small-font-size;
+    }
+
+    &--mini {
+        height: $u-button-mini-height;
+        font-size: $u-button-mini-font-size;
+        /* #ifndef APP-NVUE */
+        min-width: $u-button-mini-min-width;
+        /* #endif */
+        padding: $u-button-mini-padding;
+    }
+
+    &--disabled {
+        opacity: $u-button-disabled-opacity;
+    }
+
+    &--info {
+        color: $u-button-info-color;
+        background-color: $u-button-info-background-color;
+        border-color: $u-button-info-border-color;
+        border-width: $u-button-info-border-width;
+        border-style: $u-button-info-border-style;
+    }
+
+    &--success {
+        color: $u-button-success-color;
+        background-color: $u-button-success-background-color;
+        border-color: $u-button-success-border-color;
+        border-width: $u-button-success-border-width;
+        border-style: $u-button-success-border-style;
+    }
+
+    &--primary {
+        color: $u-button-primary-color;
+        background-color: $u-button-primary-background-color;
+        border-color: $u-button-primary-border-color;
+        border-width: $u-button-primary-border-width;
+        border-style: $u-button-primary-border-style;
+    }
+
+    &--error {
+        color: $u-button-error-color;
+        background-color: $u-button-error-background-color;
+        border-color: $u-button-error-border-color;
+        border-width: $u-button-error-border-width;
+        border-style: $u-button-error-border-style;
+    }
+
+    &--warning {
+        color: $u-button-warning-color;
+        background-color: $u-button-warning-background-color;
+        border-color: $u-button-warning-border-color;
+        border-width: $u-button-warning-border-width;
+        border-style: $u-button-warning-border-style;
+    }
+
+    &--block {
+        @include flex;
+        width: $u-button-block-width;
+    }
+
+    &--circle {
+        border-top-right-radius: $u-button-circle-border-top-right-radius;
+        border-top-left-radius: $u-button-circle-border-top-left-radius;
+        border-bottom-left-radius: $u-button-circle-border-bottom-left-radius;
+        border-bottom-right-radius: $u-button-circle-border-bottom-right-radius;
+    }
+
+    &--square {
+        border-bottom-left-radius: $u-button-square-border-top-right-radius;
+        border-bottom-right-radius: $u-button-square-border-top-left-radius;
+        border-top-left-radius: $u-button-square-border-bottom-left-radius;
+        border-top-right-radius: $u-button-square-border-bottom-right-radius;
+    }
+
+    &__icon {
+        /* #ifndef APP-NVUE */
+        min-width: $u-button-icon-min-width;
+        line-height: inherit !important;
+        vertical-align: top;
+        /* #endif */
+    }
+
+    &--plain {
+        background-color: $u-button-plain-background-color;
+    }
+
+    &--hairline {
+        border-width: $u-button-hairline-border-width !important;
+    }
+}
+</style>

+ 80 - 0
node_modules/uview-ui/components/u-button/vue.scss

xqd
@@ -0,0 +1,80 @@
+// nvue下hover-class无效
+$u-button-before-top:50% !default;
+$u-button-before-left:50% !default;
+$u-button-before-width:100% !default;
+$u-button-before-height:100% !default;
+$u-button-before-transform:translate(-50%, -50%) !default;
+$u-button-before-opacity:0 !default;
+$u-button-before-background-color:#000 !default;
+$u-button-before-border-color:#000 !default;
+$u-button-active-before-opacity:.15 !default;
+$u-button-icon-margin-left:4px !default;
+$u-button-plain-u-button-info-color:$u-info;
+$u-button-plain-u-button-success-color:$u-success;
+$u-button-plain-u-button-error-color:$u-error;
+$u-button-plain-u-button-warning-color:$u-error;
+
+.u-button {
+	width: 100%;
+	
+	&__text {
+		white-space: nowrap;
+		line-height: 1;
+	}
+	
+	&:before {
+		position: absolute;
+		top:$u-button-before-top;
+		left:$u-button-before-left;
+		width:$u-button-before-width;
+		height:$u-button-before-height;
+		border: inherit;
+		border-radius: inherit;
+		transform:$u-button-before-transform;
+		opacity:$u-button-before-opacity;
+		content: " ";
+		background-color:$u-button-before-background-color;
+		border-color:$u-button-before-border-color;
+	}
+	
+	&--active {
+		&:before {
+			opacity: .15
+		}
+	}
+	
+	&__icon+&__text:not(:empty),
+	&__loading-text {
+		margin-left:$u-button-icon-margin-left;
+	}
+	
+	&--plain {
+		&.u-button--primary {
+			color: $u-primary;
+		}
+	}
+	
+	&--plain {
+		&.u-button--info {
+			color:$u-button-plain-u-button-info-color;
+		}
+	}
+	
+	&--plain {
+		&.u-button--success {
+			color:$u-button-plain-u-button-success-color;
+		}
+	}
+	
+	&--plain {
+		&.u-button--error {
+			color:$u-button-plain-u-button-error-color;
+		}
+	}
+	
+	&--plain {
+		&.u-button--warning {
+			color:$u-button-plain-u-button-warning-color;
+		}
+	}
+}

+ 99 - 0
node_modules/uview-ui/components/u-calendar/header.vue

xqd
@@ -0,0 +1,99 @@
+<template>
+	<view class="u-calendar-header u-border-bottom">
+		<text
+			class="u-calendar-header__title"
+			v-if="showTitle"
+		>{{ title }}</text>
+		<text
+			class="u-calendar-header__subtitle"
+			v-if="showSubtitle"
+		>{{ subtitle }}</text>
+		<view class="u-calendar-header__weekdays">
+			<text class="u-calendar-header__weekdays__weekday">一</text>
+			<text class="u-calendar-header__weekdays__weekday">二</text>
+			<text class="u-calendar-header__weekdays__weekday">三</text>
+			<text class="u-calendar-header__weekdays__weekday">四</text>
+			<text class="u-calendar-header__weekdays__weekday">五</text>
+			<text class="u-calendar-header__weekdays__weekday">六</text>
+			<text class="u-calendar-header__weekdays__weekday">日</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'u-calendar-header',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin],
+		props: {
+			// 标题
+			title: {
+				type: String,
+				default: ''
+			},
+			// 副标题
+			subtitle: {
+				type: String,
+				default: ''
+			},
+			// 是否显示标题
+			showTitle: {
+				type: Boolean,
+				default: true
+			},
+			// 是否显示副标题
+			showSubtitle: {
+				type: Boolean,
+				default: true
+			},
+		},
+		data() {
+			return {
+
+			}
+		},
+		methods: {
+			name() {
+
+			}
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+
+	.u-calendar-header {
+		padding-bottom: 4px;
+
+		&__title {
+			font-size: 16px;
+			color: $u-main-color;
+			text-align: center;
+			height: 42px;
+			line-height: 42px;
+			font-weight: bold;
+		}
+
+		&__subtitle {
+			font-size: 14px;
+			color: $u-main-color;
+			height: 40px;
+			text-align: center;
+			line-height: 40px;
+			font-weight: bold;
+		}
+
+		&__weekdays {
+			@include flex;
+			justify-content: space-between;
+
+			&__weekday {
+				font-size: 13px;
+				color: $u-main-color;
+				line-height: 30px;
+				flex: 1;
+				text-align: center;
+			}
+		}
+	}
+</style>

+ 579 - 0
node_modules/uview-ui/components/u-calendar/month.vue

xqd
@@ -0,0 +1,579 @@
+<template>
+	<view class="u-calendar-month-wrapper" ref="u-calendar-month-wrapper">
+		<view v-for="(item, index) in months" :key="index" :class="[`u-calendar-month-${index}`]"
+			:ref="`u-calendar-month-${index}`" :id="`month-${index}`">
+			<text v-if="index !== 0" class="u-calendar-month__title">{{ item.year }}年{{ item.month }}月</text>
+			<view class="u-calendar-month__days">
+				<view v-if="showMark" class="u-calendar-month__days__month-mark-wrapper">
+					<text class="u-calendar-month__days__month-mark-wrapper__text">{{ item.month }}</text>
+				</view>
+				<view class="u-calendar-month__days__day" v-for="(item1, index1) in item.date" :key="index1"
+					:style="[dayStyle(index, index1, item1)]" @tap="clickHandler(index, index1, item1)"
+					:class="[item1.selected && 'u-calendar-month__days__day__select--selected']">
+					<view class="u-calendar-month__days__day__select" :style="[daySelectStyle(index, index1, item1)]">
+						<text class="u-calendar-month__days__day__select__info"
+							:class="[item1.disabled && 'u-calendar-month__days__day__select__info--disabled']"
+							:style="[textStyle(item1)]">{{ item1.day }}</text>
+						<text v-if="getBottomInfo(index, index1, item1)"
+							class="u-calendar-month__days__day__select__buttom-info"
+							:class="[item1.disabled && 'u-calendar-month__days__day__select__buttom-info--disabled']"
+							:style="[textStyle(item1)]">{{ getBottomInfo(index, index1, item1) }}</text>
+						<text v-if="item1.dot" class="u-calendar-month__days__day__select__dot"></text>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	// #ifdef APP-NVUE
+	// 由于nvue不支持百分比单位,需要查询宽度来计算每个日期的宽度
+	const dom = uni.requireNativePlugin('dom')
+	// #endif
+	import dayjs from '../../libs/util/dayjs.js';
+	export default {
+		name: 'u-calendar-month',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin],
+		props: {
+			// 是否显示月份背景色
+			showMark: {
+				type: Boolean,
+				default: true
+			},
+			// 主题色,对底部按钮和选中日期有效
+			color: {
+				type: String,
+				default: '#3c9cff'
+			},
+			// 月份数据
+			months: {
+				type: Array,
+				default: () => []
+			},
+			// 日期选择类型
+			mode: {
+				type: String,
+				default: 'single'
+			},
+			// 日期行高
+			rowHeight: {
+				type: [String, Number],
+				default: 58
+			},
+			// mode=multiple时,最多可选多少个日期
+			maxCount: {
+				type: [String, Number],
+				default: Infinity
+			},
+			// mode=range时,第一个日期底部的提示文字
+			startText: {
+				type: String,
+				default: '开始'
+			},
+			// mode=range时,最后一个日期底部的提示文字
+			endText: {
+				type: String,
+				default: '结束'
+			},
+			// 默认选中的日期,mode为multiple或range是必须为数组格式
+			defaultDate: {
+				type: [Array, String, Date],
+				default: null
+			},
+			// 最小的可选日期
+			minDate: {
+				type: [String, Number],
+				default: 0
+			},
+			// 最大可选日期
+			maxDate: {
+				type: [String, Number],
+				default: 0
+			},
+			// 如果没有设置maxDate,则往后推多少个月
+			maxMonth: {
+				type: [String, Number],
+				default: 2
+			},
+			// 是否为只读状态,只读状态下禁止选择日期
+			readonly: {
+				type: Boolean,
+				default: uni.$u.props.calendar.readonly
+			},
+			// 日期区间最多可选天数,默认无限制,mode = range时有效
+			maxRange: {
+				type: [Number, String],
+				default: Infinity
+			},
+			// 范围选择超过最多可选天数时的提示文案,mode = range时有效
+			rangePrompt: {
+				type: String,
+				default: ''
+			},
+			// 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效
+			showRangePrompt: {
+				type: Boolean,
+				default: true
+			},
+			// 是否允许日期范围的起止时间为同一天,mode = range时有效
+			allowSameDay: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				// 每个日期的宽度
+				width: 0,
+				// 当前选中的日期item
+				item: {},
+				selected: []
+			}
+		},
+		watch: {
+			selectedChange: {
+				immediate: true,
+				handler(n) {
+					this.setDefaultDate()
+				}
+			}
+		},
+		computed: {
+			// 多个条件的变化,会引起选中日期的变化,这里统一管理监听
+			selectedChange() {
+				return [this.minDate, this.maxDate, this.defaultDate]
+			},
+			dayStyle(index1, index2, item) {
+				return (index1, index2, item) => {
+					const style = {}
+					let week = item.week
+					// 不进行四舍五入的形式保留2位小数
+					const dayWidth = Number(parseFloat(this.width / 7).toFixed(3).slice(0, -1))
+					// 得出每个日期的宽度
+					// #ifdef APP-NVUE
+					style.width = uni.$u.addUnit(dayWidth)
+					// #endif
+					style.height = uni.$u.addUnit(this.rowHeight)
+					if (index2 === 0) {
+						// 获取当前为星期几,如果为0,则为星期天,减一为每月第一天时,需要向左偏移的item个数
+						week = (week === 0 ? 7 : week) - 1
+						style.marginLeft = uni.$u.addUnit(week * dayWidth)
+					}
+					if (this.mode === 'range') {
+						// 之所以需要这么写,是因为DCloud公司的iOS客户端的开发者能力有限导致的bug
+						style.paddingLeft = 0
+						style.paddingRight = 0
+						style.paddingBottom = 0
+						style.paddingTop = 0
+					}
+					return style
+				}
+			},
+			daySelectStyle() {
+				return (index1, index2, item) => {
+					let date = dayjs(item.date).format("YYYY-MM-DD"),
+						style = {}
+					// 判断date是否在selected数组中,因为月份可能会需要补0,所以使用dateSame判断,而不用数组的includes判断
+					if (this.selected.some(item => this.dateSame(item, date))) {
+						style.backgroundColor = this.color
+					}
+					if (this.mode === 'single') {
+						if (date === this.selected[0]) {
+							// 因为需要对nvue的兼容,只能这么写,无法缩写,也无法通过类名控制等等
+							style.borderTopLeftRadius = '3px'
+							style.borderBottomLeftRadius = '3px'
+							style.borderTopRightRadius = '3px'
+							style.borderBottomRightRadius = '3px'
+						}
+					} else if (this.mode === 'range') {
+						if (this.selected.length >= 2) {
+							const len = this.selected.length - 1
+							// 第一个日期设置左上角和左下角的圆角
+							if (this.dateSame(date, this.selected[0])) {
+								style.borderTopLeftRadius = '3px'
+								style.borderBottomLeftRadius = '3px'
+							}
+							// 最后一个日期设置右上角和右下角的圆角
+							if (this.dateSame(date, this.selected[len])) {
+								style.borderTopRightRadius = '3px'
+								style.borderBottomRightRadius = '3px'
+							}
+							// 处于第一和最后一个之间的日期,背景色设置为浅色,通过将对应颜色进行等分,再取其尾部的颜色值
+							if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
+									.selected[len]))) {
+								style.backgroundColor = uni.$u.colorGradient(this.color, '#ffffff', 100)[90]
+								// 增加一个透明度,让范围区间的背景色也能看到底部的mark水印字符
+								style.opacity = 0.7
+							}
+						} else if (this.selected.length === 1) {
+							// 之所以需要这么写,是因为DCloud公司的iOS客户端的开发者能力有限导致的bug
+							// 进行还原操作,否则在nvue的iOS,uni-app有bug,会导致诡异的表现
+							style.borderTopLeftRadius = '3px'
+							style.borderBottomLeftRadius = '3px'
+						}
+					} else {
+						if (this.selected.some(item => this.dateSame(item, date))) {
+							style.borderTopLeftRadius = '3px'
+							style.borderBottomLeftRadius = '3px'
+							style.borderTopRightRadius = '3px'
+							style.borderBottomRightRadius = '3px'
+						}
+					}
+					return style
+				}
+			},
+			// 某个日期是否被选中
+			textStyle() {
+				return (item) => {
+					const date = dayjs(item.date).format("YYYY-MM-DD"),
+						style = {}
+					// 选中的日期,提示文字设置白色
+					if (this.selected.some(item => this.dateSame(item, date))) {
+						style.color = '#ffffff'
+					}
+					if (this.mode === 'range') {
+						const len = this.selected.length - 1
+						// 如果是范围选择模式,第一个和最后一个之间的日期,文字颜色设置为高亮的主题色
+						if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
+								.selected[len]))) {
+							style.color = this.color
+						}
+					}
+					return style
+				}
+			},
+			// 获取底部的提示文字
+			getBottomInfo() {
+				return (index1, index2, item) => {
+					const date = dayjs(item.date).format("YYYY-MM-DD")
+					const bottomInfo = item.bottomInfo
+					// 当为日期范围模式时,且选择的日期个数大于0时
+					if (this.mode === 'range' && this.selected.length > 0) {
+						if (this.selected.length === 1) {
+							// 选择了一个日期时,如果当前日期为数组中的第一个日期,则显示底部文字为“开始”
+							if (this.dateSame(date, this.selected[0])) return this.startText
+							else return bottomInfo
+						} else {
+							const len = this.selected.length - 1
+							// 如果数组中的日期大于2个时,第一个和最后一个显示为开始和结束日期
+							if (this.dateSame(date, this.selected[0]) && this.dateSame(date, this.selected[1]) &&
+								len === 1) {
+								// 如果长度为2,且第一个等于第二个日期,则提示语放在同一个item中
+								return `${this.startText}/${this.endText}`
+							} else if (this.dateSame(date, this.selected[0])) {
+								return this.startText
+							} else if (this.dateSame(date, this.selected[len])) {
+								return this.endText
+							} else {
+								return bottomInfo
+							}
+						}
+					} else {
+						return bottomInfo
+					}
+				}
+			}
+		},
+		mounted() {
+			this.init()
+		},
+		methods: {
+			init() {
+				// 初始化默认选中
+				this.$emit('monthSelected', this.selected)
+				this.$nextTick(() => {
+					// 这里需要另一个延时,因为获取宽度后,会进行月份数据渲染,只有渲染完成之后,才有真正的高度
+					// 因为nvue下,$nextTick并不是100%可靠的
+					uni.$u.sleep(10).then(() => {
+						this.getWrapperWidth()
+						this.getMonthRect()
+					})
+				})
+			},
+			// 判断两个日期是否相等
+			dateSame(date1, date2) {
+				return dayjs(date1).isSame(dayjs(date2))
+			},
+			// 获取月份数据区域的宽度,因为nvue不支持百分比,所以无法通过css设置每个日期item的宽度
+			getWrapperWidth() {
+				// #ifdef APP-NVUE
+				dom.getComponentRect(this.$refs['u-calendar-month-wrapper'], res => {
+					this.width = res.size.width
+				})
+				// #endif
+				// #ifndef APP-NVUE
+				this.$uGetRect('.u-calendar-month-wrapper').then(size => {
+					this.width = size.width
+				})
+				// #endif
+			},
+			getMonthRect() {
+				// 获取每个月份数据的尺寸,用于父组件在scroll-view滚动事件中,监听当前滚动到了第几个月份
+				const promiseAllArr = this.months.map((item, index) => this.getMonthRectByPromise(
+					`u-calendar-month-${index}`))
+				// 一次性返回
+				Promise.all(promiseAllArr).then(
+					sizes => {
+						let height = 1
+						const topArr = []
+						for (let i = 0; i < this.months.length; i++) {
+							// 添加到months数组中,供scroll-view滚动事件中,判断当前滚动到哪个月份
+							topArr[i] = height
+							height += sizes[i].height
+						}
+						// 由于微信下,无法通过this.months[i].top的形式(引用类型)去修改父组件的month的top值,所以使用事件形式对外发出
+						this.$emit('updateMonthTop', topArr)
+					})
+			},
+			// 获取每个月份区域的尺寸
+			getMonthRectByPromise(el) {
+				// #ifndef APP-NVUE
+				// $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://www.uviewui.com/js/getRect.html
+				// 组件内部一般用this.$uGetRect,对外的为uni.$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][0], res => {
+						resolve(res.size)
+					})
+				})
+				// #endif
+			},
+			// 点击某一个日期
+			clickHandler(index1, index2, item) {
+				if (this.readonly) {
+					return;
+				}
+				this.item = item
+				const date = dayjs(item.date).format("YYYY-MM-DD")
+				if (item.disabled) return
+				// 对上一次选择的日期数组进行深度克隆
+				let selected = uni.$u.deepClone(this.selected)
+				if (this.mode === 'single') {
+					// 单选情况下,让数组中的元素为当前点击的日期
+					selected = [date]
+				} else if (this.mode === 'multiple') {
+					if (selected.some(item => this.dateSame(item, date))) {
+						// 如果点击的日期已在数组中,则进行移除操作,也就是达到反选的效果
+						const itemIndex = selected.findIndex(item => item === date)
+						selected.splice(itemIndex, 1)
+					} else {
+						// 如果点击的日期不在数组中,且已有的长度小于总可选长度时,则添加到数组中去
+						if (selected.length < this.maxCount) selected.push(date)
+					}
+				} else {
+					// 选择区间形式
+					if (selected.length === 0 || selected.length >= 2) {
+						// 如果原来就为0或者大于2的长度,则当前点击的日期,就是开始日期
+						selected = [date]
+					} else if (selected.length === 1) {
+						// 如果已经选择了开始日期
+						const existsDate = selected[0]
+						// 如果当前选择的日期小于上一次选择的日期,则当前的日期定为开始日期
+						if (dayjs(date).isBefore(existsDate)) {
+							selected = [date]
+						} else if (dayjs(date).isAfter(existsDate)) {
+							// 当前日期减去最大可选的日期天数,如果大于起始时间,则进行提示
+							if(dayjs(dayjs(date).subtract(this.maxRange, 'day')).isAfter(dayjs(selected[0])) && this.showRangePrompt) {
+								if(this.rangePrompt) {
+									uni.$u.toast(this.rangePrompt)
+								} else {
+									uni.$u.toast(`选择天数不能超过 ${this.maxRange} 天`)
+								}
+								return
+							}
+							// 如果当前日期大于已有日期,将当前的添加到数组尾部
+							selected.push(date)
+							const startDate = selected[0]
+							const endDate = selected[1]
+							const arr = []
+							let i = 0
+							do {
+								// 将开始和结束日期之间的日期添加到数组中
+								arr.push(dayjs(startDate).add(i, 'day').format("YYYY-MM-DD"))
+								i++
+								// 累加的日期小于结束日期时,继续下一次的循环
+							} while (dayjs(startDate).add(i, 'day').isBefore(dayjs(endDate)))
+							// 为了一次性修改数组,避免computed中多次触发,这里才用arr变量一次性赋值的方式,同时将最后一个日期添加近来
+							arr.push(endDate)
+							selected = arr
+						} else {
+							// 选择区间时,只有一个日期的情况下,且不允许选择起止为同一天的话,不允许选择自己
+							if (selected[0] === date && !this.allowSameDay) return
+							selected.push(date)
+						}
+					}
+				}
+				this.setSelected(selected)
+			},
+			// 设置默认日期
+			setDefaultDate() {
+				if (!this.defaultDate) {
+					// 如果没有设置默认日期,则将当天日期设置为默认选中的日期
+					const selected = [dayjs().format("YYYY-MM-DD")]
+					return this.setSelected(selected, false)
+				}
+				let defaultDate = []
+				const minDate = this.minDate || dayjs().format("YYYY-MM-DD")
+				const maxDate = this.maxDate || dayjs(minDate).add(this.maxMonth - 1, 'month').format("YYYY-MM-DD")
+				if (this.mode === 'single') {
+					// 单选模式,可以是字符串或数组,Date对象等
+					if (!uni.$u.test.array(this.defaultDate)) {
+						defaultDate = [dayjs(this.defaultDate).format("YYYY-MM-DD")]
+					} else {
+						defaultDate = [this.defaultDate[0]]
+					}
+				} else {
+					// 如果为非数组,则不执行
+					if (!uni.$u.test.array(this.defaultDate)) return
+					defaultDate = this.defaultDate
+				}
+				// 过滤用户传递的默认数组,取出只在可允许最大值与最小值之间的元素
+				defaultDate = defaultDate.filter(item => {
+					return dayjs(item).isAfter(dayjs(minDate).subtract(1, 'day')) && dayjs(item).isBefore(dayjs(
+						maxDate).add(1, 'day'))
+				})
+				this.setSelected(defaultDate, false)
+			},
+			setSelected(selected, event = true) {
+				this.selected = selected
+				event && this.$emit('monthSelected', this.selected)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+
+	.u-calendar-month-wrapper {
+		margin-top: 4px;
+	}
+
+	.u-calendar-month {
+
+		&__title {
+			font-size: 14px;
+			line-height: 42px;
+			height: 42px;
+			color: $u-main-color;
+			text-align: center;
+			font-weight: bold;
+		}
+
+		&__days {
+			position: relative;
+			@include flex;
+			flex-wrap: wrap;
+
+			&__month-mark-wrapper {
+				position: absolute;
+				top: 0;
+				bottom: 0;
+				left: 0;
+				right: 0;
+				@include flex;
+				justify-content: center;
+				align-items: center;
+
+				&__text {
+					font-size: 155px;
+					color: rgba(231, 232, 234, 0.83);
+				}
+			}
+
+			&__day {
+				@include flex;
+				padding: 2px;
+				/* #ifndef APP-NVUE */
+				// vue下使用css进行宽度计算,因为某些安卓机会无法进行js获取父元素宽度进行计算得出,会有偏移
+				width: calc(100% / 7);
+				box-sizing: border-box;
+				/* #endif */
+
+				&__select {
+					flex: 1;
+					@include flex;
+					align-items: center;
+					justify-content: center;
+					position: relative;
+
+					&__dot {
+						width: 7px;
+						height: 7px;
+						border-radius: 100px;
+						background-color: $u-error;
+						position: absolute;
+						top: 12px;
+						right: 7px;
+					}
+
+					&__buttom-info {
+						color: $u-content-color;
+						text-align: center;
+						position: absolute;
+						bottom: 5px;
+						font-size: 10px;
+						text-align: center;
+						left: 0;
+						right: 0;
+
+						&--selected {
+							color: #ffffff;
+						}
+
+						&--disabled {
+							color: #cacbcd;
+						}
+					}
+
+					&__info {
+						text-align: center;
+						font-size: 16px;
+
+						&--selected {
+							color: #ffffff;
+						}
+
+						&--disabled {
+							color: #cacbcd;
+						}
+					}
+
+					&--selected {
+						background-color: $u-primary;
+						@include flex;
+						justify-content: center;
+						align-items: center;
+						flex: 1;
+						border-radius: 3px;
+					}
+
+					&--range-selected {
+						opacity: 0.3;
+						border-radius: 0;
+					}
+
+					&--range-start-selected {
+						border-top-right-radius: 0;
+						border-bottom-right-radius: 0;
+					}
+
+					&--range-end-selected {
+						border-top-left-radius: 0;
+						border-bottom-left-radius: 0;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 144 - 0
node_modules/uview-ui/components/u-calendar/props.js

xqd
@@ -0,0 +1,144 @@
+export default {
+    props: {
+        // 日历顶部标题
+        title: {
+            type: String,
+            default: uni.$u.props.calendar.title
+        },
+        // 是否显示标题
+        showTitle: {
+            type: Boolean,
+            default: uni.$u.props.calendar.showTitle
+        },
+        // 是否显示副标题
+        showSubtitle: {
+            type: Boolean,
+            default: uni.$u.props.calendar.showSubtitle
+        },
+        // 日期类型选择,single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围
+        mode: {
+            type: String,
+            default: uni.$u.props.calendar.mode
+        },
+        // mode=range时,第一个日期底部的提示文字
+        startText: {
+            type: String,
+            default: uni.$u.props.calendar.startText
+        },
+        // mode=range时,最后一个日期底部的提示文字
+        endText: {
+            type: String,
+            default: uni.$u.props.calendar.endText
+        },
+        // 自定义列表
+        customList: {
+            type: Array,
+            default: uni.$u.props.calendar.customList
+        },
+        // 主题色,对底部按钮和选中日期有效
+        color: {
+            type: String,
+            default: uni.$u.props.calendar.color
+        },
+        // 最小的可选日期
+        minDate: {
+            type: [String, Number],
+            default: uni.$u.props.calendar.minDate
+        },
+        // 最大可选日期
+        maxDate: {
+            type: [String, Number],
+            default: uni.$u.props.calendar.maxDate
+        },
+        // 默认选中的日期,mode为multiple或range是必须为数组格式
+        defaultDate: {
+            type: [Array, String, Date, null],
+            default: uni.$u.props.calendar.defaultDate
+        },
+        // mode=multiple时,最多可选多少个日期
+        maxCount: {
+            type: [String, Number],
+            default: uni.$u.props.calendar.maxCount
+        },
+        // 日期行高
+        rowHeight: {
+            type: [String, Number],
+            default: uni.$u.props.calendar.rowHeight
+        },
+        // 日期格式化函数
+        formatter: {
+            type: [Function, null],
+            default: uni.$u.props.calendar.formatter
+        },
+        // 是否显示农历
+        showLunar: {
+            type: Boolean,
+            default: uni.$u.props.calendar.showLunar
+        },
+        // 是否显示月份背景色
+        showMark: {
+            type: Boolean,
+            default: uni.$u.props.calendar.showMark
+        },
+        // 确定按钮的文字
+        confirmText: {
+            type: String,
+            default: uni.$u.props.calendar.confirmText
+        },
+        // 确认按钮处于禁用状态时的文字
+        confirmDisabledText: {
+            type: String,
+            default: uni.$u.props.calendar.confirmDisabledText
+        },
+        // 是否显示日历弹窗
+        show: {
+            type: Boolean,
+            default: uni.$u.props.calendar.show
+        },
+        // 是否允许点击遮罩关闭日历
+        closeOnClickOverlay: {
+            type: Boolean,
+            default: uni.$u.props.calendar.closeOnClickOverlay
+        },
+        // 是否为只读状态,只读状态下禁止选择日期
+        readonly: {
+            type: Boolean,
+            default: uni.$u.props.calendar.readonly
+        },
+        // 	是否展示确认按钮
+        showConfirm: {
+            type: Boolean,
+            default: uni.$u.props.calendar.showConfirm
+        },
+        // 日期区间最多可选天数,默认无限制,mode = range时有效
+        maxRange: {
+            type: [Number, String],
+            default: uni.$u.props.calendar.maxRange
+        },
+        // 范围选择超过最多可选天数时的提示文案,mode = range时有效
+        rangePrompt: {
+            type: String,
+            default: uni.$u.props.calendar.rangePrompt
+        },
+        // 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效
+        showRangePrompt: {
+            type: Boolean,
+            default: uni.$u.props.calendar.showRangePrompt
+        },
+        // 是否允许日期范围的起止时间为同一天,mode = range时有效
+        allowSameDay: {
+            type: Boolean,
+            default: uni.$u.props.calendar.allowSameDay
+        },
+		// 圆角值
+		round: {
+		    type: [Boolean, String, Number],
+		    default: uni.$u.props.calendar.round
+		},
+		// 最多展示月份数量
+		monthNum: {
+			type: [Number, String],
+			default: 3
+		}	
+    }
+}

+ 383 - 0
node_modules/uview-ui/components/u-calendar/u-calendar.vue

xqd
@@ -0,0 +1,383 @@
+<template>
+	<u-popup
+		:show="show"
+		mode="bottom"
+		closeable
+		@close="close"
+		:round="round"
+		:closeOnClickOverlay="closeOnClickOverlay"
+	>
+		<view class="u-calendar">
+			<uHeader
+				:title="title"
+				:subtitle="subtitle"
+				:showSubtitle="showSubtitle"
+				:showTitle="showTitle"
+			></uHeader>
+			<scroll-view
+				:style="{
+                    height: $u.addUnit(listHeight)
+                }"
+				scroll-y
+				@scroll="onScroll"
+				:scroll-top="scrollTop"
+				:scrollIntoView="scrollIntoView"
+			>
+				<uMonth
+					:color="color"
+					:rowHeight="rowHeight"
+					:showMark="showMark"
+					:months="months"
+					:mode="mode"
+					:maxCount="maxCount"
+					:startText="startText"
+					:endText="endText"
+					:defaultDate="defaultDate"
+					:minDate="innerMinDate"
+					:maxDate="innerMaxDate"
+					:maxMonth="monthNum"
+					:readonly="readonly"
+					:maxRange="maxRange"
+					:rangePrompt="rangePrompt"
+					:showRangePrompt="showRangePrompt"
+					:allowSameDay="allowSameDay"
+					ref="month"
+					@monthSelected="monthSelected"
+					@updateMonthTop="updateMonthTop"
+				></uMonth>
+			</scroll-view>
+			<slot name="footer" v-if="showConfirm">
+				<view class="u-calendar__confirm">
+					<u-button
+						shape="circle"
+						:text="
+                            buttonDisabled ? confirmDisabledText : confirmText
+                        "
+						:color="color"
+						@click="confirm"
+						:disabled="buttonDisabled"
+					></u-button>
+				</view>
+			</slot>
+		</view>
+	</u-popup>
+</template>
+
+<script>
+import uHeader from './header.vue'
+import uMonth from './month.vue'
+import props from './props.js'
+import util from './util.js'
+import dayjs from '../../libs/util/dayjs.js'
+import Calendar from '../../libs/util/calendar.js'
+/**
+ * Calendar 日历
+ * @description  此组件用于单个选择日期,范围选择日期等,日历被包裹在底部弹起的容器中.
+ * @tutorial https://www.uviewui.com/components/calendar.html
+ *
+ * @property {String}				title				标题内容 (默认 日期选择 )
+ * @property {Boolean}				showTitle			是否显示标题  (默认 true )
+ * @property {Boolean}				showSubtitle		是否显示副标题	(默认 true )
+ * @property {String}				mode				日期类型选择  single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围 ( 默认 'single' )
+ * @property {String}				startText			mode=range时,第一个日期底部的提示文字  (默认 '开始' )
+ * @property {String}				endText				mode=range时,最后一个日期底部的提示文字 (默认 '结束' )
+ * @property {Array}				customList			自定义列表
+ * @property {String}				color				主题色,对底部按钮和选中日期有效  (默认 ‘#3c9cff' )
+ * @property {String | Number}		minDate				最小的可选日期	 (默认 0 )
+ * @property {String | Number}		maxDate				最大可选日期  (默认 0 )
+ * @property {Array | String| Date}	defaultDate			默认选中的日期,mode为multiple或range是必须为数组格式
+ * @property {String | Number}		maxCount			mode=multiple时,最多可选多少个日期  (默认 	Number.MAX_SAFE_INTEGER  )
+ * @property {String | Number}		rowHeight			日期行高 (默认 56 )
+ * @property {Function}				formatter			日期格式化函数
+ * @property {Boolean}				showLunar			是否显示农历  (默认 false )
+ * @property {Boolean}				showMark			是否显示月份背景色 (默认 true )
+ * @property {String}				confirmText			确定按钮的文字 (默认 '确定' )
+ * @property {String}				confirmDisabledText	确认按钮处于禁用状态时的文字 (默认 '确定' )
+ * @property {Boolean}				show				是否显示日历弹窗 (默认 false )
+ * @property {Boolean}				closeOnClickOverlay	是否允许点击遮罩关闭日历 (默认 false )
+ * @property {Boolean}				readonly	        是否为只读状态,只读状态下禁止选择日期 (默认 false )
+ * @property {String | Number}		maxRange	        日期区间最多可选天数,默认无限制,mode = range时有效
+ * @property {String}				rangePrompt	        范围选择超过最多可选天数时的提示文案,mode = range时有效
+ * @property {Boolean}				showRangePrompt	    范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效 (默认 true )
+ * @property {Boolean}				allowSameDay	    是否允许日期范围的起止时间为同一天,mode = range时有效 (默认 false )
+ * @property {Number|String}	    round				圆角值,默认无圆角  (默认 0 )
+ * @property {Number|String}	    monthNum			最多展示的月份数量  (默认 3 )
+ *
+ * @event {Function()} confirm 		点击确定按钮时触发		选择日期相关的返回参数
+ * @event {Function()} close 		日历关闭时触发			可定义页面关闭时的回调事件
+ * @example <u-calendar  :defaultDate="defaultDateMultiple" :show="show" mode="multiple" @confirm="confirm">
+	</u-calendar>
+ * */
+export default {
+	name: 'u-calendar',
+	mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+	components: {
+		uHeader,
+		uMonth
+	},
+	data() {
+		return {
+			// 需要显示的月份的数组
+			months: [],
+			// 在月份滚动区域中,当前视图中月份的index索引
+			monthIndex: 0,
+			// 月份滚动区域的高度
+			listHeight: 0,
+			// month组件中选择的日期数组
+			selected: [],
+			scrollIntoView: '',
+			scrollTop:0,
+			// 过滤处理方法
+			innerFormatter: (value) => value
+		}
+	},
+	watch: {
+		selectedChange: {
+			immediate: true,
+			handler(n) {
+				this.setMonth()
+			}
+		},
+		// 打开弹窗时,设置月份数据
+		show: {
+			immediate: true,
+			handler(n) {
+				this.setMonth()
+			}
+		}
+	},
+	computed: {
+		// 由于maxDate和minDate可以为字符串(2021-10-10),或者数值(时间戳),但是dayjs如果接受字符串形式的时间戳会有问题,这里进行处理
+		innerMaxDate() {
+			return uni.$u.test.number(this.maxDate)
+				? Number(this.maxDate)
+				: this.maxDate
+		},
+		innerMinDate() {
+			return uni.$u.test.number(this.minDate)
+				? Number(this.minDate)
+				: this.minDate
+		},
+		// 多个条件的变化,会引起选中日期的变化,这里统一管理监听
+		selectedChange() {
+			return [this.innerMinDate, this.innerMaxDate, this.defaultDate]
+		},
+		subtitle() {
+			// 初始化时,this.months为空数组,所以需要特别判断处理
+			if (this.months.length) {
+				return `${this.months[this.monthIndex].year}年${
+					this.months[this.monthIndex].month
+				}月`
+			} else {
+				return ''
+			}
+		},
+		buttonDisabled() {
+			// 如果为range类型,且选择的日期个数不足1个时,让底部的按钮出于disabled状态
+			if (this.mode === 'range') {
+				if (this.selected.length <= 1) {
+					return true
+				} else {
+					return false
+				}
+			} else {
+				return false
+			}
+		}
+	},
+	mounted() {
+		this.start = Date.now()
+		this.init()
+	},
+	methods: {
+		// 在微信小程序中,不支持将函数当做props参数,故只能通过ref形式调用
+		setFormatter(e) {
+			this.innerFormatter = e
+		},
+		// month组件内部选择日期后,通过事件通知给父组件
+		monthSelected(e) {
+			this.selected = e
+			if (!this.showConfirm) {
+				// 在不需要确认按钮的情况下,如果为单选,或者范围多选且已选长度大于2,则直接进行返还
+				if (
+					this.mode === 'multiple' ||
+					this.mode === 'single' ||
+					(this.mode === 'range' && this.selected.length >= 2)
+				) {
+					this.$emit('confirm', this.selected)
+				}
+			}
+		},
+		init() {
+			// 校验maxDate,不能小于当前时间
+			if (
+				this.innerMaxDate &&
+				new Date(this.innerMaxDate).getTime() <= Date.now()
+			) {
+				return uni.$u.error('maxDate不能小于当前时间')
+			}
+			// 滚动区域的高度
+			this.listHeight = this.rowHeight * 5 + 30
+			this.setMonth()
+		},
+		close() {
+			this.$emit('close')
+		},
+		// 点击确定按钮
+		confirm() {
+			if (!this.buttonDisabled) {
+				this.$emit('confirm', this.selected)
+			}
+		},
+		// 获得两个日期之间的月份数
+		getMonths(minDate, maxDate) {
+			const minYear = dayjs(minDate).year()
+			const minMonth = dayjs(minDate).month() + 1
+			const maxYear = dayjs(maxDate).year()
+			const maxMonth = dayjs(maxDate).month() + 1
+			return (maxYear - minYear) * 12 + (maxMonth - minMonth) + 1
+		},
+		// 设置月份数据
+		setMonth() {
+			// 最小日期的毫秒数
+			const minDate = this.innerMinDate || dayjs().valueOf()
+			// 如果没有指定最大日期,则往后推3个月
+			const maxDate =
+				this.innerMaxDate ||
+				dayjs(minDate)
+					.add(this.monthNum - 1, 'month')
+					.valueOf()
+			// 最大最小月份之间的共有多少个月份,
+			const months = uni.$u.range(
+				1,
+				this.monthNum,
+				this.getMonths(minDate, maxDate)
+			)
+			// 先清空数组
+			this.months = []
+			for (let i = 0; i < months; i++) {
+				this.months.push({
+					date: new Array(
+						dayjs(minDate).add(i, 'month').daysInMonth()
+					)
+						.fill(1)
+						.map((item, index) => {
+							// 日期,取值1-31
+							let day = index + 1
+							// 星期,0-6,0为周日
+							const week = dayjs(minDate)
+								.add(i, 'month')
+								.date(day)
+								.day()
+							const date = dayjs(minDate)
+								.add(i, 'month')
+								.date(day)
+								.format('YYYY-MM-DD')
+							let bottomInfo = ''
+							if (this.showLunar) {
+								// 将日期转为农历格式
+								const lunar = Calendar.solar2lunar(
+									dayjs(date).year(),
+									dayjs(date).month() + 1,
+									dayjs(date).date()
+								)
+								bottomInfo = lunar.IDayCn
+							}
+							let config = {
+								day,
+								week,
+								// 小于最小允许的日期,或者大于最大的日期,则设置为disabled状态
+								disabled:
+									dayjs(date).isBefore(
+										dayjs(minDate).format('YYYY-MM-DD')
+									) ||
+									dayjs(date).isAfter(
+										dayjs(maxDate).format('YYYY-MM-DD')
+									),
+								// 返回一个日期对象,供外部的formatter获取当前日期的年月日等信息,进行加工处理
+								date: new Date(date),
+								bottomInfo,
+								dot: false,
+								month:
+									dayjs(minDate).add(i, 'month').month() + 1
+							}
+							const formatter =
+								this.formatter || this.innerFormatter
+							return formatter(config)
+						}),
+					// 当前所属的月份
+					month: dayjs(minDate).add(i, 'month').month() + 1,
+					// 当前年份
+					year: dayjs(minDate).add(i, 'month').year()
+				})
+			}
+
+		},
+		// 滚动到默认设置的月份
+		scrollIntoDefaultMonth(selected) {
+			// 查询默认日期在可选列表的下标
+			const _index = this.months.findIndex(({
+				  year,
+				  month
+			  }) => {
+				month = uni.$u.padZero(month)
+				return `${year}-${month}` === selected
+			})
+			if (_index !== -1) {
+				// #ifndef MP-WEIXIN
+				this.$nextTick(() => {
+					this.scrollIntoView = `month-${_index}`
+				})
+				// #endif
+				// #ifdef MP-WEIXIN
+				this.scrollTop = this.months[_index].top || 0;
+				// #endif
+			}
+		},
+		// scroll-view滚动监听
+		onScroll(event) {
+			// 不允许小于0的滚动值,如果scroll-view到顶了,继续下拉,会出现负数值
+			const scrollTop = Math.max(0, event.detail.scrollTop)
+			// 将当前滚动条数值,除以滚动区域的高度,可以得出当前滚动到了哪一个月份的索引
+			for (let i = 0; i < this.months.length; i++) {
+				if (scrollTop >= (this.months[i].top || this.listHeight)) {
+					this.monthIndex = i
+				}
+			}
+		},
+		// 更新月份的top值
+		updateMonthTop(topArr = []) {
+			// 设置对应月份的top值,用于onScroll方法更新月份
+			topArr.map((item, index) => {
+				this.months[index].top = item
+			})
+
+			// 获取默认日期的下标
+			if (!this.defaultDate) {
+				// 如果没有设置默认日期,则将当天日期设置为默认选中的日期
+				const selected = dayjs().format("YYYY-MM")
+				this.scrollIntoDefaultMonth(selected)
+				return
+			}
+			let selected = dayjs().format("YYYY-MM");
+			// 单选模式,可以是字符串或数组,Date对象等
+			if (!uni.$u.test.array(this.defaultDate)) {
+				selected = dayjs(this.defaultDate).format("YYYY-MM")
+			} else {
+				selected = dayjs(this.defaultDate[0]).format("YYYY-MM");
+			}
+			this.scrollIntoDefaultMonth(selected)
+		}
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../libs/css/components.scss';
+
+.u-calendar {
+	&__confirm {
+		padding: 7px 18px;
+	}
+}
+</style>

+ 85 - 0
node_modules/uview-ui/components/u-calendar/util.js

xqd
@@ -0,0 +1,85 @@
+export default {
+    methods: {
+        // 设置月份数据
+        setMonth() {
+            // 月初是周几
+            const day = dayjs(this.date).date(1).day()
+            const start = day == 0 ? 6 : day - 1
+
+            // 本月天数
+            const days = dayjs(this.date).endOf('month').format('D')
+
+            // 上个月天数
+            const prevDays = dayjs(this.date).endOf('month').subtract(1, 'month').format('D')
+
+            // 日期数据
+            const arr = []
+            // 清空表格
+            this.month = []
+
+            // 添加上月数据
+            arr.push(
+                ...new Array(start).fill(1).map((e, i) => {
+                    const day = prevDays - start + i + 1
+
+                    return {
+                        value: day,
+                        disabled: true,
+                        date: dayjs(this.date).subtract(1, 'month').date(day).format('YYYY-MM-DD')
+                    }
+                })
+            )
+
+            // 添加本月数据
+            arr.push(
+                ...new Array(days - 0).fill(1).map((e, i) => {
+                    const day = i + 1
+
+                    return {
+                        value: day,
+                        date: dayjs(this.date).date(day).format('YYYY-MM-DD')
+                    }
+                })
+            )
+
+            // 添加下个月
+            arr.push(
+                ...new Array(42 - days - start).fill(1).map((e, i) => {
+                    const day = i + 1
+
+                    return {
+                        value: day,
+                        disabled: true,
+                        date: dayjs(this.date).add(1, 'month').date(day).format('YYYY-MM-DD')
+                    }
+                })
+            )
+
+            // 分割数组
+            for (let n = 0; n < arr.length; n += 7) {
+                this.month.push(
+                    arr.slice(n, n + 7).map((e, i) => {
+                        e.index = i + n
+
+                        // 自定义信息
+                        const custom = this.customList.find((c) => c.date == e.date)
+
+                        // 农历
+                        if (this.lunar) {
+                            const {
+                                IDayCn,
+                                IMonthCn
+                            } = this.getLunar(e.date)
+                            e.lunar = IDayCn == '初一' ? IMonthCn : IDayCn
+                        }
+
+                        return {
+                            ...e,
+                            ...custom
+                        }
+                    })
+                )
+            }
+        }
+    }
+}

+ 14 - 0
node_modules/uview-ui/components/u-car-keyboard/props.js

xqd
@@ -0,0 +1,14 @@
+export default {
+    props: {
+        // 是否打乱键盘按键的顺序
+        random: {
+            type: Boolean,
+            default: false
+        },
+        // 输入一个中文后,是否自动切换到英文
+        autoChange: {
+            type: Boolean,
+            default: false
+        }
+    }
+}

+ 311 - 0
node_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue

xqd
@@ -0,0 +1,311 @@
+<template>
+	<view
+		class="u-keyboard"
+		@touchmove.stop.prevent="noop"
+	>
+		<view
+			v-for="(group, i) in abc ? engKeyBoardList : areaList"
+			:key="i"
+			class="u-keyboard__button"
+			:index="i"
+			:class="[i + 1 === 4 && 'u-keyboard__button--center']"
+		>
+			<view
+				v-if="i === 3"
+				class="u-keyboard__button__inner-wrapper"
+			>
+				<view
+					class="u-keyboard__button__inner-wrapper__left"
+					hover-class="u-hover-class"
+					:hover-stay-time="200"
+					@tap="changeCarInputMode"
+				>
+					<text
+						class="u-keyboard__button__inner-wrapper__left__lang"
+						:class="[!abc && 'u-keyboard__button__inner-wrapper__left__lang--active']"
+					>中</text>
+					<text class="u-keyboard__button__inner-wrapper__left__line">/</text>
+					<text
+						class="u-keyboard__button__inner-wrapper__left__lang"
+						:class="[abc && 'u-keyboard__button__inner-wrapper__left__lang--active']"
+					>英</text>
+				</view>
+			</view>
+			<view
+				class="u-keyboard__button__inner-wrapper"
+				v-for="(item, j) in group"
+				:key="j"
+			>
+				<view
+					class="u-keyboard__button__inner-wrapper__inner"
+					:hover-stay-time="200"
+					@tap="carInputClick(i, j)"
+					hover-class="u-hover-class"
+				>
+					<text class="u-keyboard__button__inner-wrapper__inner__text">{{ item }}</text>
+				</view>
+			</view>
+			<view
+				v-if="i === 3"
+				@touchstart="backspaceClick"
+				@touchend="clearTimer"
+				class="u-keyboard__button__inner-wrapper"
+			>
+				<view
+					class="u-keyboard__button__inner-wrapper__right"
+					hover-class="u-hover-class"
+					:hover-stay-time="200"
+				>
+					<u-icon
+						size="28"
+						name="backspace"
+						color="#303133"
+					></u-icon>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * keyboard 键盘组件
+	 * @description 此为uView自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3种模式,都有可以打乱按键顺序的选项。
+	 * @tutorial https://uviewui.com/components/keyboard.html
+	 * @property {Boolean} random 是否打乱键盘的顺序
+	 * @event {Function} change 点击键盘触发
+	 * @event {Function} backspace 点击退格键触发
+	 * @example <u-keyboard ref="uKeyboard" mode="car" v-model="show"></u-keyboard>
+	 */
+	export default {
+		name: "u-keyboard",
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		data() {
+			return {
+				// 车牌输入时,abc=true为输入车牌号码,bac=false为输入省份中文简称
+				abc: false
+			};
+		},
+		computed: {
+			areaList() {
+				let data = [
+					'京',
+					'沪',
+					'粤',
+					'津',
+					'冀',
+					'豫',
+					'云',
+					'辽',
+					'黑',
+					'湘',
+					'皖',
+					'鲁',
+					'苏',
+					'浙',
+					'赣',
+					'鄂',
+					'桂',
+					'甘',
+					'晋',
+					'陕',
+					'蒙',
+					'吉',
+					'闽',
+					'贵',
+					'渝',
+					'川',
+					'青',
+					'琼',
+					'宁',
+					'挂',
+					'藏',
+					'港',
+					'澳',
+					'新',
+					'使',
+					'学'
+				];
+				let tmp = [];
+				// 打乱顺序
+				if (this.random) data = uni.$u.randomArray(data);
+				// 切割成二维数组
+				tmp[0] = data.slice(0, 10);
+				tmp[1] = data.slice(10, 20);
+				tmp[2] = data.slice(20, 30);
+				tmp[3] = data.slice(30, 36);
+				return tmp;
+			},
+			engKeyBoardList() {
+				let data = [
+					1,
+					2,
+					3,
+					4,
+					5,
+					6,
+					7,
+					8,
+					9,
+					0,
+					'Q',
+					'W',
+					'E',
+					'R',
+					'T',
+					'Y',
+					'U',
+					'I',
+					'O',
+					'P',
+					'A',
+					'S',
+					'D',
+					'F',
+					'G',
+					'H',
+					'J',
+					'K',
+					'L',
+					'Z',
+					'X',
+					'C',
+					'V',
+					'B',
+					'N',
+					'M'
+				];
+				let tmp = [];
+				if (this.random) data = uni.$u.randomArray(data);
+				tmp[0] = data.slice(0, 10);
+				tmp[1] = data.slice(10, 20);
+				tmp[2] = data.slice(20, 30);
+				tmp[3] = data.slice(30, 36);
+				return tmp;
+			}
+		},
+		methods: {
+			// 点击键盘按钮
+			carInputClick(i, j) {
+				let value = '';
+				// 不同模式,获取不同数组的值
+				if (this.abc) value = this.engKeyBoardList[i][j];
+				else value = this.areaList[i][j];
+				// 如果允许自动切换,则将中文状态切换为英文
+				if (!this.abc && this.autoChange) uni.$u.sleep(200).then(() => this.abc = true)
+				this.$emit('change', value);
+			},
+			// 修改汽车牌键盘的输入模式,中文|英文
+			changeCarInputMode() {
+				this.abc = !this.abc;
+			},
+			// 点击退格键
+			backspaceClick() {
+				this.$emit('backspace');
+				clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
+				this.timer = null;
+				this.timer = setInterval(() => {
+					this.$emit('backspace');
+				}, 250);
+			},
+			clearTimer() {
+				clearInterval(this.timer);
+				this.timer = null;
+			},
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+	$u-car-keyboard-background-color: rgb(224, 228, 230) !default;
+	$u-car-keyboard-padding:6px 0 6px !default;
+	$u-car-keyboard-button-inner-width:64rpx !default;
+	$u-car-keyboard-button-inner-background-color:#FFFFFF !default;
+	$u-car-keyboard-button-height:80rpx !default;
+	$u-car-keyboard-button-inner-box-shadow:0 1px 0px #999992 !default;
+	$u-car-keyboard-button-border-radius:4px !default;
+	$u-car-keyboard-button-inner-margin:8rpx 5rpx !default;
+	$u-car-keyboard-button-text-font-size:16px !default;
+	$u-car-keyboard-button-text-color:$u-main-color !default;
+	$u-car-keyboard-center-inner-margin: 0 4rpx !default;
+	$u-car-keyboard-special-button-width:134rpx !default;
+	$u-car-keyboard-lang-font-size:16px !default;
+	$u-car-keyboard-lang-color:$u-main-color !default;
+	$u-car-keyboard-active-color:$u-primary !default;
+	$u-car-keyboard-line-font-size:15px !default;
+	$u-car-keyboard-line-color:$u-main-color !default;
+	$u-car-keyboard-line-margin:0 1px !default;
+	$u-car-keyboard-u-hover-class-background-color:#BBBCC6 !default;
+
+	.u-keyboard {
+		@include flex(column);
+		justify-content: space-around;
+		background-color: $u-car-keyboard-background-color;
+		align-items: stretch;
+		padding: $u-car-keyboard-padding;
+
+		&__button {
+			@include flex;
+			justify-content: center;
+			flex: 1;
+			/* #ifndef APP-NVUE */
+			/* #endif */
+
+			&__inner-wrapper {
+				box-shadow: $u-car-keyboard-button-inner-box-shadow;
+				margin: $u-car-keyboard-button-inner-margin;
+				border-radius: $u-car-keyboard-button-border-radius;
+
+				&__inner {
+					@include flex;
+					justify-content: center;
+					align-items: center;
+					width: $u-car-keyboard-button-inner-width;
+					background-color: $u-car-keyboard-button-inner-background-color;
+					height: $u-car-keyboard-button-height;
+					border-radius: $u-car-keyboard-button-border-radius;
+
+					&__text {
+						font-size: $u-car-keyboard-button-text-font-size;
+						color: $u-car-keyboard-button-text-color;
+					}
+				}
+
+				&__left,
+				&__right {
+					border-radius: $u-car-keyboard-button-border-radius;
+					width: $u-car-keyboard-special-button-width;
+					height: $u-car-keyboard-button-height;
+					background-color: $u-car-keyboard-u-hover-class-background-color;
+					@include flex;
+					justify-content: center;
+					align-items: center;
+					box-shadow: $u-car-keyboard-button-inner-box-shadow;
+				}
+
+				&__left {
+					&__line {
+						font-size: $u-car-keyboard-line-font-size;
+						color: $u-car-keyboard-line-color;
+						margin: $u-car-keyboard-line-margin;
+					}
+
+					&__lang {
+						font-size: $u-car-keyboard-lang-font-size;
+						color: $u-car-keyboard-lang-color;
+
+						&--active {
+							color: $u-car-keyboard-active-color;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	.u-hover-class {
+		background-color: $u-car-keyboard-u-hover-class-background-color;
+	}
+</style>

+ 14 - 0
node_modules/uview-ui/components/u-cell-group/props.js

xqd
@@ -0,0 +1,14 @@
+export default {
+    props: {
+        // 分组标题
+        title: {
+            type: String,
+            default: uni.$u.props.cellGroup.title
+        },
+        // 是否显示外边框
+        border: {
+            type: Boolean,
+            default: uni.$u.props.cellGroup.border
+        }
+    }
+}

+ 61 - 0
node_modules/uview-ui/components/u-cell-group/u-cell-group.vue

xqd
@@ -0,0 +1,61 @@
+<template>
+    <view :style="[$u.addStyle(customStyle)]" :class="[customClass]" class="u-cell-group">
+        <view v-if="title" class="u-cell-group__title">
+            <slot name="title">
+				<text class="u-cell-group__title__text">{{ title }}</text>
+			</slot>
+        </view>
+        <view class="u-cell-group__wrapper">
+			<u-line v-if="border"></u-line>
+            <slot />
+        </view>
+    </view>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * cellGroup  单元格
+	 * @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。
+	 * @tutorial https://uviewui.com/components/cell.html
+	 * 
+	 * @property {String}	title		分组标题
+	 * @property {Boolean}	border		是否显示外边框 (默认 true )
+	 * @property {Object}	customStyle	定义需要用到的外部样式
+	 * 
+	 * @event {Function} click 	点击cell列表时触发
+	 * @example <u-cell-group title="设置喜好">
+	 */
+	export default {
+		name: 'u-cell-group',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+	
+	$u-cell-group-title-padding: 16px 16px 8px !default;
+	$u-cell-group-title-font-size: 15px !default;
+	$u-cell-group-title-line-height: 16px !default;
+	$u-cell-group-title-color: $u-main-color !default;
+
+    .u-cell-group {
+		flex: 1;
+		
+        &__title {
+            padding: $u-cell-group-title-padding;
+
+            &__text {
+                font-size: $u-cell-group-title-font-size;
+                line-height: $u-cell-group-title-line-height;
+                color: $u-cell-group-title-color;
+            }
+        }
+		
+		&__wrapper {
+			position: relative;
+		}
+    }
+</style>
+

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

xqd
@@ -0,0 +1,110 @@
+export default {
+    props: {
+        // 标题
+        title: {
+            type: [String, Number],
+            default: uni.$u.props.cell.title
+        },
+        // 标题下方的描述信息
+        label: {
+            type: [String, Number],
+            default: uni.$u.props.cell.label
+        },
+        // 右侧的内容
+        value: {
+            type: [String, Number],
+            default: uni.$u.props.cell.value
+        },
+        // 左侧图标名称,或者图片链接(本地文件建议使用绝对地址)
+        icon: {
+            type: String,
+            default: uni.$u.props.cell.icon
+        },
+        // 是否禁用cell
+        disabled: {
+            type: Boolean,
+            default: uni.$u.props.cell.disabled
+        },
+        // 是否显示下边框
+        border: {
+            type: Boolean,
+            default: uni.$u.props.cell.border
+        },
+        // 内容是否垂直居中(主要是针对右侧的value部分)
+        center: {
+            type: Boolean,
+            default: uni.$u.props.cell.center
+        },
+        // 点击后跳转的URL地址
+        url: {
+            type: String,
+            default: uni.$u.props.cell.url
+        },
+        // 链接跳转的方式,内部使用的是uView封装的route方法,可能会进行拦截操作
+        linkType: {
+            type: String,
+            default: uni.$u.props.cell.linkType
+        },
+        // 是否开启点击反馈(表现为点击时加上灰色背景)
+        clickable: {
+            type: Boolean,
+            default: uni.$u.props.cell.clickable
+        },
+        // 是否展示右侧箭头并开启点击反馈
+        isLink: {
+            type: Boolean,
+            default: uni.$u.props.cell.isLink
+        },
+        // 是否显示表单状态下的必填星号(此组件可能会内嵌入input组件)
+        required: {
+            type: Boolean,
+            default: uni.$u.props.cell.required
+        },
+        // 右侧的图标箭头
+        rightIcon: {
+            type: String,
+            default: uni.$u.props.cell.rightIcon
+        },
+        // 右侧箭头的方向,可选值为:left,up,down
+        arrowDirection: {
+            type: String,
+            default: uni.$u.props.cell.arrowDirection
+        },
+        // 左侧图标样式
+        iconStyle: {
+            type: [Object, String],
+            default: () => {
+				return uni.$u.props.cell.iconStyle
+			}
+        },
+        // 右侧箭头图标的样式
+        rightIconStyle: {
+            type: [Object, String],
+            default: () => {
+				return uni.$u.props.cell.rightIconStyle
+			}
+        },
+        // 标题的样式
+        titleStyle: {
+            type: [Object, String],
+			default: () => {
+				return uni.$u.props.cell.titleStyle
+			}
+        },
+        // 单位元的大小,可选值为large
+        size: {
+            type: String,
+            default: uni.$u.props.cell.size
+        },
+        // 点击cell是否阻止事件传播
+        stop: {
+            type: Boolean,
+            default: uni.$u.props.cell.stop
+        },
+        // 标识符,cell被点击时返回
+        name: {
+            type: [Number, String],
+            default: uni.$u.props.cell.name
+        }
+    }
+}

+ 229 - 0
node_modules/uview-ui/components/u-cell/u-cell.vue

xqd
@@ -0,0 +1,229 @@
+<template>
+	<view class="u-cell" :class="[customClass]" :style="[$u.addStyle(customStyle)]"
+		:hover-class="(!disabled && (clickable || isLink)) ? 'u-cell--clickable' : ''" :hover-stay-time="250"
+		@tap="clickHandler">
+		<view class="u-cell__body" :class="[ center && 'u-cell--center', size === 'large' && 'u-cell__body--large']">
+			<view class="u-cell__body__content">
+				<view class="u-cell__left-icon-wrap" v-if="$slots.icon || icon">
+					<slot name="icon" v-if="$slots.icon">
+					</slot>
+					<u-icon v-else :name="icon" :custom-style="iconStyle" :size="size === 'large' ? 22 : 18"></u-icon>
+				</view>
+				<view class="u-cell__title">
+					<slot name="title">
+						<text v-if="title" class="u-cell__title-text" :style="[titleTextStyle]"
+							:class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__title-text--large']">{{ title }}</text>
+					</slot>
+					<slot name="label">
+						<text class="u-cell__label" v-if="label"
+							:class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__label--large']">{{ label }}</text>
+					</slot>
+				</view>
+			</view>
+			<slot name="value">
+				<text class="u-cell__value"
+					:class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__value--large']"
+					v-if="!$u.test.empty(value)">{{ value }}</text>
+			</slot>
+			<view class="u-cell__right-icon-wrap" v-if="$slots['right-icon'] || isLink"
+				:class="[`u-cell__right-icon-wrap--${arrowDirection}`]">
+				<slot name="right-icon" v-if="$slots['right-icon']">
+				</slot>
+				<u-icon v-else :name="rightIcon" :custom-style="rightIconStyle" :color="disabled ? '#c8c9cc' : 'info'"
+					:size="size === 'large' ? 18 : 16"></u-icon>
+			</view>
+		</view>
+		<u-line v-if="border"></u-line>
+	</view>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * cell  单元格
+	 * @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。
+	 * @tutorial https://uviewui.com/components/cell.html
+	 * @property {String | Number}	title			标题
+	 * @property {String | Number}	label			标题下方的描述信息
+	 * @property {String | Number}	value			右侧的内容
+	 * @property {String}			icon			左侧图标名称,或者图片链接(本地文件建议使用绝对地址)
+	 * @property {Boolean}			disabled		是否禁用cell	
+	 * @property {Boolean}			border			是否显示下边框 (默认 true )
+	 * @property {Boolean}			center			内容是否垂直居中(主要是针对右侧的value部分) (默认 false )
+	 * @property {String}			url				点击后跳转的URL地址
+	 * @property {String}			linkType		链接跳转的方式,内部使用的是uView封装的route方法,可能会进行拦截操作 (默认 'navigateTo' )
+	 * @property {Boolean}			clickable		是否开启点击反馈(表现为点击时加上灰色背景) (默认 false ) 
+	 * @property {Boolean}			isLink			是否展示右侧箭头并开启点击反馈 (默认 false )
+	 * @property {Boolean}			required		是否显示表单状态下的必填星号(此组件可能会内嵌入input组件) (默认 false )
+	 * @property {String}			rightIcon		右侧的图标箭头 (默认 'arrow-right')
+	 * @property {String}			arrowDirection	右侧箭头的方向,可选值为:left,up,down
+	 * @property {Object | String}			rightIconStyle	右侧箭头图标的样式
+	 * @property {Object | String}			titleStyle		标题的样式
+	 * @property {Object | String}			iconStyle		左侧图标样式
+	 * @property {String}			size			单位元的大小,可选值为 large,normal,mini 
+	 * @property {Boolean}			stop			点击cell是否阻止事件传播 (默认 true )
+	 * @property {Object}			customStyle		定义需要用到的外部样式
+	 * 
+	 * @event {Function}			click			点击cell列表时触发
+	 * @example 该组件需要搭配cell-group组件使用,见官方文档示例
+	 */
+	export default {
+		name: 'u-cell',
+		data() {
+			return {
+
+			}
+		},
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		computed: {
+			titleTextStyle() {
+				return uni.$u.addStyle(this.titleStyle)
+			}
+		},
+		methods: {
+			// 点击cell
+			clickHandler(e) {
+				if (this.disabled) return
+				this.$emit('click', {
+					name: this.name
+				})
+				// 如果配置了url(此props参数通过mixin引入)参数,跳转页面
+				this.openPage()
+				// 是否阻止事件传播
+				this.stop && this.preventEvent(e)
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+
+	$u-cell-padding: 10px 15px !default;
+	$u-cell-font-size: 15px !default;
+	$u-cell-line-height: 24px !default;
+	$u-cell-color: $u-main-color !default;
+	$u-cell-icon-size: 16px !default;
+	$u-cell-title-font-size: 15px !default;
+	$u-cell-title-line-height: 22px !default;
+	$u-cell-title-color: $u-main-color !default;
+	$u-cell-label-font-size: 12px !default;
+	$u-cell-label-color: $u-tips-color !default;
+	$u-cell-label-line-height: 18px !default;
+	$u-cell-value-font-size: 14px !default;
+	$u-cell-value-color: $u-content-color !default;
+	$u-cell-clickable-color: $u-bg-color !default;
+	$u-cell-disabled-color: #c8c9cc !default;
+	$u-cell-padding-top-large: 13px !default;
+	$u-cell-padding-bottom-large: 13px !default;
+	$u-cell-value-font-size-large: 15px !default;
+	$u-cell-label-font-size-large: 14px !default;
+	$u-cell-title-font-size-large: 16px !default;
+	$u-cell-left-icon-wrap-margin-right: 4px !default;
+	$u-cell-right-icon-wrap-margin-left: 4px !default;
+	$u-cell-title-flex:1 !default;
+	$u-cell-label-margin-top:5px !default;
+
+
+	.u-cell {
+		&__body {
+			@include flex();
+			/* #ifndef APP-NVUE */
+			box-sizing: border-box;
+			/* #endif */
+			padding: $u-cell-padding;
+			font-size: $u-cell-font-size;
+			color: $u-cell-color;
+			// line-height: $u-cell-line-height;
+			align-items: center;
+
+			&__content {
+				@include flex(row);
+				align-items: center;
+				flex: 1;
+			}
+
+			&--large {
+				padding-top: $u-cell-padding-top-large;
+				padding-bottom: $u-cell-padding-bottom-large;
+			}
+		}
+
+		&__left-icon-wrap,
+		&__right-icon-wrap {
+			@include flex();
+			align-items: center;
+			// height: $u-cell-line-height;
+			font-size: $u-cell-icon-size;
+		}
+
+		&__left-icon-wrap {
+			margin-right: $u-cell-left-icon-wrap-margin-right;
+		}
+
+		&__right-icon-wrap {
+			margin-left: $u-cell-right-icon-wrap-margin-left;
+			transition: transform 0.3s;
+
+			&--up {
+				transform: rotate(-90deg);
+			}
+
+			&--down {
+				transform: rotate(90deg);
+			}
+		}
+
+		&__title {
+			flex: $u-cell-title-flex;
+
+			&-text {
+				font-size: $u-cell-title-font-size;
+				line-height: $u-cell-title-line-height;
+				color: $u-cell-title-color;
+
+				&--large {
+					font-size: $u-cell-title-font-size-large;
+				}
+			}
+
+		}
+
+		&__label {
+			margin-top: $u-cell-label-margin-top;
+			font-size: $u-cell-label-font-size;
+			color: $u-cell-label-color;
+			line-height: $u-cell-label-line-height;
+
+			&--large {
+				font-size: $u-cell-label-font-size-large;
+			}
+		}
+
+		&__value {
+			text-align: right;
+			font-size: $u-cell-value-font-size;
+			line-height: $u-cell-line-height;
+			color: $u-cell-value-color;
+
+			&--large {
+				font-size: $u-cell-value-font-size-large;
+			}
+		}
+
+		&--clickable {
+			background-color: $u-cell-clickable-color;
+		}
+
+		&--disabled {
+			color: $u-cell-disabled-color;
+			/* #ifndef APP-NVUE */
+			cursor: not-allowed;
+			/* #endif */
+		}
+
+		&--center {
+			align-items: center;
+		}
+	}
+</style>

+ 82 - 0
node_modules/uview-ui/components/u-checkbox-group/props.js

xqd
@@ -0,0 +1,82 @@
+export default {
+    props: {
+        // 标识符
+        name: {
+            type: String,
+            default: uni.$u.props.checkboxGroup.name
+        },
+        // 绑定的值
+        value: {
+            type: Array,
+            default: uni.$u.props.checkboxGroup.value
+        },
+        // 形状,circle-圆形,square-方形
+        shape: {
+            type: String,
+            default: uni.$u.props.checkboxGroup.shape
+        },
+        // 是否禁用全部checkbox
+        disabled: {
+            type: Boolean,
+            default: uni.$u.props.checkboxGroup.disabled
+        },
+
+        // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
+        activeColor: {
+            type: String,
+            default: uni.$u.props.checkboxGroup.activeColor
+        },
+        // 未选中的颜色
+        inactiveColor: {
+            type: String,
+            default: uni.$u.props.checkboxGroup.inactiveColor
+        },
+
+        // 整个组件的尺寸,默认px
+        size: {
+            type: [String, Number],
+            default: uni.$u.props.checkboxGroup.size
+        },
+        // 布局方式,row-横向,column-纵向
+        placement: {
+            type: String,
+            default: uni.$u.props.checkboxGroup.placement
+        },
+        // label的字体大小,px单位
+        labelSize: {
+            type: [String, Number],
+            default: uni.$u.props.checkboxGroup.labelSize
+        },
+        // label的字体颜色
+        labelColor: {
+            type: [String],
+            default: uni.$u.props.checkboxGroup.labelColor
+        },
+        // 是否禁止点击文本操作
+        labelDisabled: {
+            type: Boolean,
+            default: uni.$u.props.checkboxGroup.labelDisabled
+        },
+        // 图标颜色
+        iconColor: {
+            type: String,
+            default: uni.$u.props.checkboxGroup.iconColor
+        },
+        // 图标的大小,单位px
+        iconSize: {
+            type: [String, Number],
+            default: uni.$u.props.checkboxGroup.iconSize
+        },
+        // 勾选图标的对齐方式,left-左边,right-右边
+        iconPlacement: {
+            type: String,
+            default: uni.$u.props.checkboxGroup.iconPlacement
+        },
+        // 竖向配列时,是否显示下划线
+        borderBottom: {
+            type: Boolean,
+            default: uni.$u.props.checkboxGroup.borderBottom
+        }
+
+    }
+}

+ 103 - 0
node_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue

xqd
@@ -0,0 +1,103 @@
+<template>
+	<view
+	    class="u-checkbox-group"
+	    :class="bemClass"
+	>
+		<slot></slot>
+	</view>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * checkboxGroup 复选框组
+	 * @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
+	 * @tutorial https://www.uviewui.com/components/checkbox.html
+	 * @property {String}			name			标识符 
+	 * @property {Array}			value			绑定的值
+	 * @property {String}			shape			形状,circle-圆形,square-方形 (默认 'square' )
+	 * @property {Boolean}			disabled		是否禁用全部checkbox (默认 false )
+	 * @property {String}			activeColor		选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 (默认 '#2979ff' )
+	 * @property {String}			inactiveColor	未选中的颜色 (默认 '#c8c9cc' )
+	 * @property {String | Number}	size			整个组件的尺寸 单位px (默认 18 )
+	 * @property {String}			placement		布局方式,row-横向,column-纵向 (默认 'row' )
+	 * @property {String | Number}	labelSize		label的字体大小,px单位  (默认 14 )
+	 * @property {String}			labelColor		label的字体颜色 (默认 '#303133' )
+	 * @property {Boolean}			labelDisabled	是否禁止点击文本操作 (默认 false )
+	 * @property {String}			iconColor		图标颜色 (默认 '#ffffff' )
+	 * @property {String | Number}	iconSize		图标的大小,单位px (默认 12 )
+	 * @property {String}			iconPlacement	勾选图标的对齐方式,left-左边,right-右边  (默认 'left' )
+	 * @property {Boolean}			borderBottom	placement为row时,是否显示下边框 (默认 false )
+	 * @event {Function}	change	任一个checkbox状态发生变化时触发,回调为一个对象
+	 * @event {Function}	input	修改通过v-model绑定的值时触发,回调为一个对象
+	 * @example <u-checkbox-group></u-checkbox-group>
+	 */
+	export default {
+		name: 'u-checkbox-group',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+		computed: {
+			// 这里computed的变量,都是子组件u-checkbox需要用到的,由于头条小程序的兼容性差异,子组件无法实时监听父组件参数的变化
+			// 所以需要手动通知子组件,这里返回一个parentData变量,供watch监听,在其中去通知每一个子组件重新从父组件(u-checkbox-group)
+			// 拉取父组件新的变化后的参数
+			parentData() {
+				return [this.value, this.disabled, this.inactiveColor, this.activeColor, this.size, this.labelDisabled, this.shape,
+					this.iconSize, this.borderBottom, this.placement
+				]
+			},
+			bemClass() {
+				// this.bem为一个computed变量,在mixin中
+				return this.bem('checkbox-group', ['placement'])
+			},
+		},
+		watch: {
+			// 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件
+			parentData() {
+				if (this.children.length) {
+					this.children.map(child => {
+						// 判断子组件(u-checkbox)如果有init方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
+						typeof(child.init) === 'function' && child.init()
+					})
+				}
+			},
+		},
+		data() {
+			return {
+
+			}
+		},
+		created() {
+			this.children = []
+		},
+		methods: {
+			// 将其他的checkbox设置为未选中的状态
+			unCheckedOther(childInstance) {
+				const values = []
+				this.children.map(child => {
+					// 将被选中的checkbox,放到数组中返回
+					if (child.isChecked) {
+						values.push(child.name)
+					}
+				})
+				// 发出事件
+				this.$emit('change', values)
+				// 修改通过v-model绑定的值
+				this.$emit('input', values)
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+
+	.u-checkbox-group {
+
+		&--row {
+			@include flex;
+		}
+
+		&--column {
+			@include flex(column);
+		}
+	}
+</style>

+ 69 - 0
node_modules/uview-ui/components/u-checkbox/props.js

xqd
@@ -0,0 +1,69 @@
+export default {
+    props: {
+        // checkbox的名称
+        name: {
+            type: [String, Number, Boolean],
+            default: uni.$u.props.checkbox.name
+        },
+        // 形状,square为方形,circle为圆型
+        shape: {
+            type: String,
+            default: uni.$u.props.checkbox.shape
+        },
+        // 整体的大小
+        size: {
+            type: [String, Number],
+            default: uni.$u.props.checkbox.size
+        },
+        // 是否默认选中
+        checked: {
+            type: Boolean,
+            default: uni.$u.props.checkbox.checked
+        },
+        // 是否禁用
+        disabled: {
+            type: [String, Boolean],
+            default: uni.$u.props.checkbox.disabled
+        },
+        // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
+        activeColor: {
+            type: String,
+            default: uni.$u.props.checkbox.activeColor
+        },
+        // 未选中的颜色
+        inactiveColor: {
+            type: String,
+            default: uni.$u.props.checkbox.inactiveColor
+        },
+        // 图标的大小,单位px
+        iconSize: {
+            type: [String, Number],
+            default: uni.$u.props.checkbox.iconSize
+        },
+        // 图标颜色
+        iconColor: {
+            type: String,
+            default: uni.$u.props.checkbox.iconColor
+        },
+        // label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式
+        label: {
+            type: [String, Number],
+            default: uni.$u.props.checkbox.label
+        },
+        // label的字体大小,px单位
+        labelSize: {
+            type: [String, Number],
+            default: uni.$u.props.checkbox.labelSize
+        },
+        // label的颜色
+        labelColor: {
+            type: String,
+            default: uni.$u.props.checkbox.labelColor
+        },
+        // 是否禁止点击提示语选中复选框
+        labelDisabled: {
+            type: [String, Boolean],
+            default: uni.$u.props.checkbox.labelDisabled
+        }
+    }
+}

+ 344 - 0
node_modules/uview-ui/components/u-checkbox/u-checkbox.vue

xqd
@@ -0,0 +1,344 @@
+<template>
+	<view
+	    class="u-checkbox"
+	    :style="[checkboxStyle]"
+	    @tap.stop="wrapperClickHandler"
+	    :class="[`u-checkbox-label--${parentData.iconPlacement}`, parentData.borderBottom && parentData.placement === 'column' && 'u-border-bottom']"
+	>
+		<view
+		    class="u-checkbox__icon-wrap"
+		    @tap.stop="iconClickHandler"
+		    :class="iconClasses"
+		    :style="[iconWrapStyle]"
+		>
+			<slot name="icon">
+				<u-icon
+				    class="u-checkbox__icon-wrap__icon"
+				    name="checkbox-mark"
+				    :size="elIconSize"
+				    :color="elIconColor"
+				/>
+			</slot>
+		</view>
+		<text
+		    @tap.stop="labelClickHandler"
+		    :style="{
+				color: elDisabled ? elInactiveColor : elLabelColor,
+				fontSize: elLabelSize,
+				lineHeight: elLabelSize
+			}"
+		>{{label}}</text>
+	</view>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * checkbox  复选框
+	 * @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
+	 * @tutorial https://uviewui.com/components/checkbox.html
+	 * @property {String | Number | Boolean}	name			checkbox组件的标示符
+	 * @property {String}						shape			形状,square为方形,circle为圆型
+	 * @property {String | Number}				size			整体的大小
+	 * @property {Boolean}						checked			是否默认选中
+	 * @property {String | Boolean}				disabled		是否禁用
+	 * @property {String}						activeColor		选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
+	 * @property {String}						inactiveColor	未选中的颜色
+	 * @property {String | Number}				iconSize		图标的大小,单位px
+	 * @property {String}						iconColor		图标颜色
+	 * @property {String | Number}				label			label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式
+	 * @property {String}						labelColor 		label的颜色
+	 * @property {String | Number}				labelSize		label的字体大小,px单位
+	 * @property {String | Boolean}				labelDisabled	是否禁止点击提示语选中复选框
+	 * @property {Object}						customStyle		定义需要用到的外部样式
+	 * 
+	 * @event {Function}	change	任一个checkbox状态发生变化时触发,回调为一个对象
+	 * @example <u-checkbox v-model="checked" :disabled="false">天涯</u-checkbox>
+	 */
+	export default {
+		name: "u-checkbox",
+		mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+		data() {
+			return {
+				isChecked: false,
+				// 父组件的默认值,因为头条小程序不支持在computed中使用this.parent.shape的形式
+				// 故只能使用如此方法
+				parentData: {
+					iconSize: 12,
+					labelDisabled: null,
+					disabled: null,
+					shape: 'square',
+					activeColor: null,
+					inactiveColor: null,
+					size: 18,
+					value: null,
+					iconColor: null,
+					placement: 'row',
+					borderBottom: false,
+					iconPlacement: 'left'
+				}
+			}
+		},
+		computed: {
+			// 是否禁用,如果父组件u-raios-group禁用的话,将会忽略子组件的配置
+			elDisabled() {
+				return this.disabled !== '' ? this.disabled : this.parentData.disabled !== null ? this.parentData.disabled : false;
+			},
+			// 是否禁用label点击
+			elLabelDisabled() {
+				return this.labelDisabled !== '' ? this.labelDisabled : this.parentData.labelDisabled !== null ? this.parentData.labelDisabled :
+					false;
+			},
+			// 组件尺寸,对应size的值,默认值为21px
+			elSize() {
+				return this.size ? this.size : (this.parentData.size ? this.parentData.size : 21);
+			},
+			// 组件的勾选图标的尺寸,默认12px
+			elIconSize() {
+				return this.iconSize ? this.iconSize : (this.parentData.iconSize ? this.parentData.iconSize : 12);
+			},
+			// 组件选中激活时的颜色
+			elActiveColor() {
+				return this.activeColor ? this.activeColor : (this.parentData.activeColor ? this.parentData.activeColor : '#2979ff');
+			},
+			// 组件选未中激活时的颜色
+			elInactiveColor() {
+				return this.inactiveColor ? this.inactiveColor : (this.parentData.inactiveColor ? this.parentData.inactiveColor :
+					'#c8c9cc');
+			},
+			// label的颜色
+			elLabelColor() {
+				return this.labelColor ? this.labelColor : (this.parentData.labelColor ? this.parentData.labelColor : '#606266')
+			},
+			// 组件的形状
+			elShape() {
+				return this.shape ? this.shape : (this.parentData.shape ? this.parentData.shape : 'circle');
+			},
+			// label大小
+			elLabelSize() {
+				return uni.$u.addUnit(this.labelSize ? this.labelSize : (this.parentData.labelSize ? this.parentData.labelSize :
+					'15'))
+			},
+			elIconColor() {
+				const iconColor = this.iconColor ? this.iconColor : (this.parentData.iconColor ? this.parentData.iconColor :
+					'#ffffff');
+				// 图标的颜色
+				if (this.elDisabled) {
+					// disabled状态下,已勾选的checkbox图标改为elInactiveColor
+					return this.isChecked ? this.elInactiveColor : 'transparent'
+				} else {
+					return this.isChecked ? iconColor : 'transparent'
+				}
+			},
+			iconClasses() {
+				let classes = []
+				// 组件的形状
+				classes.push('u-checkbox__icon-wrap--' + this.elShape)
+				if (this.elDisabled) {
+					classes.push('u-checkbox__icon-wrap--disabled')
+				}
+				if (this.isChecked && this.elDisabled) {
+					classes.push('u-checkbox__icon-wrap--disabled--checked')
+				}
+				// 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
+				// #ifdef MP-ALIPAY || MP-TOUTIAO
+				classes = classes.join(' ')
+				// #endif
+				return classes
+			},
+			iconWrapStyle() {
+				// checkbox的整体样式
+				const style = {}
+				style.backgroundColor = this.isChecked && !this.elDisabled ? this.elActiveColor : '#ffffff'
+				style.borderColor = this.isChecked && !this.elDisabled ? this.elActiveColor : this.elInactiveColor
+				style.width = uni.$u.addUnit(this.elSize)
+				style.height = uni.$u.addUnit(this.elSize)
+				// 如果是图标在右边的话,移除它的右边距
+				if (this.parentData.iconPlacement === 'right') {
+					style.marginRight = 0
+				}
+				return style
+			},
+			checkboxStyle() {
+				const style = {}
+				if (this.parentData.borderBottom && this.parentData.placement === 'row') {
+					uni.$u.error('检测到您将borderBottom设置为true,需要同时将u-checkbox-group的placement设置为column才有效')
+				}
+				// 当父组件设置了显示下边框并且排列形式为纵向时,给内容和边框之间加上一定间隔
+				if (this.parentData.borderBottom && this.parentData.placement === 'column') {
+					style.paddingBottom = '8px'
+				}
+				return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+			}
+		},
+		mounted() {
+			this.init()
+		},
+		methods: {
+			init() {
+				// 支付宝小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环引用
+				this.updateParentData()
+				if (!this.parent) {
+					uni.$u.error('u-checkbox必须搭配u-checkbox-group组件使用')
+				}
+				// 设置初始化时,是否默认选中的状态,父组件u-checkbox-group的value可能是array,所以额外判断
+				if (this.checked) {
+					this.isChecked = true
+				} else if (uni.$u.test.array(this.parentData.value)) {
+					// 查找数组是是否存在this.name元素值
+					this.isChecked = this.parentData.value.some(item => {
+						return item === this.name
+					})
+				}
+			},
+			updateParentData() {
+				this.getParentData('u-checkbox-group')
+			},
+			// 横向两端排列时,点击组件即可触发选中事件
+			wrapperClickHandler(e) {
+				this.parentData.iconPlacement === 'right' && this.iconClickHandler(e)
+			},
+			// 点击图标
+			iconClickHandler(e) {
+				this.preventEvent(e)
+				// 如果整体被禁用,不允许被点击
+				if (!this.elDisabled) {
+					this.setRadioCheckedStatus()
+				}
+			},
+			// 点击label
+			labelClickHandler(e) {
+				this.preventEvent(e)
+				// 如果按钮整体被禁用或者label被禁用,则不允许点击文字修改状态
+				if (!this.elLabelDisabled && !this.elDisabled) {
+					this.setRadioCheckedStatus()
+				}
+			},
+			emitEvent() {
+				this.$emit('change', this.isChecked)
+				// 尝试调用u-form的验证方法,进行一定延迟,否则微信小程序更新可能会不及时
+				this.$nextTick(() => {
+					uni.$u.formValidate(this, 'change')
+				})
+			},
+			// 改变组件选中状态
+			// 这里的改变的依据是,更改本组件的checked值为true,同时通过父组件遍历所有u-checkbox实例
+			// 将本组件外的其他u-checkbox的checked都设置为false(都被取消选中状态),因而只剩下一个为选中状态
+			setRadioCheckedStatus() {
+				// 将本组件标记为与原来相反的状态
+				this.isChecked = !this.isChecked
+				this.emitEvent()
+				typeof this.parent.unCheckedOther === 'function' && this.parent.unCheckedOther(this)
+			}
+		},
+		watch:{
+			checked(){
+				this.isChecked = this.checked
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+	$u-checkbox-icon-wrap-margin-right:6px !default;
+	$u-checkbox-icon-wrap-font-size:6px !default;
+	$u-checkbox-icon-wrap-border-width:1px !default;
+	$u-checkbox-icon-wrap-border-color:#c8c9cc !default;
+	$u-checkbox-icon-wrap-icon-line-height:0 !default;
+	$u-checkbox-icon-wrap-circle-border-radius:100% !default;
+	$u-checkbox-icon-wrap-square-border-radius:3px !default;
+	$u-checkbox-icon-wrap-checked-color:#fff !default;
+	$u-checkbox-icon-wrap-checked-background-color:red !default;
+	$u-checkbox-icon-wrap-checked-border-color:#2979ff !default;
+	$u-checkbox-icon-wrap-disabled-background-color:#ebedf0 !default;
+	$u-checkbox-icon-wrap-disabled-checked-color:#c8c9cc !default;
+	$u-checkbox-label-margin-left:5px !default;
+	$u-checkbox-label-margin-right:12px !default;
+	$u-checkbox-label-color:$u-content-color !default;
+	$u-checkbox-label-font-size:15px !default;
+	$u-checkbox-label-disabled-color:#c8c9cc !default;
+
+	.u-checkbox {
+		/* #ifndef APP-NVUE */
+		@include flex(row);
+		/* #endif */
+		overflow: hidden;
+		flex-direction: row;
+		align-items: center;
+
+		&-label--left {
+			flex-direction: row
+		}
+
+		&-label--right {
+			flex-direction: row-reverse;
+			justify-content: space-between
+		}
+
+		&__icon-wrap {
+			/* #ifndef APP-NVUE */
+			box-sizing: border-box;
+			// nvue下,border-color过渡有问题
+			transition-property: border-color, background-color, color;
+			transition-duration: 0.2s;
+			/* #endif */
+			color: $u-content-color;
+			@include flex;
+			align-items: center;
+			justify-content: center;
+			color: transparent;
+			text-align: center;
+			margin-right: $u-checkbox-icon-wrap-margin-right;
+
+			font-size: $u-checkbox-icon-wrap-font-size;
+			border-width: $u-checkbox-icon-wrap-border-width;
+			border-color: $u-checkbox-icon-wrap-border-color;
+			border-style: solid;
+
+			/* #ifdef MP-TOUTIAO */
+			// 头条小程序兼容性问题,需要设置行高为0,否则图标偏下
+			&__icon {
+				line-height: $u-checkbox-icon-wrap-icon-line-height;
+			}
+
+			/* #endif */
+
+			&--circle {
+				border-radius: $u-checkbox-icon-wrap-circle-border-radius;
+			}
+
+			&--square {
+				border-radius: $u-checkbox-icon-wrap-square-border-radius;
+			}
+
+			&--checked {
+				color: $u-checkbox-icon-wrap-checked-color;
+				background-color: $u-checkbox-icon-wrap-checked-background-color;
+				border-color: $u-checkbox-icon-wrap-checked-border-color;
+			}
+
+			&--disabled {
+				background-color: $u-checkbox-icon-wrap-disabled-background-color !important;
+			}
+
+			&--disabled--checked {
+				color: $u-checkbox-icon-wrap-disabled-checked-color !important;
+			}
+		}
+
+		&__label {
+			/* #ifndef APP-NVUE */
+			word-wrap: break-word;
+			/* #endif */
+			margin-left: $u-checkbox-label-margin-left;
+			margin-right: $u-checkbox-label-margin-right;
+			color: $u-checkbox-label-color;
+			font-size: $u-checkbox-label-font-size;
+
+			&--disabled {
+				color: $u-checkbox-label-disabled-color;
+			}
+		}
+	}
+</style>

+ 8 - 0
node_modules/uview-ui/components/u-circle-progress/props.js

xqd
@@ -0,0 +1,8 @@
+export default {
+    props: {
+        percentage: {
+            type: [String, Number],
+            default: uni.$u.props.circleProgress.percentage
+        }
+    }
+}

+ 198 - 0
node_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue

xqd
@@ -0,0 +1,198 @@
+<template>
+	<view class="u-circle-progress">
+		<view class="u-circle-progress__left">
+			<view
+			    class="u-circle-progress__left__circle"
+			    :style="[leftSyle]"
+			    ref="left-circle"
+			>
+
+			</view>
+		</view>
+		<view
+		    class="u-circle-progress__right"
+		>
+			<view
+			    class="u-circle-progress__right__circle"
+			    ref="right-circle"
+				:style="[rightSyle]"
+			>
+
+			</view>
+		</view>
+		<view class="u-circle-progress__circle">
+
+		</view>
+	</view>
+</template>
+
+<script>
+	import props from './props.js';
+	// #ifdef APP-NVUE
+	const animation = uni.requireNativePlugin('animation')
+	// #endif
+	/**
+	 * CircleProgress 圆形进度条 TODO: 待完善 
+	 * @description 展示操作或任务的当前进度,比如上传文件,是一个圆形的进度环。
+	 * @tutorial https://www.uviewui.com/components/circleProgress.html
+	 * @property {String | Number}	percentage	圆环进度百分比值,为数值类型,0-100 (默认 30 )
+	 * @example
+	 */
+	export default {
+		name: 'u-circle-progress',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+		data() {
+			return {
+				leftBorderColor: 'rgb(200, 200, 200)',
+				rightBorderColor: 'rgb(200, 200, 200)',
+			}
+		},
+		computed: {
+			leftSyle() {
+				const style = {}
+				style.borderTopColor = this.leftBorderColor
+				style.borderRightColor = this.leftBorderColor
+				return style
+			},
+			rightSyle() {
+				const style = {}
+				style.borderLeftColor = this.rightBorderColor
+				style.borderBottomColor = this.rightBorderColor
+				return style
+			}
+		},
+		mounted() {
+			uni.$u.sleep().then(() => {
+				this.rightBorderColor = 'rgb(66, 185, 131)'
+				// this.init()
+			})
+		},
+		methods: {
+			init() {
+				animation.transition(this.$refs['right-circle'].ref, {
+					styles: {
+						transform: 'rotate(45deg)',
+						transformOrigin: 'center center'
+					},
+				}, () => {
+					this.rightBorderColor = 'rgb(66, 185, 131)'
+					// animation.transition(this.$refs['right-circle'].ref, {
+					// 	styles: {
+					// 		transform: 'rotate(225deg)',
+					// 		transformOrigin: 'center center'
+					// 	},
+					// 	duration: 3000,
+					// }, () => {
+					// 	animation.transition(this.$refs['left-circle'].ref, {
+					// 		styles: {
+					// 			transform: 'rotate(45deg)',
+					// 			transformOrigin: 'center center'
+					// 		},
+					// 	}, () => {
+					// 		this.leftBorderColor = 'rgb(66, 185, 131)'
+					// 		animation.transition(this.$refs['left-circle'].ref, {
+					// 			styles: {
+					// 				transform: 'rotate(225deg)',
+					// 				transformOrigin: 'center center'
+					// 			},
+					// 			duration: 1500,
+					// 		}, () => {
+
+					// 		})
+					// 	})
+					// })
+				})
+
+			}
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+
+	.u-circle-progress {
+		@include flex(row);
+		position: relative;
+		border-radius: 100px;
+		height: 100px;
+		width: 100px;
+		// transform: rotate(0deg);
+		// background-color: rgb(66, 185, 131);
+		background-color: rgb(200, 200, 200);
+		overflow: hidden;
+		justify-content: space-between;
+
+		&__circle {
+			border-radius: 100px;
+			height: 90px;
+			width: 90px;
+			transform: translate(-50%, -50%);
+			background-color: rgb(255, 255, 255);
+			left: 50px;
+			top: 50px;
+			position: absolute;
+		}
+
+		&__left {
+			position: absolute;
+			left: 0;
+			width: 50px;
+			height: 100px;
+			overflow: hidden;
+			box-sizing: border-box;
+			// background-color: rgb(66, 185, 131);
+			// background-color: rgb(200, 200, 200);
+			// transform-origin: left center;
+
+			&__circle {
+				box-sizing: border-box;
+				// background-color: red;
+				border-left-color: transparent;
+				border-bottom-color: transparent;
+				border-top-left-radius: 50px;
+				border-top-right-radius: 50px;
+				border-bottom-right-radius: 50px;
+				// border-left-color: rgb(66, 185, 131);
+				// border-bottom-color: rgb(66, 185, 131);
+				border-top-color: rgb(66, 185, 131);
+				border-right-color: rgb(66, 185, 131);
+				border-width: 5px;
+				width: 100px;
+				height: 100px;
+				transform: rotate(225deg);
+				// border-radius: 100px;
+			}
+		}
+
+		&__right {
+			position: absolute;
+			right: 0;
+			width: 50px;
+			height: 100px;
+			overflow: hidden;
+
+			&__circle {
+				position: absolute;
+				right: 0;
+				box-sizing: border-box;
+				// background-color: red;
+				border-top-color: transparent;
+				border-right-color: transparent;
+				border-top-left-radius: 50px;
+				border-bottom-left-radius: 50px;
+				border-bottom-right-radius: 50px;
+				// border-left-color: rgb(66, 185, 131);
+				// border-bottom-color: rgb(66, 185, 131);
+				border-left-color: rgb(200, 200, 200);
+				border-bottom-color: rgb(200, 200, 200);
+				border-width: 5px;
+				width: 100px;
+				height: 100px;
+				transform: rotate(45deg);
+				transform-origin: center center;
+				// border-radius: 100px;
+			}
+		}
+	}
+</style>

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

xqd
@@ -0,0 +1,74 @@
+export default {
+    props: {
+        // 最大输入长度
+        maxlength: {
+            type: [String, Number],
+            default: uni.$u.props.codeInput.maxlength
+        },
+        // 是否用圆点填充
+        dot: {
+            type: Boolean,
+            default: uni.$u.props.codeInput.dot
+        },
+        // 显示模式,box-盒子模式,line-底部横线模式
+        mode: {
+            type: String,
+            default: uni.$u.props.codeInput.mode
+        },
+        // 是否细边框
+        hairline: {
+            type: Boolean,
+            default: uni.$u.props.codeInput.hairline
+        },
+        // 字符间的距离
+        space: {
+            type: [String, Number],
+            default: uni.$u.props.codeInput.space
+        },
+        // 预置值
+        value: {
+            type: [String, Number],
+            default: uni.$u.props.codeInput.value
+        },
+        // 是否自动获取焦点
+        focus: {
+            type: Boolean,
+            default: uni.$u.props.codeInput.focus
+        },
+        // 字体是否加粗
+        bold: {
+            type: Boolean,
+            default: uni.$u.props.codeInput.bold
+        },
+        // 字体颜色
+        color: {
+            type: String,
+            default: uni.$u.props.codeInput.color
+        },
+        // 字体大小
+        fontSize: {
+            type: [String, Number],
+            default: uni.$u.props.codeInput.fontSize
+        },
+        // 输入框的大小,宽等于高
+        size: {
+            type: [String, Number],
+            default: uni.$u.props.codeInput.size
+        },
+        // 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true
+        disabledKeyboard: {
+            type: Boolean,
+            default: uni.$u.props.codeInput.disabledKeyboard
+        },
+        // 边框和线条颜色
+        borderColor: {
+            type: String,
+            default: uni.$u.props.codeInput.borderColor
+        },
+		// 是否禁止输入"."符号
+		disabledDot: {
+			type: Boolean,
+			default: uni.$u.props.codeInput.disabledDot
+		}
+    }
+}

+ 251 - 0
node_modules/uview-ui/components/u-code-input/u-code-input.vue

xqd
@@ -0,0 +1,251 @@
+<template>
+	<view class="u-code-input">
+		<view
+			class="u-code-input__item"
+			:style="[itemStyle(index)]"
+			v-for="(item, index) in codeLength"
+			:key="index"
+		>
+			<view
+				class="u-code-input__item__dot"
+				v-if="dot && codeArray.length > index"
+			></view>
+			<text
+				v-else
+				:style="{
+					fontSize: $u.addUnit(fontSize),
+					fontWeight: bold ? 'bold' : 'normal',
+					color: color
+				}"
+			>{{codeArray[index]}}</text>
+			<view
+				class="u-code-input__item__line"
+				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"
+			type="number"
+			:focus="focus"
+			:value="inputValue"
+			:maxlength="maxlength"
+			class="u-code-input__input"
+			@input="inputHandler"
+			:style="{
+				height: $u.addUnit(size) 
+			}"
+			@focus="isFocus = true"
+			@blur="isFocus = false"
+		/>
+	</view>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * CodeInput 验证码输入
+	 * @description 该组件一般用于验证用户短信验证码的场景,也可以结合uView的键盘组件使用
+	 * @tutorial https://www.uviewui.com/components/codeInput.html
+	 * @property {String | Number}	maxlength			最大输入长度 (默认 6 )
+	 * @property {Boolean}			dot					是否用圆点填充 (默认 false )
+	 * @property {String}			mode				显示模式,box-盒子模式,line-底部横线模式 (默认 'box' )
+	 * @property {Boolean}			hairline			是否细边框 (默认 false )
+	 * @property {String | Number}	space				字符间的距离 (默认 10 )
+	 * @property {String | Number}	value				预置值
+	 * @property {Boolean}			focus				是否自动获取焦点 (默认 false )
+	 * @property {Boolean}			bold				字体和输入横线是否加粗 (默认 false )
+	 * @property {String}			color				字体颜色 (默认 '#606266' )
+	 * @property {String | Number}	fontSize			字体大小,单位px (默认 18 )
+	 * @property {String | Number}	size				输入框的大小,宽等于高 (默认 35 )
+	 * @property {Boolean}			disabledKeyboard	是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true (默认 false )
+	 * @property {String}			borderColor			边框和线条颜色 (默认 '#c9cacc' )
+	 * @property {Boolean}			disabledDot			是否禁止输入"."符号 (默认 true )
+	 * 
+	 * @event {Function}	change	输入内容发生改变时触发,具体见上方说明			value:当前输入的值
+	 * @event {Function}	finish	输入字符个数达maxlength值时触发,见上方说明	value:当前输入的值
+	 * @example	<u-code-input v-model="value4" :focus="true"></u-code-input>
+	 */
+	export default {
+		name: 'u-code-input',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		data() {
+			return {
+				inputValue: '',
+				isFocus: this.focus
+			}
+		},
+		watch: {
+			value: {
+				immediate: true,
+				handler(val) {
+					// 转为字符串,超出部分截掉
+					this.inputValue = String(val).substring(0, this.maxlength)
+				}
+			},
+		},
+		computed: {
+			// 根据长度,循环输入框的个数,因为头条小程序数值不能用于v-for
+			codeLength() {
+				return new Array(Number(this.maxlength))
+			},
+			// 循环item的样式
+			itemStyle() {
+				return index => {
+					const addUnit = uni.$u.addUnit
+					const style = {
+						width: addUnit(this.size),
+						height: addUnit(this.size)
+					}
+					// 盒子模式下,需要额外进行处理
+					if (this.mode === 'box') {
+						// 设置盒子的边框,如果是细边框,则设置为0.5px宽度
+						style.border = `${this.hairline ? 0.5 : 1}px solid ${this.borderColor}`
+						// 如果盒子间距为0的话
+						if (uni.$u.getPx(this.space) === 0) {
+							// 给第一和最后一个盒子设置圆角
+							if (index === 0) {
+								style.borderTopLeftRadius = '3px'
+								style.borderBottomLeftRadius = '3px'
+							}
+							if (index === this.codeLength.length - 1) {
+								style.borderTopRightRadius = '3px'
+								style.borderBottomRightRadius = '3px'
+							}
+							// 最后一个盒子的右边框需要保留
+							if (index !== this.codeLength.length - 1) {
+								style.borderRight = 'none'
+							}
+						}
+					}
+					if (index !== this.codeLength.length - 1) {
+						// 设置验证码字符之间的距离,通过margin-right设置,最后一个字符,无需右边框
+						style.marginRight = addUnit(this.space)
+					} else {
+						// 最后一个盒子的有边框需要保留
+						style.marginRight = 0
+					}
+
+					return style
+				}
+			},
+			// 将输入的值,转为数组,给item历遍时,根据当前的索引显示数组的元素
+			codeArray() {
+				return String(this.inputValue).split('')
+			},
+			// 下划线模式下,横线的样式
+			lineStyle() {
+				const style = {}
+				style.height = this.hairline ? '2px' : '4px'
+				style.width = uni.$u.addUnit(this.size)
+				// 线条模式下,背景色即为边框颜色
+				style.backgroundColor = this.borderColor
+				return style
+			}
+		},
+		methods: {
+			// 监听输入框的值发生变化
+			inputHandler(e) {
+				const value = e.detail.value
+				this.inputValue = value
+				// 是否允许输入“.”符号
+				if(this.disabledDot) {
+					this.$nextTick(() => {
+						this.inputValue = value.replace('.', '')
+					})
+				}
+				// 未达到maxlength之前,发送change事件,达到后发送finish事件
+				this.$emit('change', value)
+				// 修改通过v-model双向绑定的值
+				this.$emit('input', value)
+				// 达到用户指定输入长度时,发出完成事件
+				if (String(value).length >= Number(this.maxlength)) {
+					this.$emit('finish', value)
+				}
+			}
+		}
+	}
+</script>
+
+<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;
+		position: relative;
+		overflow: hidden;
+
+		&__item {
+			@include flex;
+			justify-content: center;
+			align-items: center;
+			position: relative;
+
+			&__text {
+				font-size: 15px;
+				color: $u-content-color;
+			}
+
+			&__dot {
+				width: 7px;
+				height: 7px;
+				border-radius: 100px;
+				background-color: $u-content-color;
+			}
+
+			&__line {
+				position: absolute;
+				bottom: 0;
+				height: 4px;
+				border-radius: 100px;
+				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 {
+			// 之所以需要input输入框,是因为有它才能唤起键盘
+			// 这里将它设置为两倍的屏幕宽度,再将左边的一半移出屏幕,为了不让用户看到输入的内容
+			position: absolute;
+			left: -750rpx;
+			width: 1500rpx;
+			top: 0;
+			background-color: transparent;
+			text-align: left;
+		}
+	}
+	
+	/* #ifndef APP-PLUS */
+	@keyframes u-cursor-flicker {
+		0% {
+		    opacity: 0;
+		}
+		50% {
+		    opacity: 1;
+		}
+		100% {
+		    opacity: 0;
+		}
+	}
+	/* #endif */
+
+</style>

+ 34 - 0
node_modules/uview-ui/components/u-code/props.js

xqd
@@ -0,0 +1,34 @@
+export default {
+    props: {
+        // 倒计时总秒数
+        seconds: {
+            type: [String, Number],
+            default: uni.$u.props.code.seconds
+        },
+        // 尚未开始时提示
+        startText: {
+            type: String,
+            default: uni.$u.props.code.startText
+        },
+        // 正在倒计时中的提示
+        changeText: {
+            type: String,
+            default: uni.$u.props.code.changeText
+        },
+        // 倒计时结束时的提示
+        endText: {
+            type: String,
+            default: uni.$u.props.code.endText
+        },
+        // 是否在H5刷新或各端返回再进入时继续倒计时
+        keepRunning: {
+            type: Boolean,
+            default: uni.$u.props.code.keepRunning
+        },
+        // 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
+        uniqueKey: {
+            type: String,
+            default: uni.$u.props.code.uniqueKey
+        }
+    }
+}

+ 129 - 0
node_modules/uview-ui/components/u-code/u-code.vue

xqd
@@ -0,0 +1,129 @@
+<template>
+	<view class="u-code">
+		<!-- 此组件功能由js完成,无需写html逻辑 -->
+	</view>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * Code 验证码输入框
+	 * @description 考虑到用户实际发送验证码的场景,可能是一个按钮,也可能是一段文字,提示语各有不同,所以本组件 不提供界面显示,只提供提示语,由用户将提示语嵌入到具体的场景
+	 * @tutorial https://www.uviewui.com/components/code.html
+	 * @property {String | Number}	seconds			倒计时所需的秒数(默认 60 )
+	 * @property {String}			startText		开始前的提示语,见官网说明(默认 '获取验证码' )
+	 * @property {String}			changeText		倒计时期间的提示语,必须带有字母"x",见官网说明(默认 'X秒重新获取' )
+	 * @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> 
+	 */
+	export default {
+		name: "u-code",
+		mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
+		data() {
+			return {
+				secNum: this.seconds,
+				timer: null,
+				canGetCode: true, // 是否可以执行验证码操作
+			}
+		},
+		mounted() {
+			this.checkKeepRunning()
+		},
+		watch: {
+			seconds: {
+				immediate: true,
+				handler(n) {
+					this.secNum = n
+				}
+			}
+		},
+		methods: {
+			checkKeepRunning() {
+				// 获取上一次退出页面(H5还包括刷新)时的时间戳,如果没有上次的保存,此值可能为空
+				let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$uCountDownTimestamp'))
+				if(!lastTimestamp) return this.changeEvent(this.startText)
+				// 当前秒的时间戳
+				let nowTimestamp = Math.floor((+ new Date()) / 1000)
+				// 判断当前的时间戳,是否小于上一次的本该按设定结束,却提前结束的时间戳
+				if(this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {
+					// 剩余尚未执行完的倒计秒数
+					this.secNum = lastTimestamp - nowTimestamp
+					// 清除本地保存的变量
+					uni.removeStorageSync(this.uniqueKey + '_$uCountDownTimestamp')
+					// 开始倒计时
+					this.start()
+				} else {
+					// 如果不存在需要继续上一次的倒计时,执行正常的逻辑
+					this.changeEvent(this.startText)
+				}
+			},
+			// 开始倒计时
+			start() {
+				// 防止快速点击获取验证码的按钮而导致内部产生多个定时器导致混乱
+				if(this.timer) {
+					clearInterval(this.timer)
+					this.timer = null
+				}
+				this.$emit('start')
+				this.canGetCode = false
+				// 这里放这句,是为了一开始时就提示,否则要等setInterval的1秒后才会有提示
+				this.changeEvent(this.changeText.replace(/x|X/, this.secNum))
+				this.setTimeToStorage()
+				this.timer = setInterval(() => {
+					if (--this.secNum) {
+						// 用当前倒计时的秒数替换提示字符串中的"x"字母
+						this.changeEvent(this.changeText.replace(/x|X/, this.secNum))
+					} else {
+						clearInterval(this.timer)
+						this.timer = null
+						this.changeEvent(this.endText)
+						this.secNum = this.seconds
+						this.$emit('end')
+						this.canGetCode = true
+					}
+				}, 1000)
+			},
+			// 重置,可以让用户再次获取验证码
+			reset() {
+				this.canGetCode = true
+				clearInterval(this.timer)
+				this.secNum = this.seconds
+				this.changeEvent(this.endText)
+			},
+			changeEvent(text) {
+				this.$emit('change', text)
+			},
+			// 保存时间戳,为了防止倒计时尚未结束,H5刷新或者各端的右上角返回上一页再进来
+			setTimeToStorage() {
+				if(!this.keepRunning || !this.timer) return
+				// 记录当前的时间戳,为了下次进入页面,如果还在倒计时内的话,继续倒计时
+				// 倒计时尚未结束,结果大于0;倒计时已经开始,就会小于初始值,如果等于初始值,说明没有开始倒计时,无需处理
+				if(this.secNum > 0 && this.secNum <= this.seconds) {
+					// 获取当前时间戳(+ new Date()为特殊写法),除以1000变成秒,再去除小数部分
+					let nowTimestamp = Math.floor((+ new Date()) / 1000)
+					// 将本该结束时候的时间戳保存起来 => 当前时间戳 + 剩余的秒数
+					uni.setStorage({
+						key: this.uniqueKey + '_$uCountDownTimestamp',
+						data: nowTimestamp + Number(this.secNum)
+					})
+				}
+			}
+		},
+		// 组件销毁的时候,清除定时器,否则定时器会继续存在,系统不会自动清除
+		beforeDestroy() {
+			this.setTimeToStorage()
+			clearTimeout(this.timer)
+			this.timer = null
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+</style>

+ 29 - 0
node_modules/uview-ui/components/u-col/props.js

xqd
@@ -0,0 +1,29 @@
+export default {
+    props: {
+        // 占父容器宽度的多少等分,总分为12份
+        span: {
+            type: [String, Number],
+            default: uni.$u.props.col.span
+        },
+        // 指定栅格左侧的间隔数(总12栏)
+        offset: {
+            type: [String, Number],
+            default: uni.$u.props.col.offset
+        },
+        // 水平排列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`)
+        justify: {
+            type: String,
+            default: uni.$u.props.col.justify
+        },
+        // 垂直对齐方式,可选值为top、center、bottom、stretch
+        align: {
+            type: String,
+            default: uni.$u.props.col.align
+        },
+        // 文字对齐方式
+        textAlign: {
+            type: String,
+            default: uni.$u.props.col.textAlign
+        }
+    }
+}

+ 162 - 0
node_modules/uview-ui/components/u-col/u-col.vue

xqd
@@ -0,0 +1,162 @@
+<template>
+	<view
+	    class="u-col"
+		ref="u-col"
+	    :class="[
+			'u-col-' + span
+		]"
+	    :style="[colStyle]"
+	    @tap="clickHandler"
+	>
+		<slot></slot>
+	</view>
+</template>
+
+<script>
+	import props from './props.js';
+	/**
+	 * CodeInput 栅格系统的列 
+	 * @description 该组件一般用于Layout 布局 通过基础的 12 分栏,迅速简便地创建布局
+	 * @tutorial https://www.uviewui.com/components/Layout.html
+	 * @property {String | Number}	span		栅格占据的列数,总12等份 (默认 12 ) 
+	 * @property {String | Number}	offset		分栏左边偏移,计算方式与span相同 (默认 0 ) 
+	 * @property {String}			justify		水平排列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`)  (默认 'start' ) 
+	 * @property {String}			align		垂直对齐方式,可选值为top、center、bottom、stretch (默认 'stretch' ) 
+	 * @property {String}			textAlign	文字水平对齐方式 (默认 'left' ) 
+	 * @property {Object}			customStyle	定义需要用到的外部样式
+	 * @event {Function}	click	col被点击,会阻止事件冒泡到row
+	 * @example	 <u-col  span="3" offset="3" > <view class="demo-layout bg-purple"></view> </u-col>
+	 */
+	export default {
+		name: 'u-col',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		data() {
+			return {
+				width: 0,
+				parentData: {
+					gutter: 0
+				},
+				gridNum: 12
+			}
+		},
+		computed: {
+			uJustify() {
+				if (this.justify == 'end' || this.justify == 'start') return 'flex-' + this.justify
+				else if (this.justify == 'around' || this.justify == 'between') return 'space-' + this.justify
+				else return this.justify
+			},
+			uAlignItem() {
+				if (this.align == 'top') return 'flex-start'
+				if (this.align == 'bottom') return 'flex-end'
+				else return this.align
+			},
+			colStyle() {
+				const style = {
+					// 这里写成"padding: 0 10px"的形式是因为nvue的需要
+					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,
+					// #ifndef APP-NVUE
+					// 在非nvue上,使用百分比形式
+					flex: `0 0 ${100 / this.gridNum * this.span}%`,
+					marginLeft: 100 / 12 * this.offset + '%',
+					// #endif
+					// #ifdef APP-NVUE
+					// 在nvue上,由于无法使用百分比单位,这里需要获取父组件的宽度,再计算得出该有对应的百分比尺寸
+					width: uni.$u.addUnit(Math.floor(this.width / this.gridNum * Number(this.span))),
+					marginLeft: uni.$u.addUnit(Math.floor(this.width / this.gridNum * Number(this.offset))),
+					// #endif
+				}
+				return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
+			}
+		},
+		mounted() {
+			this.init()
+		},
+		methods: {
+			async init() {
+				// 支付宝小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环引用
+				this.updateParentData()
+				this.width = await this.parent.getComponentWidth()
+			},
+			updateParentData() {
+				this.getParentData('u-row')
+			},
+			clickHandler(e) {
+				this.$emit('click');
+			}
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+
+	.u-col {
+		padding: 0;
+		/* #ifndef APP-NVUE */
+		box-sizing:border-box;
+		/* #endif */
+		/* #ifdef MP */
+		display: block;
+		/* #endif */
+	}
+
+	// nvue下百分比无效
+	/* #ifndef APP-NVUE */
+	.u-col-0 {
+		width: 0;
+	}
+
+	.u-col-1 {
+		width: calc(100%/12);
+	}
+
+	.u-col-2 {
+		width: calc(100%/12 * 2);
+	}
+
+	.u-col-3 {
+		width: calc(100%/12 * 3);
+	}
+
+	.u-col-4 {
+		width: calc(100%/12 * 4);
+	}
+
+	.u-col-5 {
+		width: calc(100%/12 * 5);
+	}
+
+	.u-col-6 {
+		width: calc(100%/12 * 6);
+	}
+
+	.u-col-7 {
+		width: calc(100%/12 * 7);
+	}
+
+	.u-col-8 {
+		width: calc(100%/12 * 8);
+	}
+
+	.u-col-9 {
+		width: calc(100%/12 * 9);
+	}
+
+	.u-col-10 {
+		width: calc(100%/12 * 10);
+	}
+
+	.u-col-11 {
+		width: calc(100%/12 * 11);
+	}
+
+	.u-col-12 {
+		width: calc(100%/12 * 12);
+	}
+
+	/* #endif */
+</style>

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov