Browse Source

短剧初版模板

pansl 2 years ago
parent
commit
43a8079110
100 changed files with 12397 additions and 9512 deletions
  1. 8 22
      App.vue
  2. 23 0
      README.md
  3. 0 26
      api/activitie.js
  4. 0 18
      api/estate.js
  5. 0 44
      api/login.js
  6. 0 52
      api/vote.js
  7. 3623 0
      common/animate.css
  8. 1 0
      common/city.data.js
  9. 31 0
      common/common.css
  10. 11 0
      common/config.js
  11. 352 0
      common/html-parser.js
  12. 432 0
      common/iconfont.css
  13. 113 0
      common/lib.js
  14. 116 0
      common/request.js
  15. 54 0
      common/story.js
  16. 1456 0
      common/uni.css
  17. 94 0
      common/util.js
  18. 0 27
      components/BgWrap/index.vue
  19. 0 11
      components/README.md
  20. 0 91
      components/Upload/index.vue
  21. 170 0
      components/chunlei-video/chunLei-danmu/chunLei-danmu.nvue
  22. 214 0
      components/chunlei-video/chunLei-slider/chunLei-slider.nvue
  23. 280 0
      components/chunlei-video/chunlei-video.nvue
  24. 26 0
      components/common/copyright.vue
  25. 31 0
      components/common/empty.vue
  26. 145 0
      components/common/footer.vue
  27. 125 0
      components/common/tuij.vue
  28. 90 0
      components/countdown/time.vue
  29. 95 0
      components/dialog/ach.vue
  30. 140 0
      components/dialog/birthday.vue
  31. 89 0
      components/dialog/cardsend.vue
  32. 129 0
      components/dialog/couponshare.vue
  33. 137 0
      components/dialog/couponshareget.vue
  34. 140 0
      components/dialog/dyxx.vue
  35. 140 0
      components/dialog/login.vue
  36. 113 0
      components/dialog/payment.vue
  37. 163 0
      components/dialog/qrcode.vue
  38. 0 144
      components/dt-dropdown/dt-dropdown.vue
  39. 187 0
      components/fanxiao-sign/sigin-in.vue
  40. 138 0
      components/h-form-alert/h-form-alert.vue
  41. 48 0
      components/h-form-alert/readme.md
  42. 0 173
      components/maskDialog/maskDialog.vue
  43. 166 0
      components/ming-pop/ming-pop.vue
  44. 134 0
      components/model/model.vue
  45. 184 0
      components/select/address.vue
  46. 176 0
      components/select/birthday.vue
  47. 175 0
      components/select/coupon.vue
  48. 280 0
      components/select/datetime.vue
  49. 179 0
      components/select/mendian.vue
  50. 63 0
      components/select/star.vue
  51. 173 0
      components/share-btn/share-btn.vue
  52. 74 0
      components/show/photo.vue
  53. 96 0
      components/sub/tab.vue
  54. 137 0
      components/sub/tabnav.vue
  55. 138 0
      components/sub/tabvs.vue
  56. 142 0
      components/sub/tabvsw.vue
  57. 96 0
      components/uni-icons1/icons.js
  58. 57 0
      components/uni-icons1/uni-icons.vue
  59. 194 0
      components/uni-load-more/uni-load-more.vue
  60. 210 0
      components/uni-pagination/uni-pagination.vue
  61. 263 0
      components/uni-popup/uni-popup.vue
  62. 281 0
      components/uni-transition/uni-transition.vue
  63. 118 0
      components/upload/face.vue
  64. 147 0
      components/upload/list.vue
  65. 0 21
      components/uview-ui/LICENSE
  66. 0 106
      components/uview-ui/README.md
  67. 0 190
      components/uview-ui/components/u-action-sheet/u-action-sheet.vue
  68. 0 256
      components/uview-ui/components/u-alert-tips/u-alert-tips.vue
  69. 0 290
      components/uview-ui/components/u-avatar-cropper/u-avatar-cropper.vue
  70. 0 1265
      components/uview-ui/components/u-avatar-cropper/weCropper.js
  71. 0 244
      components/uview-ui/components/u-avatar/u-avatar.vue
  72. 0 153
      components/uview-ui/components/u-back-top/u-back-top.vue
  73. 0 216
      components/uview-ui/components/u-badge/u-badge.vue
  74. 0 596
      components/uview-ui/components/u-button/u-button.vue
  75. 0 639
      components/uview-ui/components/u-calendar/u-calendar.vue
  76. 0 257
      components/uview-ui/components/u-car-keyboard/u-car-keyboard.vue
  77. 0 299
      components/uview-ui/components/u-card/u-card.vue
  78. 0 70
      components/uview-ui/components/u-cell-group/u-cell-group.vue
  79. 0 316
      components/uview-ui/components/u-cell-item/u-cell-item.vue
  80. 0 123
      components/uview-ui/components/u-checkbox-group/u-checkbox-group.vue
  81. 0 284
      components/uview-ui/components/u-checkbox/u-checkbox.vue
  82. 0 220
      components/uview-ui/components/u-circle-progress/u-circle-progress.vue
  83. 0 147
      components/uview-ui/components/u-circle-progress/u-line-progress/u-line-progress.vue
  84. 0 156
      components/uview-ui/components/u-col/u-col.vue
  85. 0 204
      components/uview-ui/components/u-collapse-item/u-collapse-item.vue
  86. 0 99
      components/uview-ui/components/u-collapse/u-collapse.vue
  87. 0 237
      components/uview-ui/components/u-column-notice/u-column-notice.vue
  88. 0 318
      components/uview-ui/components/u-count-down/u-count-down.vue
  89. 0 241
      components/uview-ui/components/u-count-to/u-count-to.vue
  90. 0 153
      components/uview-ui/components/u-divider/u-divider.vue
  91. 0 132
      components/uview-ui/components/u-dropdown-item/u-dropdown-item.vue
  92. 0 298
      components/uview-ui/components/u-dropdown/u-dropdown.vue
  93. 0 193
      components/uview-ui/components/u-empty/u-empty.vue
  94. 0 384
      components/uview-ui/components/u-field/u-field.vue
  95. 0 431
      components/uview-ui/components/u-form-item/u-form-item.vue
  96. 0 134
      components/uview-ui/components/u-form/u-form.vue
  97. 0 52
      components/uview-ui/components/u-full-screen/u-full-screen.vue
  98. 0 54
      components/uview-ui/components/u-gap/u-gap.vue
  99. 0 126
      components/uview-ui/components/u-grid-item/u-grid-item.vue
  100. 0 0
      components/uview-ui/components/u-grid/u-grid.vue

+ 8 - 22
App.vue

@@ -1,7 +1,11 @@
 <script>
+	import Vue from 'vue'
 	export default {
 		onLaunch: function() {
-			console.log('App Launch')
+			const extConfig = uni.getExtConfigSync ? uni.getExtConfigSync() : {};
+			if(extConfig.appid){
+				this.$config.appId = extConfig.appid;
+			}
 		},
 		onShow: function() {
 			console.log('App Show')
@@ -11,26 +15,8 @@
 		}
 	}
 </script>
-
-<style lang="scss">
-@import "/components/uview-ui/index.scss";
-@import "./static/css/common.css";
-	/*每个页面公共css */
-	html {
-		width: 100%;
-		background-color: $theme-color;
-		font-family: PingFangSC-Medium,PingFangSC-Regular,PingFang SC;
-		margin-bottom: 176rpx;
-		// margin: 32rpx;
-	}
-	page{
-		margin-bottom: 176rpx;
-		font-family: PingFangSC-Medium,PingFangSC-Regular,PingFang SC;
-		margin:0 auto;
-	}
-	/* #ifdef H5 */
-	    uni-page-head {
-	        display: none;
-	    }
+<style>
+	/* #ifndef APP-PLUS-NVUE */
+	@import url("./static/css/common.css");
 	/* #endif */
 </style>

+ 23 - 0
README.md

@@ -0,0 +1,23 @@
+####软件订制开发、技术合作、创业合作等可以加我wx zhuzhi520 请备注(uniapp)
+####uniapp qq技术交流 306003105
+
+
+# 项目功能介绍 支持无限滑动 高性能滑动 预加载 视频预览
+
+# 1、首页
+
+# 2、视频
+
+# 3、视频播放,购买
+
+# 4、我的
+
+# 5、分销
+
+
+# 总结
+
+功能基本上完善,欢迎大家测试...
+
+h5地址:https://xjc.demo.hongcd.com/h5 复制手机浏览器打开
+

+ 0 - 26
api/activitie.js

@@ -1,26 +0,0 @@
-import request from '@/utils/request.js'
-import {
-	getStorage,
-	clearStorage
-} from '@/utils/storage.js'
-export function activitie(data) {
-	return request({
-		url: '/activities',
-		data,
-		noAuth: true
-	})
-}
-export function activitieDetail(id, data) {
-	return request({
-		url: `/activities/${id}`,
-		data: {...data,mobile: getStorage('mobile') ? getStorage('mobile') : ''	},
-		noAuth: false
-	})
-}
-export function resultAnnounce(data) {
-	return request({
-		url: '/activities/result_announce',
-		data,
-		noAuth: false
-	})
-}

+ 0 - 18
api/estate.js

@@ -1,18 +0,0 @@
-import request from '@/utils/request.js'
-
-export function estate(data) {
-	return request({
-		url: '/estates',
-		data,
-		noAuth: false
-	})
-}
-
-export function switchEstate(data) {
-	return request({
-		url: '/estate',
-		data,
-		method: 'POST',
-		noAuth: false
-	})
-}

+ 0 - 44
api/login.js

@@ -1,44 +0,0 @@
-import request from '@/utils/request.js'
-
-export function login(data) {
-	return request({
-		url: '/login',
-		method: 'POST',
-		data,
-		noAuth: true
-	})
-}
-
-export function getSms(data) {
-	return request({
-		url: '/sms',
-		method: 'POST',
-		data,
-		noAuth: true
-	})
-}
-
-export function logout() {
-	return request({
-		url: '/logout',
-		method: 'POST',
-		noAuth: false
-	})
-}
-
-export function wxLogin(data) {
-	return request({
-		url: '/mp/login',
-		method: 'POST',
-		data,
-		noAuth: true
-	})
-}
-
-export function user(data) {
-	return request({
-		url: '/my',
-		data,
-		noAuth: false
-	})
-}

+ 0 - 52
api/vote.js

@@ -1,52 +0,0 @@
-import request from '@/utils/request.js'
-import {
-	getStorage,
-	clearStorage
-} from '@/utils/storage.js'
-export function votesLog(data) {
-	return request({
-		url: '/votes/log',
-		data:{...data,mobile: getStorage('mobile') ? getStorage('mobile') : ''},
-		noAuth: false
-	})
-}
-export function votesConfirmJoin(data) {
-	return request({
-		url: '/votes/confirm/join',
-		data,
-		method: 'POST',
-		noAuth: false
-	})
-}
-// 查看活动投票结果
-export function votesResult(data) {
-	return request({
-		url: '/votes/result',
-		data,
-		noAuth: false
-	})
-}
-// 网络投票
-export function votes(id, data) {
-	return request({
-		url: `/votes/${id}`,
-		data,
-		method: 'POST',
-		noAuth: false
-	})
-}
-// 投票码列表
-export function votesTicket(data) {
-	return request({
-		url: `/votes/ticket/code`,
-		data,
-		noAuth: false
-	})
-}
-// 查看活动投票详情
-export function votesCodeResult(id) {
-	return request({
-		url: `/votes/${id}`,
-		noAuth: false
-	})
-}

File diff suppressed because it is too large
+ 3623 - 0
common/animate.css


File diff suppressed because it is too large
+ 1 - 0
common/city.data.js


+ 31 - 0
common/common.css

@@ -0,0 +1,31 @@
+/* flex布局 */
+.u-f,.u-f-ac,.u-f-ajc{
+	display: flex;
+}
+.u-f-ac,.u-f-ajc{
+	align-items: center;
+}
+.u-f-ajc{
+	justify-content: center;
+}
+.u-f-jsb{
+	justify-content: space-between;
+}
+.u-f1{
+	flex: 1;
+}
+.u-f2{
+	flex: 2;
+}
+.u-f3{
+	flex: 3;
+}
+.u-f-column{
+	flex-direction: column;
+}
+.u-f-l{
+	justify-content:flex-start;
+}
+.u-f-r{
+	justify-content:flex-end;
+}

+ 11 - 0
common/config.js

@@ -0,0 +1,11 @@
+// 配置信息
+export default {
+	// api请求前缀
+	webUrl:'https://xjc.demo.hongcd.com',//uni.getStorageSync("config").weburl?uni.getStorageSync("config").weburl:'http://192.168.10.175',
+	imgUrl:'https://xjc.demo.hongcd.com',//uni.getStorageSync("config").imgurl?uni.getStorageSync("config").imgurl:'http://192.168.10.175',
+	staticUrl:'https://xjc.demo.hongcd.com/img/',//静态图片地址https://xjc.demo.hongcd.com
+	// websocket地址
+	//websocketUrl:"https://wx.***.com",
+	// 消息提示tabbar索引  websocketUrl:"https://wx.***.com",
+	TabbarIndex:2
+}

+ 352 - 0
common/html-parser.js

@@ -0,0 +1,352 @@
+/*
+ * HTML5 Parser By Sam Blowes
+ *
+ * Designed for HTML5 documents
+ *
+ * Original code by John Resig (ejohn.org)
+ * http://ejohn.org/blog/pure-javascript-html-parser/
+ * Original code by Erik Arvidsson, Mozilla Public License
+ * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
+ *
+ * ----------------------------------------------------------------------------
+ * License
+ * ----------------------------------------------------------------------------
+ *
+ * This code is triple licensed using Apache Software License 2.0,
+ * Mozilla Public License or GNU Public License
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License.  You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is Simple HTML Parser.
+ *
+ * The Initial Developer of the Original Code is Erik Arvidsson.
+ * Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
+ * Reserved.
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * ----------------------------------------------------------------------------
+ * Usage
+ * ----------------------------------------------------------------------------
+ *
+ * // Use like so:
+ * HTMLParser(htmlString, {
+ *     start: function(tag, attrs, unary) {},
+ *     end: function(tag) {},
+ *     chars: function(text) {},
+ *     comment: function(text) {}
+ * });
+ *
+ * // or to get an XML string:
+ * HTMLtoXML(htmlString);
+ *
+ * // or to get an XML DOM Document
+ * HTMLtoDOM(htmlString);
+ *
+ * // or to inject into an existing document/DOM node
+ * HTMLtoDOM(htmlString, document);
+ * HTMLtoDOM(htmlString, document.body);
+ *
+ */
+// Regular Expressions for parsing tags and attributes
+var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
+var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
+var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
+
+var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5
+// fixed by xxx 将 ins 标签从块级名单中移除
+
+var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); // Inline Elements - HTML 5
+
+var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); // Elements that you can, intentionally, leave open
+// (and which close themselves)
+
+var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
+
+var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything)
+
+var special = makeMap('script,style');
+function HTMLParser(html, handler) {
+  var index;
+  var chars;
+  var match;
+  var stack = [];
+  var last = html;
+
+  stack.last = function () {
+    return this[this.length - 1];
+  };
+
+  while (html) {
+    chars = true; // Make sure we're not in a script or style element
+
+    if (!stack.last() || !special[stack.last()]) {
+      // Comment
+      if (html.indexOf('<!--') == 0) {
+        index = html.indexOf('-->');
+
+        if (index >= 0) {
+          if (handler.comment) {
+            handler.comment(html.substring(4, index));
+          }
+
+          html = html.substring(index + 3);
+          chars = false;
+        } // end tag
+
+      } else if (html.indexOf('</') == 0) {
+        match = html.match(endTag);
+
+        if (match) {
+          html = html.substring(match[0].length);
+          match[0].replace(endTag, parseEndTag);
+          chars = false;
+        } // start tag
+
+      } else if (html.indexOf('<') == 0) {
+        match = html.match(startTag);
+
+        if (match) {
+          html = html.substring(match[0].length);
+          match[0].replace(startTag, parseStartTag);
+          chars = false;
+        }
+      }
+
+      if (chars) {
+        index = html.indexOf('<');
+        var text = index < 0 ? html : html.substring(0, index);
+        html = index < 0 ? '' : html.substring(index);
+
+        if (handler.chars) {
+          handler.chars(text);
+        }
+      }
+    } else {
+      html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) {
+        text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
+
+        if (handler.chars) {
+          handler.chars(text);
+        }
+
+        return '';
+      });
+      parseEndTag('', stack.last());
+    }
+
+    if (html == last) {
+      throw 'Parse Error: ' + html;
+    }
+
+    last = html;
+  } // Clean up any remaining tags
+
+
+  parseEndTag();
+
+  function parseStartTag(tag, tagName, rest, unary) {
+    tagName = tagName.toLowerCase();
+
+    if (block[tagName]) {
+      while (stack.last() && inline[stack.last()]) {
+        parseEndTag('', stack.last());
+      }
+    }
+
+    if (closeSelf[tagName] && stack.last() == tagName) {
+      parseEndTag('', tagName);
+    }
+
+    unary = empty[tagName] || !!unary;
+
+    if (!unary) {
+      stack.push(tagName);
+    }
+
+    if (handler.start) {
+      var attrs = [];
+      rest.replace(attr, function (match, name) {
+        var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : '';
+        attrs.push({
+          name: name,
+          value: value,
+          escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
+
+        });
+      });
+
+      if (handler.start) {
+        handler.start(tagName, attrs, unary);
+      }
+    }
+  }
+
+  function parseEndTag(tag, tagName) {
+    // If no tag name is provided, clean shop
+    if (!tagName) {
+      var pos = 0;
+    } // Find the closest opened tag of the same type
+    else {
+        for (var pos = stack.length - 1; pos >= 0; pos--) {
+          if (stack[pos] == tagName) {
+            break;
+          }
+        }
+      }
+
+    if (pos >= 0) {
+      // Close all the open elements, up the stack
+      for (var i = stack.length - 1; i >= pos; i--) {
+        if (handler.end) {
+          handler.end(stack[i]);
+        }
+      } // Remove the open elements from the stack
+
+
+      stack.length = pos;
+    }
+  }
+}
+
+function makeMap(str) {
+  var obj = {};
+  var items = str.split(',');
+
+  for (var i = 0; i < items.length; i++) {
+    obj[items[i]] = true;
+  }
+
+  return obj;
+}
+
+function removeDOCTYPE(html) {
+  return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
+}
+
+function parseAttrs(attrs) {
+  return attrs.reduce(function (pre, attr) {
+    var value = attr.value;
+    var name = attr.name;
+
+    if (pre[name]) {
+			pre[name] = pre[name] + " " + value;
+    } else {
+			pre[name] = value;
+    }
+
+    return pre;
+  }, {});
+}
+
+function parseHtml(html) {
+  html = removeDOCTYPE(html);
+  var stacks = [];
+  var results = {
+    node: 'root',
+    children: []
+  };
+  HTMLParser(html, {
+    start: function start(tag, attrs, unary) {
+      var node = {
+        name: tag
+      };
+
+      if (attrs.length !== 0) {
+        node.attrs = parseAttrs(attrs);
+      }
+
+      if (unary) {
+        var parent = stacks[0] || results;
+
+        if (!parent.children) {
+          parent.children = [];
+        }
+
+        parent.children.push(node);
+      } else {
+        stacks.unshift(node);
+      }
+    },
+    end: function end(tag) {
+      var node = stacks.shift();
+      if (node.name !== tag) console.error('invalid state: mismatch end tag');
+
+      if (stacks.length === 0) {
+        results.children.push(node);
+      } else {
+        var parent = stacks[0];
+
+        if (!parent.children) {
+          parent.children = [];
+        }
+
+        parent.children.push(node);
+      }
+    },
+    chars: function chars(text) {
+      var node = {
+        type: 'text',
+        text: text
+      };
+
+      if (stacks.length === 0) {
+        results.children.push(node);
+      } else {
+        var parent = stacks[0];
+
+        if (!parent.children) {
+          parent.children = [];
+        }
+
+        parent.children.push(node);
+      }
+    },
+    comment: function comment(text) {
+      var node = {
+        node: 'comment',
+        text: text
+      };
+      var parent = stacks[0];
+
+      if (!parent.children) {
+        parent.children = [];
+      }
+
+      parent.children.push(node);
+    }
+  });
+  return results.children;
+}
+
+export default parseHtml;

File diff suppressed because it is too large
+ 432 - 0
common/iconfont.css


+ 113 - 0
common/lib.js

@@ -0,0 +1,113 @@
+import $http from "./request.js";
+// 网络监听
+const NetWork = {
+	// 网络状态
+	isConnect:false,
+	// 监听网络状态
+	On(){
+		// 获取当前网络状态
+		uni.getNetworkType({
+			success: (res) => {
+				if(res.networkType!=='none'){ 
+					this.isConnect=true; 
+					return;
+					}
+				uni.showModal({
+					title: '',
+					content:"请先连接网络哦",
+					showCancel: false,
+					confirmText: "确定",
+					success: function (res) {
+						
+					}
+				});
+			}
+		})
+		// 监听网络状态变化
+		uni.onNetworkStatusChange((res)=>{
+			this.isConnect = res.isConnected;
+			if(!res.isConnected){
+				uni.showModal({
+					title: '',
+					content:"您目前处于断网状态",
+					showCancel: false,
+					confirmText: "确定",
+					success: function (res) {
+						
+					}
+				});
+			}
+		})
+	}
+}
+
+// app更新
+const Update = function(showToast = false){
+	// #ifdef APP-PLUS  
+	plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) {  
+		/*
+		
+		{
+			"msg": "ok",
+			"data": {
+				"id": 1,
+				"url": "http://www.baidu.com",
+				"version": "1.0.1",
+				"status": 1,
+				"create_time": null
+			}
+		}
+		
+		*/
+		$http.post('/update',{
+			ver:widgetInfo.version, 
+		}).then((res) => {
+			let [err,result] = res;
+			// 错误处理
+			if (!$http.errorCheck(err,result)) return;
+			// 成功
+			var data = result.data.data;  
+			if (!data.url){
+				// 无需更新
+				if (showToast) {
+					return uni.showToast({ title: 'YT无需更新',icon:"none" })
+				}
+			}
+			
+			uni.showModal({
+				title: '发现新的版本',
+				content: '最新版本:'+data.version,
+				cancelText: '放弃更新',
+				confirmText: '立即更新',
+				success: res => {
+					if(res.confirm){
+						uni.downloadFile({  
+							url: data.url,  
+							success: (downloadResult) => {  
+								if (downloadResult.statusCode === 200) {  
+									plus.runtime.install(downloadResult.tempFilePath, {  
+										force: false  
+									}, function() {  
+										console.log('install success...');  
+										plus.runtime.restart();  
+									}, function(e) {  
+										console.error('install fail...');  
+									});  
+								}  
+							}  
+						});  
+					}
+				}
+			});
+			
+		});
+		
+	});  
+	// #endif  
+}
+
+import config from "./config.js"
+export default {
+	NetWork,
+	Update
+}

+ 116 - 0
common/request.js

@@ -0,0 +1,116 @@
+// 引入配置文件
+import config from "./config.js";
+export default{
+	config:{
+		baseUrl:config.webUrl,
+		header:{
+			'Content-Type':'application/json;charset=UTF-8',
+			'Content-Type':'application/x-www-form-urlencoded'
+		},
+		data: {},
+		method: "GET",
+		dataType: "json",
+	},
+	request(options = {}){
+		options.header = options.header || this.config.header;
+		options.method = options.method || this.config.method;
+		options.dataType = options.dataType || this.config.dataType;
+		options.url = this.config.baseUrl+options.url;
+		// TODO:token增加等操作
+		if (options.token) {
+			options.data.token = uni.getStorageSync("userinfo").token;
+			options.data.uid = uni.getStorageSync("userinfo").id;
+		}
+		var version='web';
+		// #ifdef APP-PLUS
+		var version=plus.runtime.version
+		// #endif
+		options.data.version=version
+		return uni.request(options).then(res => {
+			if(res[1].data.msg=='version10001'){
+				uni.showModal({
+					title: '更新提示',
+					content:"当前版本需要更新,请及时更新",
+					showCancel: false,
+					confirmText: "确定",
+					success: function (ress) {
+						plus.runtime.openURL(res[1].data.data);
+						uni.reLaunch({
+							url:'/pages/public/login'
+						})
+					}
+				});
+				return false;
+			}
+			return res;
+		});
+	},
+	get(url,data,options={}){
+		options.url = url;
+		options.data = data;
+		options.method = 'GET';
+		return this.request(options);
+	},
+	post(url,data,options={}){
+		options.url = url;
+		options.data = data;
+		options.method = 'POST';
+		return this.request(options);
+	},
+	
+	// 上传图片
+	upload(url,options = {}){
+		options.url = this.config.baseUrl+url;
+		options.header = options.header || this.config.header;
+		options.fileType = options.fileType || "image";
+		options.formData = options.formData || {};
+		options.filePath = options.filePath;
+		options.name = options.name;
+		// TODO:token增加等操作
+		if (options.token) {
+			// 验证是否登录
+			if (!this.checkToken(options.checkToken)) return;
+			// 验证权限
+			if (!this.checkAuth(options.checkAuth)) return; 
+			options.header.token = User.token;
+		}
+		
+		return uni.uploadFile(options);
+	},
+	// 错误处理
+	errorCheck(err,res,errfun = false,resfun = false){
+		if (err) {
+			typeof errfun === 'function' && errfun();
+			uni.showToast({ title: '加载失败',icon:"none" });
+			return false;
+		}
+		if (res.data.errorCode) {
+			typeof errfun === 'function' && resfun();
+			uni.showToast({ title: res.data.msg,icon:"none" });
+			return false;
+		}
+		return true;
+	},
+	// 验证用户是否登录
+	checkToken(checkToken){
+		if (checkToken && !User.token) {
+			uni.showToast({ title: '请先登录', icon:"none" })
+			uni.navigateTo({
+				url: '/pages/login/login'
+			});
+			return false;
+		}
+		return true;
+	},
+	// 验证用户权限
+	checkAuth(checkAuth){
+		if (checkAuth && !User.userinfo.phone) {
+			uni.showToast({ title: '请先绑定手机号码', icon:"none" })
+			uni.navigateTo({
+				url: '/pages/user-bind-phone/user-bind-phone'
+			});
+			return false;
+		}
+		return true;
+	}
+}

+ 54 - 0
common/story.js

@@ -0,0 +1,54 @@
+const util = {
+	/**
+	 * 存储历史数据
+	 * val [string | object]需要存储的内容
+	 */
+	setHistory(val) {
+		let searchHistory = uni.getStorageSync('search:history');
+		if (!searchHistory) searchHistory = [];
+		let serachData = {};
+		if (typeof(val) === 'string') {
+			serachData = {
+				adcode: [],
+				address: [],
+				city: [],
+				district: [],
+				id: [],
+				location: [],
+				name: val,
+				typecode: []
+			};
+		} else {
+			serachData = val
+		}
+
+		// 判断数组是否存在,如果存在,那么将放到最前面
+		for (var i = 0; i < searchHistory.length; i++) {
+			if (searchHistory[i].name === serachData.name) {
+				searchHistory.splice(i, 1);
+				break;
+			}
+		}
+		uni.setStorage({
+			key: 'search:history',
+			data: searchHistory,
+			success: function() {
+				// console.log('success');
+			}
+		});
+	},
+	getHistory() {
+
+	},
+	removeHistory() {
+		uni.removeStorage({
+			key: 'search:history',
+			success: function(res) {
+				console.log('success');
+			}
+		});
+		return []
+	}
+
+}
+export default util;

File diff suppressed because it is too large
+ 1456 - 0
common/uni.css


+ 94 - 0
common/util.js

@@ -0,0 +1,94 @@
+function formatTime(time) {
+	if (typeof time !== 'number' || time < 0) {
+		return time
+	}
+	var hour = parseInt(time / 3600)
+	time = time % 3600
+	var minute = parseInt(time / 60)
+	time = time % 60
+	var second = time
+
+	return ([hour, minute, second]).map(function (n) {
+		n = n.toString()
+		return n[1] ? n : '0' + n
+	}).join(':')
+}
+
+function formatLocation(longitude, latitude) {
+	if (typeof longitude === 'string' && typeof latitude === 'string') {
+		longitude = parseFloat(longitude)
+		latitude = parseFloat(latitude)
+	}
+
+	longitude = longitude.toFixed(2)
+	latitude = latitude.toFixed(2)
+
+	return {
+		longitude: longitude.toString().split('.'),
+		latitude: latitude.toString().split('.')
+	}
+}
+var dateUtils = {
+	UNITS: {
+		'年': 31557600000,
+		'月': 2629800000,
+		'天': 86400000,
+		'小时': 3600000,
+		'分钟': 60000,
+		'秒': 1000
+	},
+	humanize: function (milliseconds) {
+		var humanize = '';
+		for (var key in this.UNITS) {
+			if (milliseconds >= this.UNITS[key]) {
+				humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前';
+				break;
+			}
+		}
+		return humanize || '刚刚';
+	},
+	format: function (dateStr) {
+		var date = this.parse(dateStr)
+		var diff = Date.now() - date.getTime();
+		if (diff < this.UNITS['天']) {
+			return this.humanize(diff);
+		}
+		var _format = function (number) {
+			return (number < 10 ? ('0' + number) : number);
+		};
+		return date.getFullYear() + '-' + _format(date.getMonth() + 1) + '-' + _format(date.getDay()) + '-' +
+			_format(date.getHours()) + ':' + _format(date.getMinutes());
+	},
+	parse: function (str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串,转化为一个Date对象
+		var a = str.split(/[^0-9]/);
+		return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
+	}
+};
+
+function yzyTime(cjsj) {	
+	var date = new Date(cjsj * 1000);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
+	var Y = date.getFullYear() + '-';
+	var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
+	var D = (date.getDate() + 1 <= 10 ? '0' + (date.getDate()) : date.getDate()) + ' ';
+	var h = (date.getHours() + 1 <= 10 ? '0' + (date.getHours()) : date.getHours()) + ':';
+	var m = (date.getMinutes() + 1 <= 10 ? '0' + (date.getMinutes()) : date.getMinutes()) + ':';
+	var s = (date.getSeconds() + 1 <= 10 ? '0' + (date.getSeconds()) : date.getSeconds()) + '';
+	return Y + M + D + h + m + s;
+}
+function yzyTimes(cjsj) {	
+	var date = new Date(cjsj * 1000);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
+	var Y = date.getFullYear() + '-';
+	var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
+	var D = (date.getDate() + 1 <= 10 ? '0' + (date.getDate()) : date.getDate()) + ' ';
+	var h = (date.getHours() + 1 <= 10 ? '0' + (date.getHours()) : date.getHours()) + ':';
+	var m = (date.getMinutes() + 1 <= 10 ? '0' + (date.getMinutes()) : date.getMinutes()) + ':';
+	var s = (date.getSeconds() + 1 <= 10 ? '0' + (date.getSeconds()) : date.getSeconds()) + '';
+	return Y + M + D;
+}
+module.exports = {
+	yzyTime:yzyTime,
+	yzyTimes:yzyTimes,
+	formatTime:formatTime,
+	formatLocation:formatLocation,
+	dateUtils:dateUtils
+}

+ 0 - 27
components/BgWrap/index.vue

@@ -1,27 +0,0 @@
-<template>
-	<view class="bgWrap" :style="{backgroundColor: color}" />
-</template>
-
-<script>
-	export default {
-		name: 'bgWrap',
-		props: {
-			color: {
-				type: String,
-				default: '#FFFFFF'
-			}
-		}
-	}
-</script>
-
-<style scoped>
-	.bgWrap {
-		position: fixed;
-		width: 100%;
-		height: 100%;
-		top: 0;
-		left: 0;
-		background-color: #F9F9F9;
-		z-index: -1;
-	}
-</style>

+ 0 - 11
components/README.md

@@ -1,11 +0,0 @@
-## 引入插件
-`在main.js中添加` 
-
-import dropdown from './components/dropdown/dt-dropDown.vue'
-Vue.component('dropdown', dropdown)
-
-
-
-## 使用 
-
-<dropdown :list="list" @onClick="dropDownChange"></dropdown>

+ 0 - 91
components/Upload/index.vue

@@ -1,91 +0,0 @@
-<template>
-	<view class="">
-		<u-upload :file-list="imgSrcList" :action="action" name="image" :header="header" @on-success='onSuccess'
-			:before-upload="beforeUpload" @on-remove="onRemove" :multiple='isMultiple' :maxCount="limitNumber"
-			:show-progress='false'>
-		</u-upload>
-	</view>
-</template>
-
-<script>
-	import {
-		getStorage,
-		clearStorage
-	} from '@/utils/storage.js'
-	import {
-		baseUrl
-	} from '@/config/app.js'
-
-	export default {
-		props: {
-			// 上传的url地址
-			uploadUrl: {
-				type: String,
-				default: '/upload/image'
-			},
-			// 上传样式类型
-			listType: {
-				type: String,
-				default: 'text'
-			},
-			// 上传的名称
-			isWho: {
-				type: String,
-				default: ''
-			},
-			// 是否是多选
-			isMultiple: {
-				type: Boolean,
-				default: false
-			},
-			// 多选的个数
-			limitNumber: {
-				type: Number,
-				default: 5
-			},
-			// 多选图片回调的路径
-			imgSrcList: {
-				type: Array,
-				default () {
-					return []
-				}
-			},
-		},
-		data() {
-			return {
-				header: {
-					'Authorization': `bearer ${getStorage('access_token')}`
-				},
-				action: baseUrl + this.uploadUrl,
-			};
-		},
-		computed: {
-
-		},
-		async onLoad(options) {
-
-		},
-		methods: {
-			onRemove(index, lists) {
-				console.log('图片已被移除')
-				this.$emit('remove',index, lists)
-			},
-			beforeUpload(index, list) {
-
-			},
-			onSuccess(reg, index, list) {
-				// console.log(reg, index, list, 'onSuccess')
-				const fileList = list.map(el =>
-					el.response?.data
-				)
-				if (fileList.every(el => el)) {
-					this.$emit('onUpload', fileList)
-				}
-				// console.log(fileList)
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-</style>

+ 170 - 0
components/chunlei-video/chunLei-danmu/chunLei-danmu.nvue

@@ -0,0 +1,170 @@
+<template>
+	<div class="danmu" :style="{ width: `${width}px` }">
+		<div class="danmu-row" :style="{ width: `${width}px` }">
+			<div :style="{ left:`${width}px`}" ref="move" :id="item._id" v-for="item in danmuList1" :key="item._id" class="moveDiv">
+				<image :src="item.avatar" class="img" v-if="item.avatar"></image>
+				<text :class="`${platform}-title`" :style="{ color:item.color?item.color:'#fff' }">{{item.text}}</text>
+			</div>
+		</div>
+		<div class="danmu-row" :style="{ width: `${width}px` }">
+			<div :style="{ left:`${width}px`}" ref="move" :id="item._id" v-for="item in danmuList2" :key="item._id" class="moveDiv">
+				<image :src="item.avatar" class="img" v-if="item.avatar"></image>
+				<text :class="`${platform}-title`" :style="{ color:item.color?item.color:'#fff' }">{{item.text}}</text>
+			</div>
+		</div>
+		<div class="danmu-row" :style="{ width: `${width}px` }">
+			<div :style="{ left:`${width}px`}" ref="move" :id="item._id" v-for="item in danmuList3" :key="item._id" class="moveDiv">
+				<image :src="item.avatar" class="img" v-if="item.avatar"></image>
+				<text :class="`${platform}-title`" :style="{ color:item.color?item.color:'#fff' }">{{item.text}}</text>
+			</div>
+		</div>
+		<div class="danmu-row" :style="{ width: `${width}px` }">
+			<div :style="{ left:`${width}px`}" ref="move" :id="item._id" v-for="item in danmuList4" :key="item._id" class="moveDiv">
+				<image :src="item.avatar" class="img" v-if="item.avatar"></image>
+				<text :class="`${platform}-title`" :style="{ color:item.color?item.color:'#fff' }">{{item.text}}</text>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+	const animation = weex.requireModule('animation');
+	const modal = weex.requireModule('modal');
+	export default{
+		props:{
+			width:{
+				type:Number,
+				default:0
+			},
+			danmuList:{ //弹幕
+				type:[Array],
+				default:()=>[]
+			},
+			platform:{
+				type:String,
+				default:'android'
+			},
+			current:{
+				type:Number,
+				default:0
+			}
+		},
+		data(){
+			return{
+				danmuList1:[],
+				danmuList2:[],
+				danmuList3:[],
+				danmuList4:[],
+			}
+		},
+		methods:{
+			promise(){
+				let promise = new Promise((resolve,reject)=>{
+					setTimeout(()=>{
+						resolve()
+					},100)
+				})
+				return promise
+			},
+			cleanDanmu(){
+				this.danmuList1 = []
+				this.danmuList2 = []
+				this.danmuList3 = []
+				this.danmuList4 = []
+			},
+			randomRange(min, max) { // min最小值,max最大值
+			    return Math.floor(Math.random() * (max - min)) + min;
+			},
+			animationText(id,distance,fn){
+				let el
+				let elList = this.$refs.move
+				for (let item of elList) {
+					if(item.attr.id == id){
+						el = item
+					}
+					
+				}
+				animation.transition(el, {
+					styles: {
+						transform: `translate( ${distance}px, 0px)`,
+					},
+					duration: 20000, //ms
+					timingFunction: 'ease',
+					delay: 0 //ms
+					}, () => {
+						fn()
+					}
+				)
+			}
+		},
+		watch:{
+			danmuList:{
+				immediate:true,
+				handler(newVal,oldVal){
+					for (let key in newVal) {
+						newVal[key]._id = key
+					}
+				}
+			},
+			current:{
+				handler:async function(newVal,oldVal){
+					
+					//间隔0.25
+					if(Math.abs(newVal-oldVal)>=0.24){
+						for (let item of this.danmuList) {
+							if( item.time > Math.floor(newVal*1) && item.time <= Math.floor(newVal*1+ 0.25) ) {
+								let num = this.randomRange(1,5)
+								this[`danmuList${num}`].push(item)
+								await this.promise()
+								
+								//开始动画
+								this.animationText(item._id,-this.width*2,()=>{
+									let index
+									//删除动画后的text
+									for (let key in this[`danmuList${num}`]) {
+										if(this[`danmuList${num}`][key]._id==item._id){
+											index = key
+										}
+									}
+									this[`danmuList${num}`].splice(index,1)
+								})
+							}
+						}
+					}
+					
+				}
+			},
+		}
+	}
+</script>
+
+<style>
+.danmu{
+	height: 160px;
+	flex-direction: column;
+	
+}
+.danmu-row{
+	position: relative;
+	height: 40px;
+	flex-direction: row;
+	
+}
+.moveDiv{
+	position: absolute;
+	flex-direction: row;
+	justify-content: center;
+}
+.android-title{
+	font-size: 24px;
+}
+.img{
+	width: 30px;
+	height: 30px;
+	margin-left: 10px;
+	border-radius: 15px;
+}
+.ios-title{
+	font-size: 24px;
+}
+</style>

+ 214 - 0
components/chunlei-video/chunLei-slider/chunLei-slider.nvue

@@ -0,0 +1,214 @@
+<template>
+	<div class="slider flex" id="slider" :style="{ width: `${width}px` }" ref="slider">
+		<div class="slider-left flex" :style="{ width: `${leftWidth}px` }" @touchend.stop="sliderTouch">
+			<div class="left" :style="{backgroundColor:backgroundColor}"></div>
+		</div>
+		<div class="slider-right flex" @touchend.stop="sliderTouch" :style="{ width: `${currentWidth-leftWidth}px` }">
+			<div class="right"></div>
+		</div>
+		<div class="block flex" :style="{backgroundColor:touch?blockOuterColor:'rgba(0,0,0,0)', left: `${leftWidth}px`}"
+			@click.stop="">
+			<div class="block-inner flex" :style="{backgroundColor:blockBackgroundColor}"  @touchmove.stop.prevent="blockTouchMove" @touchend="blockTouchEnd" @touchstart="blockTouchStart">
+				<div class="block-inner-inner" :style="{backgroundColor:blockColor}">
+					
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+	export default{
+		props:{
+			min:{
+				type:Number,
+				default:0
+			},
+			max:{
+				type:Number,
+				default:0
+			},
+			value:{
+				type:Number,
+				default:0
+			},
+			width:{
+				type:Number,
+				default:0
+			},
+			ratio:{
+				type:Number,
+				default:1
+			},
+			direction:{
+				type:String,
+				default:'screenX'
+			},
+			backgroundColor:{ //滑块右侧背景条的颜色
+				type:String,
+				default:'#e9e9e9'
+			},
+			blockColor:{ //滑块颜色
+				type:String,
+				default:'#ffffff'
+			},
+			screenLeft:{ //slider距离左边距离
+				type:Number,
+				default:0
+			},
+			iosDirection:{
+				type:Number,
+				default:1
+			}
+		},
+		data(){
+			return{
+				oldToucesX:0,
+				leftWidth:0,
+				oldLeftWidth:0,
+				touch:false
+			}
+		},
+		mounted() {
+			
+			
+		},
+		methods:{
+			sliderTouch(e){
+				console.log(e)
+				let touches = e.changedTouches[0]
+				this.leftWidth = (touches[this.direction]||touches['clientX'])*this.ratio-this.screenLeft
+				this.leftWidth = this.leftWidth > this.currentWidth? this.currentWidth : this.leftWidth
+				this.leftWidth = this.leftWidth < 0? 0 : this.leftWidth
+				this.blockTouchEnd()
+				
+			},
+			// 触摸开始
+			blockTouchStart(e) {
+				this.touch = true
+				this.oldLeftWidth = this.leftWidth
+				this.oldToucesX = e.changedTouches[0][this.direction]||e.changedTouches[0]['clientX'];
+			},
+			// 计算方向
+			blockTouchMove(e) {
+				let newToucesX
+				
+				newToucesX= e.changedTouches[0][this.direction]||e.changedTouches[0]['clientX'];
+				
+				this.leftWidth = this.iosDirection*(newToucesX - this.oldToucesX)*this.ratio+ this.oldLeftWidth
+				this.leftWidth = this.leftWidth > this.currentWidth? this.currentWidth : this.leftWidth
+				this.leftWidth = this.leftWidth < 0? 0 : this.leftWidth
+				
+			},
+			// 结束触摸
+			blockTouchEnd(e) {
+				let current = this.leftWidth / this.currentWidth *this.max
+				const event = {detail:{value:current}}
+				this.$emit('change',event)
+				this.touch = false
+			},
+			colorRgb(string,opacity){
+				var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
+				var sColor = string.toLowerCase();
+				if(sColor && reg.test(sColor)){
+				    if(sColor.length === 4){
+				        var sColorNew = "#";
+				        for(var i=1; i<4; i+=1){
+				            sColorNew += sColor.slice(i,i+1).concat(sColor.slice(i,i+1));   
+				        }
+				        sColor = sColorNew;
+				    }
+				    //处理六位的颜色值
+				    var sColorChange = [];
+				    for(var i=1; i<7; i+=2){
+				        sColorChange.push(parseInt("0x"+sColor.slice(i,i+2)));  
+				    }
+				    return "rgba(" + sColorChange.join(",") +`,${opacity}`+")";
+				}else{
+				    return sColor;  
+				}
+			}
+		},
+		computed:{
+			blockOuterColor(){
+				return this.colorRgb(this.blockColor,0.4)
+			},
+			blockBackgroundColor(){
+				return this.colorRgb(this.blockColor,0.5)
+			},
+			currentWidth(){
+				return this.width - 40
+			}
+		},
+		watch:{
+			value:{
+				immediate:true,
+				handler(newVal,oldVal){
+					if(this.touch) return
+					
+					this.leftWidth = newVal/this.max * this.currentWidth
+					this.leftWidth = this.leftWidth > this.currentWidth? this.currentWidth : this.leftWidth
+				}
+			}
+			
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.flex{
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		
+	}
+	.slider{
+		position: relative;
+		flex-direction: row;
+		height: 40px;
+		align-items: center;
+		
+		justify-content: center;
+	}
+	.slider-left{
+		height: 40px;
+		flex-direction: row;
+		align-items: center;
+	}
+	.left{
+		flex: 1;
+		height: 3px;
+	}
+	.slider-right{
+		height: 40px;
+		flex-direction: row;
+		align-items: center;
+	}
+	.right{
+		height: 3px;
+		background-color: rgba(0,0,0,0.3);
+		flex: 1;
+	}
+	.block{
+		position: absolute;
+		height: 40px;
+		width: 40px;
+		border-radius: 20px;
+		justify-content: center;
+		align-items: center;
+		z-index: 999999;
+	}
+	.block-inner{
+		height: 20px;
+		width: 20px;
+		border-radius: 10px;
+		justify-content: center;
+		align-items: center;
+	}
+	.block-inner-inner{
+		height: 10px;
+		width: 10px;
+		border-radius: 5px;
+		
+	}
+</style>

+ 280 - 0
components/chunlei-video/chunlei-video.nvue

@@ -0,0 +1,280 @@
+<template>
+	<view class="video">
+		<video :src="src" :controls="controls" :show-center-play-btn="controls" :show-play-btn="controls" play-btn-position="center" autoplay="true" :muted="!load||!play"
+			:style="{ height: height }" :loop="true" @controlstoggle="controlstoggle" @fullscreenchange="screenChange" @play="continuePlay"
+			:enable-progress-gesture="false" :objectFit="objectFit" @ended="playEnd" :initial-time="startTime"
+			:id="`video_${src}`" ref="`video_${src}`" class="video" @timeupdate="timeupdate">
+		</video>
+		<cover-view class="icon-view" v-if="!play&&!playFirst">
+			<!-- <text class="icon" style="color:#FFF">&#xe896;</text> -->
+		</cover-view>
+		<cover-image class="img" :style="{ height: height }" :src="poster" v-if="poster!=''&&playFirst"></cover-image>
+		<cover-view class="top"></cover-view>
+		<!-- <cover-view class="bottom"></cover-view> -->
+		<!-- #ifdef APP-PLUS -->
+		<cover-view class="danmu-view">
+			<chunLei-danmu :danmuList="danmuList" :width="750"  :current="time" ref="danmu"></chunLei-danmu>
+		</cover-view>
+		<!-- #endif -->
+		<!-- #ifndef MP-WEIXIN -->
+		<cover-view class="slider-view">
+			<chunLei-slider :max="duration" :value="time" :style="{width:`${100}%`}" :screenLeft="120" :width="380" @change="changeCurrent"></chunLei-slider>
+		</cover-view>
+		<cover-image :src="rotateImg" class="rotate-img" :style="{transform:`rotate(${time*20}deg)`}"></cover-image>
+		<!-- #endif -->
+		<!-- #ifdef MP-WEIXIN -->
+		<!-- <cover-view class="progressBar" :style="{ width: barWidth }"></cover-view> -->
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+	
+	import chunLeiSlider from './chunLei-slider/chunLei-slider.nvue';
+	//#ifdef APP-NVUE
+	import chunLeiDanmu from './chunLei-danmu/chunLei-danmu.nvue';
+	//#endif
+	export default{ 
+		components:{
+			chunLeiSlider,
+			//#ifdef APP-NVUE
+			chunLeiDanmu
+			//#endif
+		},
+		props:{
+			controls:{
+				type:Boolean,
+				default:false
+			},
+			src:{
+				type:String,
+				default:''
+			},
+			rotateImg:{
+				type:String,
+				default:''
+			},
+			play:{
+				type:Boolean,
+				default:false
+			},
+			height:{
+				type:String,
+				default:''
+			},
+			width:{
+				type:String,
+				default:''
+			},
+			initialTime:{
+				type:Number,
+				default:0
+			},
+			gDuration:{
+				type:Number,
+				default:999
+			}, //大概时长使进度条更准确
+			objectFit:{
+				type:String,
+				default:'contain'
+			},
+			poster:{ //视频封面的图片
+				type:String,
+				default:''
+			},
+			danmuList:{
+				type:Array,
+				default:[]
+			}
+		},
+		data(){
+			return{
+				time:0,
+				duration:0,
+				playFirst:true,
+				load:false,
+				timer:null
+			}
+		},
+		beforeCreate() {
+			// #ifdef APP-NVUE
+			var domModule = weex.requireModule('dom');
+			domModule.addRule('fontFace', {
+				'fontFamily': "texticons",
+				'src': "url('//static/chunlei-video/text-icon.ttf')"
+			});
+			// #endif
+		},
+		mounted() {
+			this.videoCtx = uni.createVideoContext(`video_${this.src}`,this)
+			//#ifndef MP-WEIXIN
+			setTimeout(()=>{this.videoCtx.play();},200)
+			// #endif
+		},
+		methods:{
+			continuePlay(){
+				if(!this.load){
+					this.load = true
+					this.videoPlay()
+				}
+			},
+			//拖动滑块
+			changeCurrent(e){
+				this.time = e.detail.value
+				this.videoCtx.seek(this.time)
+			},
+			screenChange(e){
+				//console.log(e.detail.fullScreen);
+				this.$emit('screenChange',e.detail.fullScreen)
+			},
+			controlstoggle(e){
+				console.log(e.detail.show);
+				//console.log(99999999);
+				this.$emit('controlstoggle',e.detail.show)
+			},
+			
+			playEnd(){
+				// console.log(2222222);
+				this.videoCtx.exitFullScreen()
+				this.$emit('playEnd')
+			},
+			timeupdate(event){
+				this.duration = event.detail.duration
+				if(this.time>=event.detail.duration) this.time=0
+				this.time = event.detail.currentTime
+				this.$emit('timeupdate',this.time)
+			},
+			videoPlay:function(){
+				if(this.timer) clearTimeout(this.timer)
+				this.timer = setTimeout(()=>{
+					console.log(this.play)
+					if(this.play){
+						this.videoCtx.play();
+						this.playFirst = false
+					}else{
+						this.videoCtx.pause();
+						this.$emit('pause',this.time)
+					}
+				})
+			},
+		},
+		watch:{
+			//防抖 防止视频播放暂停太快
+			play: function (newVal,oldVal){if(this.load) this.videoPlay()},
+			startTime:{
+				immediate: true,
+				handler(newVal,oldVal){
+					this.time = newVal
+				}
+			},
+			gDuration:{
+				immediate: true,
+				handler(newVal,oldVal){
+					this.duration = newVal
+				}
+			}
+		},
+		computed:{
+			barWidth(){
+				let width = this.time/this.duration*parseInt(this.width)
+				return `${width}px`
+			},
+			startTime(){
+				return this.initialTime
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	/* #ifndef APP-PLUS-NVUE */
+	@font-face {
+		font-family: "texticons";
+		src: url('~@/static/chunlei-video/text-icon.ttf') format('truetype');
+	}
+	/* #endif*/
+	.video{
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		width: 750rpx;
+		
+		justify-content: center;
+		align-items: center;
+	}
+	.img{
+		position: absolute;
+		
+		width: 750rpx;
+	}
+	.icon-view{
+		position: absolute;
+	}
+	.top{
+		position: absolute;
+		top:0;
+		background-image: linear-gradient(to top , rgba(0,0,0,0) , rgba(0,0,0,0.7));
+		width: 750rpx;
+		height: 300rpx;
+	}
+	.icon{
+		opacity: 0.6;
+		font-size: 42px;
+		color: #fff;
+		/* #ifndef APP-PLUS-NVUE */
+		font-family: "texticons";
+		/* #endif*/
+		font-family: texticons;
+	}
+	.bottom{
+		position: absolute;
+		bottom: 0;
+		background-image: linear-gradient(to top , rgba(0,0,0,0.7) , rgba(0,0,0,0));
+		width: 750rpx;
+		height: 300rpx;
+	}
+	.slider-view{
+		position: absolute;
+		left: 0;
+		bottom: 0px;
+		width: 750rpx;
+	}
+	.progressBar{
+		border-radius: 2upx;
+		height: 4upx;
+		background-color: #FFFFFF;
+		z-index: 999999;
+		position: absolute;
+		left: 0;
+		bottom: 30px;
+		//#ifndef APP-PLUS-NVUE
+		animation: flicker 4s linear infinite;
+		animation-direction:alternate;
+		//#endif
+	}
+	//#ifndef APP-PLUS-NVUE
+	@keyframes flicker {
+		0% { box-shadow:0 0 0 #FFFFFF; }
+	     /** 暂停效果 */
+		10% { box-shadow:0 0 2upx #FFFFFF; }
+	    50% { box-shadow:0 0 10upx #FFFFFF; }
+	    60% { box-shadow:0 0 12upx #FFFFFF; }
+	    90% { box-shadow:0 0 18upx #FFFFFF; }
+	    100% { box-shadow:0 0 20upx #FFFFFF; }
+	
+	}
+	//#endif
+	.danmu-view{
+		position: absolute;
+		top:0;
+		height: 160px;
+	}
+	.rotate-img{
+		width: 90rpx;
+		height: 90rpx;
+		position: absolute;
+		bottom: 100rpx;
+		right: 20rpx;
+		border-radius: 45rpx;
+	}
+</style>

+ 26 - 0
components/common/copyright.vue

@@ -0,0 +1,26 @@
+<template>
+	<view class="copyright">
+		<image :src="statics.copyright"></image>
+	</view>
+</template>
+
+<script>
+	export default{
+		data(){
+			return {
+				
+			}
+		}
+	}
+</script>
+
+<style>
+	.copyright{
+		padding: 48rpx;
+		text-align: center;
+	}
+	.copyright image{
+		width: 208rpx;
+		height: 76rpx;
+	}
+</style>

+ 31 - 0
components/common/empty.vue

@@ -0,0 +1,31 @@
+<template>
+	<view class="empty-box">
+		<image :src="statics.emptyImg" style="width: 296rpx; height: 296rpx;"></image>
+		<view class="ft14 cl-notice mt20">
+			{{title}}
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			title:{
+				type:String,
+				default:'暂无普通用户优惠券',
+			}
+		},
+		data(){
+			return {
+				
+			}
+		}
+	}
+</script>
+
+<style>
+	.empty-box{
+		padding: 60rpx;
+		text-align: center;
+	}
+</style>

+ 145 - 0
components/common/footer.vue

@@ -0,0 +1,145 @@
+<template>
+	<view class="footer-h" v-if="isShowFooter">
+		<view class="footer-box footer-h">
+			<view class="footer-main flex space">
+				<view v-for="(item,index) in getFooter" :key="index" :data-model="item.model" @click="linkTo" class="footer-item" :style="{width:getWidth,color:model== item.model ? tempColor : '#AEB2C1'}">
+					<text class="ft22 iconfont" :class="item.icon"></text>
+					<view class="ft12 mt4 ftw600">{{item.name}}</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			model:{
+				type:String,
+				default:'',
+			},
+		},
+		data(){
+			return {
+				footerList:[
+					{name:'首页',icon:'icontabbar03',model:'index',show:1},
+					{name:'全部列表',icon:'icontabbar01',model:'tuan',show:1},
+					{name:'次卡',icon:'icontabbar03',model:'card',show:0},
+					{name:'优惠券',icon:'icontabbar06',model:'coupon',show:0}, //预留其他组件
+					{name:'积分商城',icon:'icontabbar05',model:'integral',show:0},
+					{name:'个人中心',icon:'icontabbar04',model:'member',show:1},
+				]
+				// footerList:[
+				// 	{name:'VIP',icon:'icontabbar01',model:'index',show:1},
+				// 	{name:'特惠',icon:'icontabbar02',model:'tuan',show:1},
+				// 	{name:'次卡',icon:'icontabbar03',model:'card',show:1},
+				// 	{name:'优惠券',icon:'icontabbar06',model:'coupon',show:0}, //预留其他组件
+				// 	{name:'积分商城',icon:'icontabbar05',model:'integral',show:1},
+				// 	{name:'我的',icon:'icontabbar04',model:'member',show:1},
+				// ]
+			}
+		},
+		computed:{
+			isShowFooter(){
+				let show = false;
+				for(var a  in this.footerList){
+					if(this.footerList[a].model == this.model && this.footerList[a].show == 1){
+						show = true;
+					}
+				}
+				return show;
+			},
+			getFooter(){
+				let arr = new Array;
+				for(var a  in this.footerList){
+					if(this.footerList[a].show == 1){
+						arr.push(this.footerList[a]);
+					}
+				}
+				return arr;
+			},
+			getWidth(){
+				let len = this.getFooter.length;
+				if(len > 0){
+					return  (100/len) + '%';
+				}
+				return  '100%';
+			}
+		},methods:{
+			linkTo(e){ //链接相关的操作 这个操作一般在首页 和底部菜单出现,其他地方的请另外操作
+				let model = e.currentTarget.dataset.model;
+				if(this.model == model) return;
+				if(model == 'index'){
+					let page = getCurrentPages();
+					if(page.length > 1){
+						uni.navigateBack({
+							delta:page.length
+						});
+					}else{
+						uni.reLaunch({
+							url:'/pages/client/index'
+						})
+					}
+					return;
+				}
+				let url = '';
+				switch(model){
+					case 'tuan':
+						url = '/pages/client/tuan/index';
+					break;
+					case 'coupon':
+						url = '/pages/client/coupon/index';
+					break;
+					case  'card':
+						url = '/pages/client/card/index';
+					break;
+					case 'member':
+						url = '/pages/client/member/index';
+					break;
+					case 'integral':
+						url = '/pages/client/integral/index'
+					break;
+				}
+				if(url == '') return;
+				if(this.model == 'index'){
+					uni.navigateTo({
+						url:url
+					})
+				}else{
+					uni.redirectTo({
+						url:url
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+	.footer-h {
+		height: 100rpx;
+		height: calc(100rpx + constant(safe-area-inset-bottom));
+		height: calc(100rpx + env(safe-area-inset-bottom));
+	}
+	
+	.footer-box {
+		width: 100%;
+		position: fixed;
+		z-index: 100;
+		left: 0;
+		bottom: 0;
+		background: #FFFFFF;
+		box-shadow: 0rpx -4rpx 16rpx 0rpx rgba(0, 0, 0, 0.04);
+	}
+	
+	.footer-main {
+		height: 100rpx;
+	}
+	
+	.footer-item {
+		height: 100rpx;
+		width: 20%;
+		padding-top: 10rpx;
+		text-align: center;
+	}
+</style>

+ 125 - 0
components/common/tuij.vue

@@ -0,0 +1,125 @@
+<view class="pd16_15">
+				<navigator url="/pages/client/tuan/detail">
+				<view class="box pd16_15 flex alcenter mb16">
+					<image class="tuan-product-l"></image>
+					<view class="tuan-product-r pl15">
+						<view class="ft14 ftw600 cl-main text-over2">洗剪吹加护理一次套餐 会员只需5…</view>
+						<view class="mt16">
+							<text class="ft12 cl-orange">会员价</text>
+							<text class="ft12 cl-orange">¥</text>
+							<text class="ft16 cl-orange ftw600">58</text>
+							<text class="ml15 ft12 cl-notice text-line">¥88</text>
+						</view>
+						<view class="mt16 flex space alcenter">
+							<view class="ft12 cl-notice">868次</view>
+							<view class="btn-mini" :style="getBtnStyle">播放</view>
+						</view>
+					</view>
+				</view>
+				</navigator>
+				
+				<view class="box pd16_15 flex alcenter mb16">
+					<image class="tuan-product-l"></image>
+					<view class="tuan-product-r pl15">
+						<view class="ft14 ftw600 cl-main text-over2">洗剪吹加护理一次套餐 会员只需5…</view>
+						<view class="mt16">
+							<text class="ft12 cl-orange">会员价</text>
+							<text class="ft12 cl-orange">¥</text>
+							<text class="ft16 cl-orange ftw600">58</text>
+							<text class="ml15 ft12 cl-notice text-line">¥88</text>
+						</view>
+						<view class="mt16 flex space alcenter">
+							<view class="ft12 cl-notice">868次</view>
+							<view class="btn-mini" :style="getBtnStyle">播放</view>
+						</view>
+					</view>
+				</view>
+				
+				<view class="box pd16_15 flex alcenter mb16">
+					<image class="tuan-product-l"></image>
+					<view class="tuan-product-r pl15">
+						<view class="ft14 ftw600 cl-main text-over2">洗剪吹加护理一次套餐 会员只需5…</view>
+						<view class="mt16">
+							<text class="ft12 cl-orange">会员价</text>
+							<text class="ft12 cl-orange">¥</text>
+							<text class="ft16 cl-orange ftw600">58</text>
+							<text class="ml15 ft12 cl-notice text-line">¥88</text>
+						</view>
+						<view class="mt16 flex space alcenter">
+							<view class="ft12 cl-notice">868次</view>
+							<view class="btn-mini" :style="getBtnStyle">播放</view>
+						</view>
+					</view>
+				</view>
+				
+				<view class="box pd16_15 flex alcenter mb16">
+					<image class="tuan-product-l"></image>
+					<view class="tuan-product-r pl15">
+						<view class="ft14 ftw600 cl-main text-over2">洗剪吹加护理一次套餐 会员只需5…</view>
+						<view class="mt16">
+							<text class="ft12 cl-orange">会员价</text>
+							<text class="ft12 cl-orange">¥</text>
+							<text class="ft16 cl-orange ftw600">58</text>
+							<text class="ml15 ft12 cl-notice text-line">¥88</text>
+						</view>
+						<view class="mt16 flex space alcenter">
+							<view class="ft12 cl-notice">868次</view>
+							<view class="btn-mini" :style="getBtnStyle">播放</view>
+						</view>
+					</view>
+				</view>
+		</view>
+
+<script>
+	export default{
+		props:{
+			model:{
+				type:String,
+				default:'',
+			},
+		},
+		data(){
+			return {
+				footerList:[
+					{name:'首页',icon:'icontabbar03',model:'index',show:1},
+					{name:'全部列表',icon:'icontabbar01',model:'tuan',show:1},
+					{name:'次卡',icon:'icontabbar03',model:'card',show:0},
+					{name:'优惠券',icon:'icontabbar06',model:'coupon',show:0}, //预留其他组件
+					{name:'积分商城',icon:'icontabbar05',model:'integral',show:0},
+					{name:'个人中心',icon:'icontabbar04',model:'member',show:1},
+				]
+				// footerList:[
+				// 	{name:'VIP',icon:'icontabbar01',model:'index',show:1},
+				// 	{name:'特惠',icon:'icontabbar02',model:'tuan',show:1},
+				// 	{name:'次卡',icon:'icontabbar03',model:'card',show:1},
+				// 	{name:'优惠券',icon:'icontabbar06',model:'coupon',show:0}, //预留其他组件
+				// 	{name:'积分商城',icon:'icontabbar05',model:'integral',show:1},
+				// 	{name:'我的',icon:'icontabbar04',model:'member',show:1},
+				// ]
+			}
+		},
+		computed:{
+
+		},
+		methods:{
+
+		}
+	}
+</script>
+
+<style>
+	.member-face .face{
+		width: 160rpx;
+		height: 160rpx;
+		border:6rpx solid #FFFFFF;
+		background: #FFFFFF;
+		border-radius: 100rpx;
+		box-shadow: 0rpx 24rpx 48rpx 0rpx rgba(197, 202, 219, 0.3);
+	}
+	.miniapp-icon{
+		width: 48rpx;
+		height: 48rpx;
+		border-radius: 24rpx;
+		background: #F2F2F2;
+	}
+</style>

+ 90 - 0
components/countdown/time.vue

@@ -0,0 +1,90 @@
+<template>
+	<view>
+		<view class="flex alcenter">
+			<text class="order-t"  :class="size" :style="{background:bgColor,color:color}">{{showT.h}}</text><text class="ft12 ftw600 plr5">:</text>
+			<text class="order-t"  :class="size" :style="{background:bgColor,color:color}">{{showT.m}}</text><text class="ft12 ftw600 plr5">:</text>
+			<text class="order-t"   :class="size" :style="{background:bgColor,color:color}">{{showT.s}}</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	import  helper from '@/static/js/helper.js';
+	
+	export default{
+		props:{
+			t:{
+				type:Number,
+				default:0,
+			},
+			size:{
+				type:String,
+				default:''
+			},
+			bgColor:{
+				type:String,
+				default:'#2E2F33'
+			},
+			color:{
+				type:String,
+				default:'#ffffff'
+			}
+		},
+		data(){
+			return {
+				myT:0,
+				timer:null,
+			}
+		},
+		computed:{
+			showT(){
+				let myT = this.myT;
+				
+				return helper.djsFull(myT);
+			}
+		},
+		created(){
+			this.myT = this.t;
+			this.djs();
+		},
+		destroyed(){
+			if(this.timer != null){
+				clearInterval(this.timer);
+			}
+		},
+		methods:{
+			djs(){
+				if(this.timer){
+					clearInterval(this.timer);
+				}	
+				this.timer = setInterval(()=>{
+					if(this.myT == 0){
+						clearInterval(this.timer);
+					}else{
+						this.myT = this.myT - 1;
+					}
+				},1000);
+			}
+		}
+	}
+</script>
+
+<style>
+	.order-t{
+		width:48rpx;
+		height:48rpx;
+		background:#FFFFFF;
+		text-align: center;
+		line-height: 48rpx;
+		font-size:28rpx;
+		font-weight: 500;
+		color: #000000;
+		border-radius: 8rpx;
+	}
+	.order-t.small{
+		width: 40rpx;
+		height: 40rpx;
+		font-size: 24rpx;
+		line-height: 40rpx;
+	}
+</style>

+ 95 - 0
components/dialog/ach.vue

@@ -0,0 +1,95 @@
+<template>
+	<view class="ach-modal">
+		<view  class="modal-bg"></view>
+		<view class="modal-box animated fast"  :class="show   ? 'slideInUp' : 'slideOutDown'">
+			<view class="modal-main">
+				<view class="closed">
+					<text @click="closed()" class="iconfont  ft20 cl-notice iconbtn_close"></text>
+				</view>
+				<view class="lh20 ft16 cl-main ftw600 text-center">不予通过</view>
+				
+				
+				<view class=" pd16_15">
+					<view class="ft14 cl-info2">不过理由</view>
+					<view class="mt16">
+						<textarea placeholder="请输入拒绝的理由" class="ft14 cl-main" placeholder-class="cl-notice"></textarea>
+					</view>
+				</view>
+				
+			</view>
+			<view class="bg-w mt16 pd10_15" style="box-shadow: 0rpx -4rpx 16rpx 0rpx rgba(0, 0, 0, 0.04);">
+				<button class="btn-manage">确定</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	
+	
+	export  default{
+		props:{
+			id:{
+				type:Number,
+				default:0
+			},
+		},
+		data(){
+			return {
+			
+				show:false,
+			}
+		},
+		created(){
+			this.show = true;
+		},
+		methods:{
+		
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.$emit('closed');
+				},400);
+			}
+		}
+	}
+</script>
+
+<style>
+	.ach-modal{
+		position: relative;
+		z-index: 400;
+	}
+	.ach-modal .modal-bg{
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+	}
+	.ach-modal .modal-box{
+		position: fixed;
+		z-index: 401;
+		background:#FFFFFF;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		padding-bottom:0rpx;
+		padding-bottom:constant(safe-area-inset-bottom);
+		padding-bottom:env(safe-area-inset-bottom);
+		border-radius:32rpx 32rpx 0rpx 0rpx;
+	}
+	.ach-modal .modal-main{
+		position: relative;
+		height: auto;
+		overflow: hidden;
+		padding-top: 64rpx;
+	}
+	.ach-modal .modal-main .closed{
+		position: absolute;
+		right: 40rpx;
+		top: 40rpx;
+	}
+</style>

+ 140 - 0
components/dialog/birthday.vue

@@ -0,0 +1,140 @@
+<template>
+	<view  class="birthday-modal-middle">
+		<view  class="bg"></view>
+		<view class="birthday-modal-middle-main" :class=" show ? 'animated fast zoomInUp' :'animated fast  zoomOutDown'">
+			<view class="middle-main">
+				<view @click="closed" class="middle-closed">
+					<text class="iconfont  iconbtn_close cl-notice ft20"></text>
+				</view>
+				<view class="text-center">
+					<text class="ft16 ftw600 cl-main">{{title}}</text>
+				</view>
+				<view class="text-center mt24">
+					<image :src="statics.birthdayPic" style="width: 412rpx; height: 296rpx;"></image>
+				</view>
+				<view class="mt24" style="max-height: 400rpx; overflow-y: scroll;">
+					<view class="birthday-gift-box pd16_15">
+						<view class="flex alcenter space">
+							<text class="ft14 cl-main">专业洗剪吹3次</text>
+							<text class="ft12 cl-notice">x1</text>
+						</view>
+						<view class="mt8 ft12 cl-orange">价值¥188</view>
+					</view>
+					
+					<view class="birthday-gift-box pd16_15 mt8">
+						<view class="flex alcenter space">
+							<text class="ft14 cl-main">专业洗剪吹3次</text>
+							<text class="ft12 cl-notice">x1</text>
+						</view>
+						<view class="mt8 ft12 cl-orange">价值¥188</view>
+					</view>
+					<view class="birthday-gift-box pd16_15 mt8">
+						<view class="flex alcenter space">
+							<text class="ft14 cl-main">专业洗剪吹3次</text>
+							<text class="ft12 cl-notice">x1</text>
+						</view>
+						<view class="mt8 ft12 cl-orange">价值¥188</view>
+					</view>
+				</view>
+			</view>
+			<view v-if="showOnly ==  false" class="birthday-get-btn" :style="{background:tempColor}">确定领取</view>
+		</view>	
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			title:{
+				type:String,
+				default:'祝你生日快乐'
+			},
+			datas:{
+				type:Array,
+				default:function(){
+					return new Array;
+				}
+			},
+			showOnly:{
+				type:Boolean,
+				default:false
+			}
+		},
+		data(){
+			return {
+				show:false,
+			}
+		},
+		created(){
+			this.show = true;
+		},
+		methods:{
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.$emit('closed',true);
+				},400)
+			}	
+		}
+	}
+</script>
+
+<style>
+	.birthday-modal-middle{
+		width: 100%;
+		height: 100vh;
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		
+	}
+	.birthday-modal-middle .bg{
+		position: fixed;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+		z-index: 401;
+		left: 0;
+		top: 0;
+	}
+	.birthday-modal-middle-main{
+		width: 690rpx;
+		background: #F5F6FA;
+		border-radius: 32rpx;
+		position: fixed;
+		top: 50%;
+		left: calc(50% - 345rpx);
+		transform:translateY(-50%);
+		z-index: 402;
+		overflow: hidden;
+	}
+	.birthday-modal-middle-main .middle-main{
+		position: relative;
+		padding: 64rpx 30rpx 30rpx 30rpx;
+	}
+	.birthday-modal-middle-main .middle-closed{
+		position: absolute;
+		width: 40rpx;
+		height: 40rpx;
+		right: 50rpx;
+		top: 50rpx;
+		text-align: center;
+		line-height: 40rpx;
+	}
+	.birthday-gift-box{
+		width: 100%;
+		height: 148rpx;
+		background: #FFFFFF;
+		border-radius: 8rpx;
+	}
+	.birthday-get-btn{
+		width: 100%;
+		height: 96rpx;
+		text-align: center;
+		font-size: 32rpx;
+		color:#FFFFFF;
+		font-weight: 500;
+		line-height: 96rpx;
+	}
+</style>

+ 89 - 0
components/dialog/cardsend.vue

@@ -0,0 +1,89 @@
+<template>
+	<view class="cardsend-modal">
+		<view  class="modal-bg"></view>
+		<view class="modal-box animated fast" :class="show   ? 'slideInUp' : 'slideOutDown'">
+			<view class="modal-main">
+				<view class="closed">
+					<text @click="closed()" class="iconfont  ft20 cl-notice iconbtn_close"></text>
+				</view>
+				<view class="lh20 ft16 cl-main ftw600 text-center">赠送好友</view>
+				<view class="text-center ft16 ftw600 text-over mt40">【VIP洗剪吹次卡】</view>
+				<view class="mt32 plr15">
+					<view class="box pd16_15">
+						<input placeholder="输入对方手机号" type="number" placeholder-class="cl-info2"  class="ft16 ftw600 text-center"/>
+					</view>
+					<view class="text-center mt16 ft14 cl-orange lh20">手机号不存在,请重新输入</view>
+				</view>
+			</view>
+			<view class="pd10_15 bg-w mt60">
+				<button class="btn-big" :style="getBtnStyle">确定赠送</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	
+	export  default{
+		props:{
+		
+		},
+		data(){
+			return {
+				show:false,
+			}
+		},
+		created(){
+			this.show = true;
+		
+		},
+		methods:{
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.$emit('closed');
+				},400);
+			}
+		}
+	}
+</script>
+
+<style>
+	.cardsend-modal{
+		position: relative;
+		z-index: 400;
+	}
+	.cardsend-modal .modal-bg{
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+	}
+	.cardsend-modal .modal-box{
+		position: fixed;
+		z-index: 401;
+		background: #F5F6FA;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		padding-bottom:0rpx;
+		padding-bottom:constant(safe-area-inset-bottom);
+		padding-bottom:env(safe-area-inset-bottom);
+		border-radius:32rpx 32rpx 0rpx 0rpx;
+	}
+	.cardsend-modal .modal-main{
+		position: relative;
+		height: auto;
+		overflow: hidden;
+		padding-top: 64rpx;
+		padding-bottom: 40rpx;
+	}
+	.cardsend-modal .modal-main .closed{
+		position: absolute;
+		right: 40rpx;
+		top: 40rpx;
+	}
+</style>

+ 129 - 0
components/dialog/couponshare.vue

@@ -0,0 +1,129 @@
+<template>
+	<view  class="couponshare-modal-middle">
+		<view  class="bg"></view>
+		<view class="couponshare-modal-middle-main" :class=" show ? 'animated fast zoomInUp' :'animated fast  zoomOutDown'">
+			<view class="middle-main">
+				<view @click="closed" class="middle-closed">
+					<text class="iconfont  iconbtn_close  ft20"></text>
+				</view>
+				<view class="pd20_15">
+					<view class="ft14 cl-w">恭喜您!支付成功</view>
+					<view class="ft16 ftw500 cl-yellow mt8">分享好友一起领券吧</view>
+				</view>
+				<view class="text-center">
+					<image :src="statics.couponAlert[0]" style="width: 260rpx; height: 260rpx;"></image>
+				</view>
+				<image :src="statics.couponAlert[2]" class="footer-bg"></image>
+				<view class="footer-act-main">
+					<button open-type="share" class="share-btn">邀好友领券</button>
+				</view>
+			</view>
+		</view>	
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			
+		},
+		data(){
+			return {
+				show:false,
+			}
+		},
+		created(){
+			this.show = true;
+		},
+		methods:{
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.$emit('closed',true);
+				},400)
+			}	
+		}
+	}
+</script>
+
+<style>
+	.couponshare-modal-middle{
+		width: 100%;
+		height: 100vh;
+		position: fixed;
+		z-index: 200;
+		left: 0;
+		top: 0;
+		
+	}
+	.couponshare-modal-middle .bg{
+		position: fixed;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+		z-index: 201;
+		left: 0;
+		top: 0;
+	}
+	.couponshare-modal-middle-main{
+		width: 630rpx;
+		background: #FD4E4A;
+		border-radius: 32rpx;
+		position: fixed;
+		top: 50%;
+		left: calc(50% - 315rpx);
+		transform:translateY(-50%);
+		z-index: 202;
+		overflow: hidden;
+	}
+	.couponshare-modal-middle-main .middle-main{
+		position: relative;
+		height: 576rpx;
+		width: 100%;
+	}
+	.couponshare-modal-middle-main .middle-closed{
+		position: absolute;
+		width: 80rpx;
+		height: 80rpx;
+		right:0rpx;
+		top: 0rpx;
+		text-align: center;
+		line-height: 80rpx;
+		text-align: center;
+		background: rgba(0,0,0,0.5);
+		color:#FFFFFF;
+		border-radius: 0rpx 0rpx 0rpx 32rpx;
+	}
+	.couponshare-modal-middle-main .footer-bg{
+		width: 100%;
+		height: 160rpx;
+		position: absolute;
+		left: 0;
+		bottom: 0;
+	}
+	.couponshare-modal-middle-main .footer-act-main{
+		width: 100%;
+		height: 160rpx;
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+	}
+	.couponshare-modal-middle-main .footer-act-main .share-btn{
+		width: 330rpx;
+		height: 80rpx;
+		background: linear-gradient(180deg, #FFF6D6 0%, #FFE388 100%);
+		box-shadow: 0rpx 8rpx 24rpx 0rpx rgba(0, 0, 0, 0.08);
+		border-radius: 40rpx;
+		color:#F14844;
+		font-size: 32rpx;
+		font-weight: 500;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		margin: 0;
+		padding: 0;
+	}
+</style>

+ 137 - 0
components/dialog/couponshareget.vue

@@ -0,0 +1,137 @@
+<template>
+	<view  class="couponshareget-modal-middle">
+		<view  class="bg"></view>
+		<view class="couponshareget-modal-middle-main" :class=" show ? 'animated fast zoomInUp' :'animated fast  zoomOutDown'">
+			<view class="middle-main">
+				<view @click="closed" class="middle-closed">
+					<text class="iconfont  iconbtn_close  ft20"></text>
+				</view>
+				<view class="pd20_15">
+					<view class="flex alcenter"><image :src="statics.defaultFace" class="coupon-share-get-face"></image> <text class="ml10 ft14 cl-w">张华邀请您</text></view>
+					<view class="ft16 ftw500 cl-yellow mt8">一起领取优惠券</view>
+				</view>
+				<view class="text-center">
+					<image :src="statics.couponAlert[1]" style="width: 240rpx; height: 240rpx;"></image>
+				</view>
+				<image :src="statics.couponAlert[2]" class="footer-bg"></image>
+				<view class="footer-act-main">
+					<button @click="getAct" class="share-btn">立即领取</button>
+				</view>
+			</view>
+		</view>	
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			
+		},
+		data(){
+			return {
+				show:false,
+			}
+		},
+		created(){
+			this.show = true;
+		},
+		methods:{
+			getAct(){
+				this.$emit('loginAct');
+			},
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.$emit('closed',true);
+				},400)
+			}	
+		}
+	}
+</script>
+
+<style>
+	.couponshareget-modal-middle{
+		width: 100%;
+		height: 100vh;
+		position: fixed;
+		z-index: 200;
+		left: 0;
+		top: 0;
+		
+	}
+	.couponshareget-modal-middle .bg{
+		position: fixed;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+		z-index: 201;
+		left: 0;
+		top: 0;
+	}
+	.couponshareget-modal-middle-main{
+		width: 630rpx;
+		background: #FD4E4A;
+		border-radius: 32rpx;
+		position: fixed;
+		top: 50%;
+		left: calc(50% - 315rpx);
+		transform:translateY(-50%);
+		z-index: 202;
+		overflow: hidden;
+	}
+	.couponshareget-modal-middle-main .middle-main{
+		position: relative;
+		height: 576rpx;
+		width: 100%;
+	}
+	.couponshareget-modal-middle-main .middle-closed{
+		position: absolute;
+		width: 80rpx;
+		height: 80rpx;
+		right:0rpx;
+		top: 0rpx;
+		text-align: center;
+		line-height: 80rpx;
+		text-align: center;
+		background: rgba(0,0,0,0.5);
+		color:#FFFFFF;
+		border-radius: 0rpx 0rpx 0rpx 32rpx;
+	}
+	.couponshareget-modal-middle-main .footer-bg{
+		width: 100%;
+		height: 160rpx;
+		position: absolute;
+		left: 0;
+		bottom: 0;
+	}
+	.couponshareget-modal-middle-main .footer-act-main{
+		width: 100%;
+		height: 160rpx;
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+	}
+	.couponshareget-modal-middle-main .footer-act-main .share-btn{
+		width: 330rpx;
+		height: 80rpx;
+		background: linear-gradient(180deg, #FFF6D6 0%, #FFE388 100%);
+		box-shadow: 0rpx 8rpx 24rpx 0rpx rgba(0, 0, 0, 0.08);
+		border-radius: 40rpx;
+		color:#F14844;
+		font-size: 32rpx;
+		font-weight: 500;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		margin: 0;
+		padding: 0;
+	}
+	.couponshareget-modal-middle-main .coupon-share-get-face{
+		width: 48rpx;
+		height: 48rpx;
+		border-radius: 24rpx;
+	}
+</style>

+ 140 - 0
components/dialog/dyxx.vue

@@ -0,0 +1,140 @@
+<template>
+	<view class="login-modal">
+		<view  class="modal-bg" :style="{zIndex:zindex}"></view>
+		<view class="modal-box animated fast" :style="{zIndex:zindex+1,background:bg}" :class="show   ? 'slideInUp' : 'slideOutDown'">
+			<view class="modal-main">
+				<view class="closed">
+					<text @click="closed()" class="iconfont  ft20 cl-notice iconbtn_close"></text>
+				</view>
+				<view class="lh20 ft16 cl-main ftw600 text-center">{{step == 0 ? '授权登录请求' : '授权手机号码'}}</view>
+				<view v-if="step == 0" class="mt60">
+						<view class="text-center ft14 cl-main">
+							点击登录 享受更多会员特惠?
+						</view>
+						<view class="mt40 flex alcenter center">
+							<button class="btn-mid" @click="closed()" :style="{color:tempColor,background:'#F5F6FA'}" style="width: 300rpx;">拒绝</button>
+							<button class="btn-mid" @click="getUserInfo" :style="{background:tempColor}" style="margin-left: 30rpx;width: 300rpx; color: #FFFFFF;">登录</button>
+						</view>
+				</view>
+				<view v-if="step == 1" class="mt60">
+						<view class="text-center ft14 cl-main">
+							点击登录 享受更多会员特惠
+						</view>
+						
+						<view class="plr30 mt40">
+							<button class="btn-big" :style="getBtnStyle">
+								<text class="iconfont iconicon_weixin mr10 ft20"></text>订阅消息
+							</button>
+						</view>
+				</view>
+				
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	
+	
+	export  default{
+		props:{
+			zindex:{
+				type:Number,
+				default:402,
+			},
+			bg:{
+				type:String,
+				default:'#ffffff',
+			},
+			
+		},
+		data(){
+			return {
+				show:false,
+				code:'',
+				mdata:'',
+				miv:'',
+				step:0, // 1
+			}
+		},
+		created(){
+			this.show = true;
+			// uni.login({
+			//   provider: 'weixin',
+			//   success: (loginRes)=> {
+			// 	  console.log(loginRes);
+			// 	this.code = loginRes.code;
+			//   },
+			//   fail:()=>{
+			// 	  uni.showToast({
+			// 	  	icon:'none',
+			// 		title:'小程序登录失败'
+			// 	  });
+			// 	  this.show = false;
+			//   }
+			// });
+		},
+		methods:{
+			getUserInfo(e){
+				// if(!e.detail.userInfo){
+				// 	this.closed();
+				// }else{
+				// 	this.mdata = e.detail.encryptedData;
+				// 	this.miv = e.detail.iv;
+				// 	this.step = 1;
+				// }
+				uni.navigateTo({
+					url:'/pages/login/login'
+				})
+			},
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.$emit('closed');
+				},400);
+			}
+		}
+	}
+</script>
+
+<style>
+	.login-modal{
+		position: relative;
+		z-index: 400;
+	}
+	.login-modal .modal-bg{
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+	}
+	.login-modal .modal-box{
+		position: fixed;
+		z-index: 401;
+		background:#FFFFFF;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		padding-bottom:0rpx;
+		padding-bottom:constant(safe-area-inset-bottom);
+		padding-bottom:env(safe-area-inset-bottom);
+		border-radius:32rpx 32rpx 0rpx 0rpx;
+	}
+	.login-modal .modal-main{
+		position: relative;
+		height: auto;
+		overflow: hidden;
+		min-height: 800rpx;
+		padding-top: 64rpx;
+		padding-bottom: 40rpx;
+	}
+	.login-modal .modal-main .closed{
+		position: absolute;
+		right: 40rpx;
+		top: 40rpx;
+	}
+	
+</style>

+ 140 - 0
components/dialog/login.vue

@@ -0,0 +1,140 @@
+<template>
+	<view class="login-modal">
+		<view  class="modal-bg" :style="{zIndex:zindex}"></view>
+		<view class="modal-box animated fast" :style="{zIndex:zindex+1,background:bg}" :class="show   ? 'slideInUp' : 'slideOutDown'">
+			<view class="modal-main">
+				<view class="closed">
+					<text @click="closed()" class="iconfont  ft20 cl-notice iconbtn_close"></text>
+				</view>
+				<view class="lh20 ft16 cl-main ftw600 text-center">{{step == 0 ? '授权登录请求' : '授权手机号码'}}</view>
+				<view v-if="step == 0" class="mt60">
+						<view class="text-center ft14 cl-main">
+							点击登录 享受更多会员特惠?
+						</view>
+						<view class="mt40 flex alcenter center">
+							<button class="btn-mid" @click="closed()" :style="{color:tempColor,background:'#F5F6FA'}" style="width: 300rpx;">拒绝</button>
+							<button class="btn-mid" @click="getUserInfo" :style="{background:tempColor}" style="margin-left: 30rpx;width: 300rpx; color: #FFFFFF;">登录</button>
+						</view>
+				</view>
+				<view v-if="step == 1" class="mt60">
+						<view class="text-center ft14 cl-main">
+							点击登录 享受更多会员特惠
+						</view>
+						
+						<view class="plr30 mt40">
+							<button class="btn-big" :style="getBtnStyle">
+								<text class="iconfont iconicon_weixin mr10 ft20"></text>微信授权手机号
+							</button>
+						</view>
+				</view>
+				
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	
+	
+	export  default{
+		props:{
+			zindex:{
+				type:Number,
+				default:402,
+			},
+			bg:{
+				type:String,
+				default:'#ffffff',
+			},
+			
+		},
+		data(){
+			return {
+				show:false,
+				code:'',
+				mdata:'',
+				miv:'',
+				step:0, // 1
+			}
+		},
+		created(){
+			this.show = true;
+			// uni.login({
+			//   provider: 'weixin',
+			//   success: (loginRes)=> {
+			// 	  console.log(loginRes);
+			// 	this.code = loginRes.code;
+			//   },
+			//   fail:()=>{
+			// 	  uni.showToast({
+			// 	  	icon:'none',
+			// 		title:'小程序登录失败'
+			// 	  });
+			// 	  this.show = false;
+			//   }
+			// });
+		},
+		methods:{
+			getUserInfo(e){
+				// if(!e.detail.userInfo){
+				// 	this.closed();
+				// }else{
+				// 	this.mdata = e.detail.encryptedData;
+				// 	this.miv = e.detail.iv;
+				// 	this.step = 1;
+				// }
+				uni.navigateTo({
+					url:'/pages/login/login'
+				})
+			},
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.$emit('closed');
+				},400);
+			}
+		}
+	}
+</script>
+
+<style>
+	.login-modal{
+		position: relative;
+		z-index: 400;
+	}
+	.login-modal .modal-bg{
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+	}
+	.login-modal .modal-box{
+		position: fixed;
+		z-index: 401;
+		background:#FFFFFF;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		padding-bottom:0rpx;
+		padding-bottom:constant(safe-area-inset-bottom);
+		padding-bottom:env(safe-area-inset-bottom);
+		border-radius:32rpx 32rpx 0rpx 0rpx;
+	}
+	.login-modal .modal-main{
+		position: relative;
+		height: auto;
+		overflow: hidden;
+		min-height: 800rpx;
+		padding-top: 64rpx;
+		padding-bottom: 40rpx;
+	}
+	.login-modal .modal-main .closed{
+		position: absolute;
+		right: 40rpx;
+		top: 40rpx;
+	}
+	
+</style>

+ 113 - 0
components/dialog/payment.vue

@@ -0,0 +1,113 @@
+<template>
+	<view class="payment-modal">
+		<view  class="modal-bg"></view>
+		<view class="modal-box animated fast"  :class="show   ? 'slideInUp' : 'slideOutDown'">
+			<view class="modal-main">
+				<view class="closed">
+					<text @click="closed()" class="iconfont  ft20 cl-notice iconbtn_close"></text>
+				</view>
+				<view class="lh20 ft16 cl-main ftw600 text-center">支付订单</view>
+				
+				
+				<view class=" pd16_15">
+					
+					<radio-group @change="changeType">
+					<view class="box pd16_15 flex alcenter space">
+						<view class="flex alcenter">
+							<text class="iconfont iconicon_pay_balance ft32" style="color: #FFBD1E;"></text>
+							<text class="ml15 ft14 ftw500 cl-main">余额支付</text>
+							<text class="ml10 ft12 cl-notice">余额为0,不可用</text>
+						</view>
+						<view>
+							<radio value="money" :checked="payType ==  'money'" :disabled="false" :color="tempColor"  />
+						</view>
+					</view>
+	
+					<view class="box pd16_15 mt16  flex alcenter space">
+						<view class="flex alcenter">
+							<text class="iconfont iconicon_pay_balance ft32 cl-green"></text>
+							<text class="ml15 ft14 ftw500 cl-main">微信支付</text>
+						</view>
+						<view>
+							<radio value="weixin" :checked="payType ==  'weixin'" :color="tempColor"  />
+						</view>
+					</view>
+					</radio-group>
+				</view>
+				
+			</view>
+			<view class="bg-w mt16 pd10_15" style="box-shadow: 0rpx -4rpx 16rpx 0rpx rgba(0, 0, 0, 0.04);">
+				<button class="btn-big" :style="getBtnStyle">确定支付</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	
+	
+	export  default{
+		props:{
+			
+		},
+		data(){
+			return {
+				payType:'weixin',
+				show:false,
+			}
+		},
+		created(){
+			this.show = true;
+		},
+		methods:{
+			changeType(e){
+				this.payType = e.detail.value;
+			},
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.$emit('closed');
+				},400);
+			}
+		}
+	}
+</script>
+
+<style>
+	.payment-modal{
+		position: relative;
+		z-index: 400;
+	}
+	.payment-modal .modal-bg{
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+	}
+	.payment-modal .modal-box{
+		position: fixed;
+		z-index: 401;
+		background:#FFFFFF;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		padding-bottom:0rpx;
+		padding-bottom:constant(safe-area-inset-bottom);
+		padding-bottom:env(safe-area-inset-bottom);
+		border-radius:32rpx 32rpx 0rpx 0rpx;
+	}
+	.payment-modal .modal-main{
+		position: relative;
+		height: auto;
+		overflow: hidden;
+		padding-top: 64rpx;
+	}
+	.payment-modal .modal-main .closed{
+		position: absolute;
+		right: 40rpx;
+		top: 40rpx;
+	}
+</style>

+ 163 - 0
components/dialog/qrcode.vue

@@ -0,0 +1,163 @@
+<template>
+	<view class="qrocde-modal">
+		<view  class="modal-bg" @click="closed()" :style="{zIndex:zindex}"></view>
+		<view class="modal-box animated fast" :style="{zIndex:zindex+1,background:bg}" :class="show   ? 'slideInUp' : 'slideOutDown'">
+			<!-- #ifdef MP-WEIXIN -->
+			
+			<view style="padding: 100upx 0px;">
+			<button open-type="share" style="width: 80%; background: #ff0000; color: #ffffff; height: 100upx;">点击分享</button>
+			<button @click="closed()" style="width: 80%; background: #ddd; margin-top: 30upx; color: #333; height: 100upx;">取消分享</button>
+			</view>
+			<!-- #endif -->
+			<!-- #ifndef MP-WEIXIN -->
+			<view class="modal-main">
+				<view class="closed">
+					<text @click="closed()" class="iconfont  ft20 cl-notice iconbtn_close"></text>
+				</view>
+				<view class="lh20 ft16 cl-main ftw600 text-center">我的分享二维码</view>
+				<view @click="getp()" class="flex center mt40"  style="height: 400rpx;">
+					<image :src="qrcodeImg" style="width: 400rpx; height: 400rpx;"></image>
+				</view>
+				<view class="text-center ft14 cl-info2" style="padding: 10upx 80upx;white-space:normal; word-break:break-all; word-wrap:break-word;">
+					<view class="text-center ft14" @click="copys()" style="padding-bottom: 20upx;">扫码上面的二维码【ID:{{uid}}】</view>
+					<view class="text-center ft14" @click="copy()">点击复制地址<br>{{qrurl}}</view>
+				</view>
+			</view>
+			<!-- #endif -->
+		</view>
+	</view>
+</template>
+
+<script>
+	import  QR   from '../../static/js/wxqrcode.js';
+	
+	export  default{
+		props:{
+			zindex:{
+				type:Number,
+				default:401,
+			},
+			bg:{
+				type:String,
+				default:'#ffffff',
+			},
+			
+		},
+		data(){
+			return {
+				show:false,
+				qrcodeImg:'',
+				uid:'',
+				qrurl:'',
+			}
+		},
+		created(){
+			this.show = true;
+			this.uid = uni.getStorageSync("userinfo").id;
+			this.qrurl=this.configs.webUrl+'/h5/#/pages/login/reg?uid='+this.uid
+			let img = QR.createQrCodeImg(this.qrurl, {  
+			     size: 300//二维码大小  
+			})
+			this.qrcodeImg = img;
+		},
+		methods:{
+			copy(){
+				var value=this.qrurl
+			  //提示模板
+			  uni.showModal({
+			    content:value,//模板中提示的内容
+			    confirmText:'复制内容',
+			    success:()=>{//点击复制内容的后调函数
+			      //uni.setClipboardData方法就是讲内容复制到粘贴板
+			      uni.setClipboardData({
+			        data:value,//要被复制的内容
+			        success:()=>{//复制成功的回调函数
+			          uni.showToast({//提示
+			            title:'复制成功'
+			          })
+			        }
+			      });
+			    }
+			  });
+			},
+			copys(){
+				console.log(1111)
+				var value=this.uid
+			  //提示模板
+			  uni.showModal({
+			    content:value,//模板中提示的内容
+			    confirmText:'复制内容',
+			    success:()=>{//点击复制内容的后调函数
+			      //uni.setClipboardData方法就是讲内容复制到粘贴板
+			      uni.setClipboardData({
+			        data:value,//要被复制的内容
+			        success:()=>{//复制成功的回调函数
+			          uni.showToast({//提示
+			            title:'复制成功'
+			          })
+			        }
+			      });
+			    }
+			  });
+			},
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.$emit('closed');
+				},400);
+			},
+			getp(){
+				let thia=this.qrcodeImg
+				//#ifdef APP-PLUS  
+				uni.saveImageToPhotosAlbum({
+				    filePath: thia.qrcodeImg,
+				    success: function () {
+				        console.log('save success');
+				    }
+				});
+				//#endif
+			}
+		}
+	}
+</script>
+
+<style>
+	.qrocde-modal{
+		position: relative;
+		z-index: 400;
+	}
+	.qrocde-modal .modal-bg{
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+	}
+	.qrocde-modal .modal-box{
+		position: fixed;
+		z-index: 401;
+		background:#FFFFFF;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		padding-bottom:0rpx;
+		padding-bottom:constant(safe-area-inset-bottom);
+		padding-bottom:env(safe-area-inset-bottom);
+		border-radius:32rpx 32rpx 0rpx 0rpx;
+	}
+	.qrocde-modal .modal-main{
+		position: relative;
+		height: auto;
+		overflow: hidden;
+		min-height: 1000rpx;
+		padding-top: 64rpx;
+		padding-bottom: 40rpx;
+	}
+	.qrocde-modal .modal-main .closed{
+		position: absolute;
+		right: 40rpx;
+		top: 40rpx;
+	}
+</style>

+ 0 - 144
components/dt-dropdown/dt-dropdown.vue

@@ -1,144 +0,0 @@
-<template>
-	<view>
-		<view @click="showShadow" class="dropWrap">{{title}}
-			<!-- <view class="sanjiao"></view> -->
-			<uni-icons class='icon' type="arrowdown" v-if="!showIf"></uni-icons>
-			<uni-icons class='icon' type="arrowup" v-else></uni-icons>
-		</view>
-		<view class="dropdown">
-			<view :class="showIf ? 'dropdown-mask' : 'undropdown-mask'" @click="hideShadow"></view>
-			<!-- <view class="ul" :style="showIf?'height:'+list.length*30+'px':''"> -->
-			<view class="ul" :style="'--i:'+list.length" :class="showIf?'show':''">
-				<!-- 不支持就用上面那种 -->
-				<view class="li" v-for="(item, index) in list" :key="index" @click="handlerItem(item)">{{ item.name }}
-				</view>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	export default {
-		name: 'dropdown',
-		props: {
-			list: {
-				type: Array,
-				default: () => []
-			},
-			current: {
-				type: [String, Number],
-				default: 0
-			},
-			title: {
-				type: String,
-				default: '全局操作'
-			}
-		},
-		data() {
-			return {
-				showIf: false
-			};
-		},
-		methods: {
-			handlerItem(value) {
-				this.showIf = false
-				console.log(value)
-				this.$emit('onClick', value);
-			},
-			hideShadow() {
-				this.showIf = false;
-			},
-			showShadow() {
-				this.showIf = true;
-				// this.$emit('titleClick', value);
-			}
-		}
-	};
-</script>
-
-<style scoped lang="scss">
-	.dropWrap {
-		box-sizing: border-box;
-		// width: 96px;
-		// height: 26px;
-		// border: 1px solid #e8ecef;
-		font-size: 12px;
-		color: #666666;
-		padding: 4px 8px;
-		display: flex;
-		align-items: center;
-		justify-content: space-between;
-
-		.icon {
-			font-size: 20rpx;
-			padding-left: 10rpx;
-			color: rgba(216, 216, 216, 1) !important;
-		}
-
-		// .sanjiao {
-		// 	width: 0;
-		// 	height: 0;
-		// 	border-left: 6px solid transparent;
-		// 	border-right: 6px solid transparent;
-		// 	border-top: 6px solid #C5CFD5;
-		// 	border-bottom: 6px solid transparent;
-		// 	transform: translateY(3px);
-		// }
-	}
-
-	.dropdown {
-		position: absolute;
-		z-index: 100;
-
-		.ul {
-			width: 136rpx;
-			position: relative;
-			z-index: 101;
-			list-style: none;
-			background-color: #fff;
-			border-radius: 4rpx;
-			padding-left: 0;
-			box-shadow: 6rpx 6rpx 10rpx rgba(122, 122, 122, 0.2);
-			transition: all 0.2s;
-			height: 0;
-			overflow: hidden;
-
-			.li {
-				box-sizing: border-box;
-				color: #000;
-				height: 30px;
-				// border-bottom: 1px solid #e6eaeb;
-				font-size: 24rpx;
-				line-height: 30px; //与下面的高度保持一致
-				padding-left: 8px;
-				text-align: center;
-
-				&:hover {
-					background-color: rgba(243, 243, 243, 1);
-				}
-			}
-
-			// .li:last-child {
-			// 	border-bottom: none;
-			// }
-		}
-
-		.show {
-			height: calc(var(--i) * 30px); //与上面的高度保持一致
-		}
-
-		.dropdown-mask {
-			top: 0;
-			left: 0;
-			position: fixed;
-			width: 100vw;
-			height: 100vh;
-			z-index: 100;
-			pointer-events: auto;
-		}
-
-		.undropdown-mask {
-			pointer-events: none;
-		}
-	}
-</style>

+ 187 - 0
components/fanxiao-sign/sigin-in.vue

@@ -0,0 +1,187 @@
+<template>
+	<view>
+		<view class="sign_conent_box">
+			<view class="sign_conent">
+				<view class="sign_conent_title">
+					你已连续签到
+					<span class="sign_conent_title_span">{{qdjl}}</span>
+					天
+				</view>
+				<view class="ft12 mt10" style="color: #999;">签到领看币,新剧抢先看。连续签到7天领惊喜礼包</view>
+				<view class="sign_list_aligns">
+					<scroll-view class="scroll-view_H" scroll-x="true">
+						<view class="scroll_view_items" v-for="(item, index) in sign_list" :key="index">
+							<!--  -->
+							<view class="scroll_view_itemsv">
+								<view class="scroll_view_item">
+									<view class="scroll_view_item_img_box">
+										<image v-if="item.xz==2" :src="statics.xuanzhong" class="scroll_view_item_img" mode=""></image>
+										<image v-if="item.xz==1" :src="statics.yuanq" class="scroll_view_item_img" mode=""></image>
+										<view v-if="item.xz==1" class="scroll_view_item_top">{{ item.discount }}</view>
+									</view>
+									<view class="scroll_view_item_tips">{{ item.day }}</view>
+								</view>
+								<view class="scroll_xian" v-show="index !== sign_list.length - 1"></view>
+							</view>
+						</view>
+					</scroll-view>
+				</view>
+				<view class="sign_conent_btn" @click="cksigin()">今日签到</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	props: {
+		sign_list: {},
+		qdjl: 0,
+		tdsy: 0,
+	},
+	data() {
+		return {};
+	},
+	methods: {
+		cksigin() {
+			if(uni.getStorageSync("userinfo")){
+				let this_=this
+				let data = {};
+				data.tdsy=this.tdsy
+				data.token = uni.getStorageSync("userinfo").token
+				data.uid = uni.getStorageSync("userinfo").id
+				uni.request({
+					url: this.configs.webUrl+'/api/user/qingdao',
+					data: data,
+					success: data => {
+						uni.showModal({
+							title: '温馨提示',
+							content: data.data.msg,
+							showCancel: false,
+							success: res => {
+								if(data.data.code==1){
+									this_.$emit('cksigin')
+								}
+							}
+						});
+					},
+					fail: (data, code) => {
+					}
+				});
+			}else{
+				uni.showModal({
+					title: '温馨提示',
+					content: '请先登录',
+					showCancel: true,
+					confirmText: "登录",
+					success: function (res) {
+						if (res.confirm) {
+							uni.navigateTo({
+								url:'/pages/login/login'
+							})						
+						} else if (res.cancel) {
+							//uni.navigateBack();						
+						}
+					}
+				});
+			}
+		},
+	}
+};
+</script>
+
+<style lang="scss">
+.sign_conent_box {
+	width: 100%;
+	display: flex;
+	justify-content: center;
+	margin-top: 30upx;
+	.sign_conent {
+		width: 686upx;
+		// background: white;
+		// border-radius: 20upx;
+		padding: 0upx 0upx;
+		box-sizing: border-box;
+		.sign_conent_title {
+			width: 100%;
+			font-size: 36upx;
+			font-weight: bold;
+			color: #333333;
+			.sign_conent_title_span {
+				color: #ff6526 !important;
+			}
+		}
+		.sign_list_aligns {
+			width: 100%;
+			padding: 30upx 0 30upx 0;
+			box-sizing: border-box;
+			.scroll-view_H {
+				width: 100%;
+				display: flex;
+				white-space: nowrap;
+				.scroll_view_items {
+					display: inline-block;
+				}
+				.scroll_view_itemsv {
+					display: flex;
+				}
+				.scroll_view_item {
+					.scroll_view_item_img_box {
+						width: 60upx;
+						height: 30upx;
+						position: relative;
+						.scroll_view_item_top {
+							font-size: 24upx;
+							color: #bfbfbf;
+							// font-weight: bold;
+							position: absolute;
+							top: 14upx;
+							width: 100%;
+							text-align: center;
+							z-index: 1;
+						}
+						.scroll_view_item_bottom {
+							font-size: 12upx;
+							color: #ffe29d;
+							position: absolute;
+							bottom: 18upx;
+							left: 42upx;
+							z-index: 2;
+						}
+					}
+					.scroll_view_item_tips {
+						width: 60upx;
+						text-align: center;
+						font-size: 24upx;
+						padding-top: 40upx;
+						color: #333333;
+					}
+					.scroll_view_item_img {
+						width: 60upx;
+						height: 60upx;
+						position: absolute;
+						top: 0;
+						left: 0;
+						z-index: 0;
+					}
+				}
+				.scroll_xian {
+					width: 40upx;
+					height: 4upx;
+					background: #bfbfbf;
+					margin-top: 30upx;
+				}
+			}
+		}
+		.sign_conent_btn {
+			width: 100%;
+			border-radius: 45upx;
+			background: linear-gradient(270deg, #fcae3a 0%, #f15d25 100%);
+			color: #ffffff;
+			text-align: center;
+			padding: 22upx 0;
+			font-size: 32upx;
+		}
+	}
+}
+</style>

+ 138 - 0
components/h-form-alert/h-form-alert.vue

@@ -0,0 +1,138 @@
+<template>
+	<view class="a_mask">
+		<form class="a_box" @submit="formSubmit" @reset="formReset">
+			<view class="a_head">
+				{{title}}
+			</view>
+			<view class="a_input">
+				<input :type="type" :value="value" :placeholder="placeholder" :name="name"/>
+			</view>
+			<view class="a_btn">
+				
+				<button form-type="reset" :style="{color:cancelColor}">{{cancelText}}</button>
+				<button form-type="submit" :style="{color:confirmColor}">{{confirmText}}</button>
+			</view>
+		</form>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:{
+			title:{
+				type:String,
+				default:'提示'
+			},
+			placeholder:{
+				type:String,
+				default:'请点击输入'
+			},
+			name:{
+				type:String,
+				default:'text'
+			},
+			type:{
+				type:String,
+				default:'text'
+			},
+			value:{
+				type:String,
+				default:''
+			},
+			cancelColor:{
+				type:String,
+				default:'#999999'
+			},
+			confirmColor:{
+				type:String,
+				default:'#333333'
+			},
+			cancelText:{
+				type:String,
+				default:'取消'
+			},
+			confirmText:{
+				type:String,
+				default:'确定'
+			},
+		},
+		data() {
+			return {
+
+			};
+		},
+		methods: {
+			formSubmit: function(e) {
+				console.log(e)
+				let _formdata = e.detail.value
+				this.$emit('confirm',_formdata)
+			},
+			formReset: function(e) {
+				this.$emit('cancel')
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.a_mask{
+		position: fixed;
+		z-index: 99999;
+		background-color: rgba(0,0,0,0.5);
+		top: 0;
+		left: 0;
+		bottom: 0;
+		right: 0;
+		.a_box{
+			width: 500upx;
+			overflow: hidden;
+			
+			background-color: #fff;
+			border-radius: 10upx;
+			position: absolute;
+			top: 50%;
+			left: 50%;
+			transform: translate(-50%,-50%);
+			
+			.a_head{
+				text-align: center;
+				font-size: 30upx;
+				line-height: 88upx;
+			}
+			.a_input{
+				padding: 30upx 20upx;
+				font-size: 28upx;
+				input{
+					text-align: center;
+				}
+			}
+			.a_btn{
+				text-align: center;
+				font-size: 30upx;
+				line-height: 88upx;
+				display: flex;
+				justify-content: space-between;
+				border-top: 1upx solid #f5f5f5;
+				button{
+					width: 50%;
+					background-color: #fff;
+					font-size: 30upx;
+					border-radius: 0upx;
+					padding: 0;
+					&::after{
+						border:none
+					}
+					&:first-child{
+						border-right: 1upx solid #f5f5f5;
+						color: #999999;
+						box-sizing: border-box;
+					}
+					&:last-child{
+						color: #333;
+					}
+				}
+				
+			}
+		}
+	}
+</style>

+ 48 - 0
components/h-form-alert/readme.md

@@ -0,0 +1,48 @@
+### 输入弹窗
+
+弹窗组件。
+
+**使用方式:**
+
+在 ``script`` 中引用组件 
+
+```javascript
+import hFormAlert from '@/components/h-form-alert/h-form-alert.vue';
+export default {
+    components: {hFormAlert}
+}
+```
+
+基本用法
+
+```html
+<hFormAlert v-if="控制显示隐藏"  @confirm="确认点击监听" @cancel="取消点击监听"></hFormAlert>
+```
+
+例子
+
+```html
+<hFormAlert v-if="cancelShow"  name="cancel_desc" placeholder="请输入取消原因" @confirm="confirm" @cancel="cancel"></hFormAlert>
+```
+
+
+**属性说明:**
+
+|属性名|类型|默认值	|说明|
+|---|----|---|---|
+|title|String|提示|弹窗头部文字|
+|name|String|text|输入框的name|
+|type|String|text|输入框的类型,就是input组件默认的type|
+|placeholder|String|请点击输入|输入框的占位文字|
+|value|String|‘’|输入框默认值|
+|cancelColor|String|#999999|取消按钮文本颜色|
+|cancelText|String|取消|取消按钮文本|
+|confirmColor|String|#333333|确认按钮文本颜色|
+|confirmText|String|确认|确认按钮文本|
+
+**事件说明:**
+
+|事件称名|说明|返回参数|
+|---|----|---|
+|confirm|确认按钮点击触发事件,返回参数是用户输入内容|{text:输入内容}|
+|cancel|取消按钮点击触发事件,无返回参数|

+ 0 - 173
components/maskDialog/maskDialog.vue

@@ -1,173 +0,0 @@
-<template>
-	<!-- 遮罩层 -->
-	<view class="mask flex-center" v-if="show" @touchmove.stop.prevent :style="{'height':height}">
-		<view class="warp">
-			<view class="rect flex-center-column-around">
-				<view class="title" v-if="isShowTitle" :style="titleStyle">
-					{{title}}
-				</view>
-				<image :src="img" mode="widthFix" v-if="isShowimg"></image>
-				<view class="text" v-if="isShowContent">
-					{{content}}
-				</view>
-				<view class="btn">
-					<button v-if="isShowCancel" size='mini' :style="{'color': cancelColor,'background':cancelBgcColor}"
-						plain type='primary' @tap.stop='cancel'>取消</button>
-					<button v-if="isShowSure" size='mini' :style="{'color': sureColor,'background':sureBgcColor}" plain
-						type="primary" @tap.stop='sure'>确定</button>
-				</view>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	export default {
-		name: "maskDialog",
-		props: {
-			//标题
-			title: {
-				type: String,
-				default: '系统提示'
-			},
-			titleStyle: {
-				type: Object,
-				default: () => {}
-			},
-			//是否展示内容
-			isShowContent: {
-				type: Boolean,
-				default: true
-			},
-			//是否展示取消按钮
-			isShowCancel: {
-				type: Boolean,
-				default: true
-			},
-			//是否展示确认按钮
-			isShowSure: {
-				type: Boolean,
-				default: true
-			},
-			//是否展示标题
-			isShowTitle: {
-				type: Boolean,
-				default: true
-			},
-			// 取消按钮的字体颜色
-			cancelColor: {
-				type: String,
-				default: 'rgba(81, 108, 255, 1)'
-			},
-			// 取消按钮的背景颜色
-			cancelBgcColor: {
-				type: String,
-				default: '#fff'
-			},
-			// 确认按钮的字体颜色
-			sureColor: {
-				type: String,
-				default: '#fff'
-			},
-			// 确认按钮的背景颜色
-			sureBgcColor: {
-				type: String,
-				default: 'linear-gradient(90deg, #7C99FF 0%, #4660FE 100%)'
-			},
-			// 展示的图片
-			img: {
-				type: String,
-				default: '/static/img/vote/Illustration.png'
-			},
-			//是否展示图片
-			isShowimg: {
-				type: Boolean,
-				default: true
-			},
-			//mask内容
-			content: {
-				type: String,
-				default: '这是一个系统提示内容'
-			},
-			//是否展示mask
-			show: {
-				type: Boolean,
-				default: false
-			},
-			height: {
-				type: String,
-				default: '100%'
-			}
-		},
-		data() {
-			return {
-
-			};
-		},
-		methods: {
-			cancel() {
-				this.$emit("onCancel")
-			},
-			sure() {
-				this.$emit("onSure")
-				// console.log(this.show)
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.mask {
-		width: 100%;
-		height: 100%;
-		position: absolute;
-		top: 50%;
-		left: 50%;
-		transform: translate(-50%,-50%);
-		z-index: 990;
-		background-color: rgba(216, 216, 216, 0.85);
-		.warp {
-			width: 100%;
-			height: 100%;
-			position: absolute;
-			top: 50%;
-			left: 50%;
-			transform: translate(-50%,-50%);
-			display: flex;
-			justify-content: center;
-			align-items: center;
-			flex-direction: column;
-		}
-
-		.rect {
-			width: 686rpx;
-			height: 540rpx;
-			background: #FFFFFF;
-			border-radius: 16rpx;
-
-			// display: flex;
-			// flex-direction: column;
-			// align-items: center;
-			// justify-content: space-around;
-			image {
-				width: 40%;
-				height: 200rpx;
-			}
-
-			.text {
-				font-size: 28rpx;
-				font-weight: 500;
-				color: #516CFF;
-				line-height: 40rpx;
-			}
-
-			.btn {
-				width: 60%;
-				display: flex;
-				justify-content: space-around;
-				align-items: center;
-				flex: none;
-			}
-		}
-	}
-</style>

+ 166 - 0
components/ming-pop/ming-pop.vue

@@ -0,0 +1,166 @@
+<template>
+	<!-- v-if解决center弹窗位置问题 -->
+	<view :class="direction==='center'?'centers':''" v-if="direction==='center'?open:true">
+		<view class="product-window"
+			:style="{width:width+'%',height:height=='fit-content'?height:(open?height:'fit-content')}"
+			:class="(open ? 'on' : '')+' '+direction" @touchmove.stop.prevent="">
+			<!-- 兼容h5顶部导航空位 -->
+			<!-- #ifndef MP -->
+			<view v-if="(direction!=='below'&&direction!=='center')" style="height: 100rpx;"></view>
+			<!-- #endif -->
+			<image src="../../static/ming-pop/close.png" mode=""
+				:class="(direction!=='below'&&direction!=='center')?'iconfont-h5':''" class="iconfont" @click="close"
+				v-if="is_close"></image>
+			<slot></slot>
+		</view>
+		<view class="mask" v-if="is_mask" @touchmove.prevent :hidden="!open" @click="close(1)"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			direction: {
+				type: String,
+				default: "below"
+			},
+			width: {
+				type: Number,
+				default: 100
+			},
+			height: {
+				type: String,
+				default: "fit-content"
+			},
+			is_close: {
+				type: Boolean,
+				default: true
+			},
+			is_mask: {
+				type: Boolean,
+				default: true
+			},
+			maskFun: {
+				type: Boolean,
+				default: true
+			}
+		},
+		data() {
+			return {
+				open: false
+			};
+		},
+		methods: {
+			show() {
+				this.open = true;
+				this.$emit("watchOpen")
+			},
+			close(e) {
+				if (e == 1 && !this.maskFun) return;
+				this.open = false;
+				this.$emit("watchClose")
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	view {
+		box-sizing: border-box;
+	}
+
+	.centers {
+		width: 100vw;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		// height: 100%;
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+	}
+
+	.product-window {
+		position: fixed;
+		background-color: #fff;
+		z-index: 77;
+		border-radius: 15rpx;
+		padding: 50rpx 30rpx;
+		transition: all .3s cubic-bezier(.25, .5, .5, .9);
+		-webkit-transition: all .3s cubic-bezier(.25, .5, .5, .9);
+	}
+
+	.below {
+		left: 0;
+		bottom: 0;
+		transform: translate3d(0, 100%, 0);
+		-webkit-transform: translate3d(0, 100%, 0);
+	}
+
+	.up {
+		top: 0;
+		left: 0;
+		transform: translate3d(0, -100%, 0);
+		-webkit-transform: translate3d(0, -100%, 0);
+	}
+
+	.right {
+		right: 0;
+		top: 0;
+		height: 100%;
+		transform: translate3d(100vw, 0, 0);
+		-webkit-transform: translate3d(100vw, 0, 0);
+	}
+
+	.left {
+		left: 0;
+		top: 0;
+		height: 100%;
+		transform: translate3d(-100vw, 0, 0);
+		-webkit-transform: translate3d(-100vw, 0, 0);
+	}
+
+	.center {
+		position: static;
+		-webkit-position: static;
+		transform: translate3d(-100vw, -100%, 0);
+		-webkit-transform: translate3d(-100vw, -100%, 0);
+	}
+
+	.product-window.on {
+		transform: translate3d(0, 0, 0);
+		-webkit-transform: translate3d(0, 0, 0);
+	}
+
+	.mask {
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background-color: #000;
+		opacity: .5;
+		z-index: 5;
+	}
+
+
+	.product-window .iconfont {
+		position: fixed;
+		right: 30rpx;
+		top: 20rpx;
+		font-size: 35rpx;
+		color: #8a8a8a;
+		width: 50rpx;
+		height: 50rpx;
+	}
+
+	//兼容h5顶部导航空位
+	// #ifndef MP
+	.product-window .iconfont-h5 {
+		top: 100rpx;
+	}
+
+	// #endif
+</style>

+ 134 - 0
components/model/model.vue

@@ -0,0 +1,134 @@
+<template>
+	<view>
+		<view class="userModel u-flex u-row-center u-col-center">
+			<view class="cont u-flex-col u-col-center" :style="{width: ad?'300px':'520rpx'}">
+				<image src="../../static/icon/jinbi.png"></image>
+				<view class="text u-text-center u-content-color u-p-l-60 u-p-r-60" v-html="title"></view>
+				<view class="" v-if="ad">
+					<view class="u-p-t-20" style="width: 300px;">
+						<!-- #ifdef MP-QQ -->
+						<ad unit-id="8aa061ea8e5bac1c717623a7be7badd8"></ad>
+						<!-- #endif -->
+						<!-- #ifdef MP-WEIXIN -->
+						<ad unit-id="adunit-0d2cf81781c3cd01"></ad>
+						<!-- #endif -->
+					</view>
+					<view class="btn u-text-center adClass" hover-class="hover-class" hover-stay-time="50" style="margin-left: 20%;margin-top: 30rpx;">
+						{{btnText}}
+						<button open-type="share" style="position: absolute;top: 0;left: 0;width: 100%;height: 100%;opacity: 0;"></button>
+					</view>
+				</view>
+				<view class="btn u-text-center" hover-class="hover-class" hover-stay-time="50" v-else @click="save">
+					{{btnText}}
+				</view>
+				<view v-if="closeText!=' '" class="no u-text-center u-p-t-30" @click="close">{{closeText}}</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'model',
+		props:{
+			title:{	//显示的内容
+				type: String,
+				default: '为了更好的浏览体验,快去授权登录吧'
+			},
+			authorize:{	//是否授权登录
+				type: Boolean,
+				default: true
+			},
+			ad:{	//广告
+				type: Boolean,
+				default: false
+			},
+			btnText:{	//按钮文字
+				type: String,
+				default: '授权登录'
+			},
+			closeText:{	//关闭文笔
+				type: String,
+				default: '暂时不用'
+			}
+		},
+		data() {
+			return {
+				
+			};
+		},
+		methods: {
+			save(){
+				this.$emit('save');
+			},
+			close(){
+				this.$emit('close');
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.userModel{
+		z-index: 9999999;
+		position: fixed;
+		top: 0;
+		left: 0;
+		width: 100vw;
+		height: 100vh;
+		background-color: rgba(0,0,0,0.6);
+		// backdrop-filter: blur(4rpx);
+		.cont{
+			width: 520rpx;
+			padding: 0px 0 50rpx 0;
+			background-color: #FFFFFF;
+			border-radius: 32rpx;
+			image{
+				width: 128rpx;
+				height: 128rpx;
+				margin-top: -60rpx;
+				margin-bottom: 40rpx;
+			}
+			.text{
+				line-height: 46rpx;
+			}
+			.btn{
+				position: relative;
+				margin-top: 50rpx;
+				color: #FFFFFF;
+				width: 60%;
+				line-height: 80rpx;
+				border-radius: 80rpx;
+				background-image: linear-gradient(to bottom right, #fce03d , #f8c93c);
+			}
+			.no{
+				color: #B8B8B8;
+			}
+		}
+	}
+	.num{
+		font-size: 16px;
+		font-weight: 700;
+		color: #f8c93c;
+		padding: 0 8rpx;
+	}
+	
+	.adClass{
+		animation: tiaobig 1.2s ease-in-out alternate infinite;
+		// animation-iteration-count:1;
+	}
+	@keyframes tiaobig {
+		25% {
+			transform: scale(0.98);
+		}
+		50% {
+			transform: scale(1.08);
+		}
+		75% {
+			transform: scale(0.98);
+		}
+		100% {
+			transform: scale(1.08);
+		}
+	}
+</style>

+ 184 - 0
components/select/address.vue

@@ -0,0 +1,184 @@
+<template>
+	<view>
+		<view @click="showAct" class="pd16_15 flex alcenter">
+			<view style="width: calc(100% - 40rpx);" class="flex">
+				<text class="iconfont iconicon_location02 ft18" :style="{color:tempColor}"></text>
+				<view class="pl10" style="width: calc(100% - 40rpx);">
+					<view v-if="getSelectItem == null" class="ft14 cl-main ftw600">选择收货地址</view> 
+					<view v-if="getSelectItem != null" class="ft14 cl-main ftw600 text-over">{{getSelectItem.address}}</view>
+					<view v-if="getSelectItem != null" class="ft12 mt12 cl-info2">{{getSelectItem.name}} {{getSelectItem.mobile}}</view>
+				</view>
+			</view>
+			<text class="iconfont iconicon_arrow_small ft14 cl-notice"></text>
+		</view>
+		
+		<view v-show="showAddress" class="address-modal">
+			<view  class="modal-bg"></view>
+			<view class="modal-box animated fast"  :class="show   ? 'slideInUp' : 'slideOutDown'">
+				<view class="modal-main">
+					<view class="closed">
+						<text @click="closed()" class="iconfont  ft20 cl-notice iconbtn_close"></text>
+					</view>
+					<view class="lh20 ft16 cl-main ftw600 text-center">选择收货地址</view>
+					
+					<view class="pd16_15">
+						<navigator url="/pages/client/member/address">
+							<view class="box noshadow pd10_15 flex alcenter center" :style="{color:tempColor}">
+								<text class="iconfont iconbtn_add_liner ft20 mr5"></text>
+								<text class="ft16 ftw600">新增地址</text>
+							</view>
+						</navigator>	
+						<radio-group @change="selectAddr">
+							
+						<view v-for="(item,index) in addrs" :key="index" class="box noshadow pd16_15 mt16 flex alcenter space">
+							<view style="width: calc(100% - 60rpx);">
+								<view class="flex alcenter">
+									<view class="tag-default mr10" v-if="item.is_default == 1" :style="{background:tempColor}">默认</view>
+									<text class="ft14 ftw600 cl-main">{{item.name}}  {{item.mobile}}</text>
+								</view>
+								<view class="mt8 ft12 cl-notice text-over">
+									{{item.address}}
+								</view>
+							</view>
+							<radio :value="item.address_id" :checked="item.address_id == getSelectId"  :color="tempColor"  />
+						</view>
+						
+						</radio-group>
+					</view>
+					
+					<view v-if="addrs.length > 0 " class="plr15 mt40">
+						<button class="btn-big" @click="selectYes" :style="getBtnStyle">确定选择</button>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			value:{
+				type:Number,
+				default:0
+			},
+		},
+		data(){
+			return {
+				show:false,
+				showAddress:false,
+				isSelect:false,
+				selectId:0,
+				addrs:[
+					{address_id:1,name:'张华2',mobile:'13515608638',address:'合肥市包河区万达临湖苑A区16栋1602室',is_default:1},
+					{address_id:2,name:'张华',mobile:'13515608638',address:'合肥市包河区万达临湖苑A区16栋2007室',is_default:0}
+				],
+			}
+		},
+		computed:{
+			getDefaultId(){
+				if(this.addrs.length == 0) return 0;
+				for(var a in this.addrs){
+					if(this.addrs[a].is_default == 1){
+						return this.addrs[a].address_id;
+					}
+				}
+				if(this.addrs[0]){
+					return this.addrs[0].address_id;
+				}
+			},
+			getSelectId(){
+				if(this.isSelect){
+					return this.selectId;
+				}
+				if(this.value > 0){
+					return this.value;
+				}
+				return this.getDefaultId;
+			},
+			getSelectItem(){
+				for(var a  in this.addrs){
+					if(this.addrs[a].address_id == this.value){
+						return this.addrs[a];
+					}
+				}
+				return null;
+			}
+		},
+		created(){
+			
+		},
+		methods:{
+			selectAddr(e){
+				this.isSelect = true;
+				this.selectId = parseInt(e.detail.value);
+			},
+			showAct(){
+				this.showAddress = true;
+				this.show = true;
+			},
+			selectYes(){
+				if(this.getSelectId){
+					this.$emit('input',this.getSelectId);
+					this.closed();
+				}
+			},
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.showAddress = false;
+				},400);
+			}
+		}
+	}
+</script>
+
+<style>
+	.address-modal{
+		position: relative;
+		z-index: 400;
+	}
+	.address-modal .modal-bg{
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+	}
+	.address-modal .modal-box{
+		position: fixed;
+		z-index: 401;
+		background:#F5F6FA;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		padding-bottom:0rpx;
+		padding-bottom:constant(safe-area-inset-bottom);
+		padding-bottom:env(safe-area-inset-bottom);
+		border-radius:32rpx 32rpx 0rpx 0rpx;
+	}
+	.address-modal .modal-main{
+		position: relative;
+		height: auto;
+		overflow: hidden;
+		padding-top: 64rpx;
+		padding-bottom: 40rpx;
+	}
+	.address-modal .modal-main .closed{
+		position: absolute;
+		right: 40rpx;
+		top: 40rpx;
+	}
+	
+	.tag-default{
+		width: 64rpx;
+		height: 36rpx;
+		border-radius: 4rpx;
+		text-align: center;
+		line-height: 36rpx;
+		font-size: 24rpx;
+		color:#FFFFFF;
+	}
+</style>

+ 176 - 0
components/select/birthday.vue

@@ -0,0 +1,176 @@
+<template>
+	<view>
+		<view @click="showSelect" class="flex alcenter">
+			<text v-if="value.length == 0" class="ft14 ftw500 cl-main">请选择</text>
+			<text v-else class="ft14 ftw500 cl-main">{{value[0]}}月{{value[1]}}日</text>
+			<text class="iconfont  iconicon_arrow_small ft14 ml10"></text>
+		</view>
+		<view v-show="showBirthday" class="birthday-modal">
+			<view  class="modal-bg"></view>
+			<view class="modal-box animated fast"  :class="show   ? 'slideInUp' : 'slideOutDown'">
+				<view class="modal-main">
+					<view class="closed">
+						<text @click="closed()" class="iconfont  ft20 cl-notice iconbtn_close"></text>
+					</view>
+					<view class="lh20 ft16 cl-main ftw600 text-center">请选择生日</view>
+					<view class="mt30">
+						
+						<picker-view class="picker-view" indicator-style="height:50px" :value="selectVal" @change="bindChange">
+						
+							<picker-view-column>
+								<view class="item text-center" v-for="(item,index) in month" :key="index">{{item}}</view>
+							</picker-view-column>
+							<picker-view-column>
+								<view class="item text-center" v-for="(item,index) in days" :key="index">{{item}}</view>
+							</picker-view-column>
+						</picker-view>	  
+						
+					</view>
+					
+					<view class="plr15 mt40">
+						<button class="btn-big" @click="selectYes" :style="isSelect == false ? getBtnDisStyle :getBtnStyle ">确定选择</button>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	
+	export  default{
+		props:{
+			value:{
+				type:Array,
+				default:function(){
+					return [];
+				}
+			},
+		},
+		computed:{
+			selectVal(){
+				let value = this.value;
+				if(value.length == 0){
+					value = new Array;
+					value = ['01','01'];
+				}
+				let arr = [0,0];
+				for(var a  in this.month){
+					if(this.month[a] == value[0]){
+						arr[0] = a;
+					}
+				}
+				for(var  b  in  this.days){
+					if(this.days[b] == value[1]){
+						arr[1] = b;
+					}
+				}
+				return arr;
+			}
+		},
+		data(){
+			let month = new Array;
+			for(var i= 1;i<=12;i++){
+				var m  = i < 10 ? '0'+i : i;
+				month.push(m);
+			}
+			let days = this.makeDays(this.value[0] ? this.value[0] : '01');
+		
+			return {
+				month:month,
+				days:days,
+				show:false,
+				showBirthday:false,
+				isSelect:false,
+				selectdate:['01','01'],
+			}
+		},
+		created(){
+			
+		},
+		methods:{
+			showSelect(){
+				this.showBirthday = true;
+				this.show = true;
+			},
+			makeDays(m){
+				let dmax = 31;
+				if(m == '02'){
+					dmax = 29;
+				}else{
+					if(m == '04' || m == '06' || m == '09' || m == '11'){
+						dmax = 30;
+					}else{
+						dmax = 31;
+					}
+				}
+				let days  = new Array;
+				for(var i = 1;i<=dmax;i++){
+					var d = i< 10 ? '0'+i : i;
+					days.push(d);
+				}
+				return days;
+			},
+			bindChange(e){
+				let values = e.detail.value;
+				this.days = this.makeDays(this.month[values[0]]);
+				this.selectdate = [this.month[values[0]],this.days[values[1]]];
+				this.isSelect = true;
+			},
+			selectYes(){
+				console.log(this.selectdate);
+				console.log(this.isSelect);
+				if(this.isSelect ){
+					this.$emit('input',this.selectdate);
+					this.closed();
+				}
+			},
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.showBirthday = false;
+				},400);
+			}
+		}
+	}
+</script>
+
+<style>
+	.birthday-modal{
+		position: relative;
+		z-index: 400;
+	}
+	.birthday-modal .modal-bg{
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+	}
+	.birthday-modal .modal-box{
+		position: fixed;
+		z-index: 401;
+		background:#FFFFFF;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		padding-bottom:0rpx;
+		padding-bottom:constant(safe-area-inset-bottom);
+		padding-bottom:env(safe-area-inset-bottom);
+		border-radius:32rpx 32rpx 0rpx 0rpx;
+	}
+	.birthday-modal .modal-main{
+		position: relative;
+		height: auto;
+		overflow: hidden;
+		padding-top: 64rpx;
+		padding-bottom: 40rpx;
+	}
+	.birthday-modal .modal-main .closed{
+		position: absolute;
+		right: 40rpx;
+		top: 40rpx;
+	}
+</style>

+ 175 - 0
components/select/coupon.vue

@@ -0,0 +1,175 @@
+<template>
+	<view>
+		<view @click="showAct" >
+			<text v-if="showType == 0" class="ft14 cl-notice">暂无券可用</text>
+			<text v-if="showType == 1" class="ft14 cl-notice">有{{coupons.length}}张可选</text>
+			<text v-if="showType == 2" class="ft14 cl-price">-¥{{getSelectItem.num}}</text>
+			<text v-if="showType != 2"  class="iconfont iconicon_arrow_small cl-notice ft14 ml10"></text>
+		</view>
+		
+		<view v-show="showCoupon" class="coupon-modal">
+			<view  class="modal-bg"></view>
+			<view class="modal-box animated fast"  :class="show   ? 'slideInUp' : 'slideOutDown'">
+				<view class="modal-main">
+					<view class="closed">
+						<text @click="closed()" class="iconfont  ft20 cl-notice iconbtn_close"></text>
+					</view>
+					<view class="lh20 ft16 cl-main ftw600 text-center">选择优惠券</view>
+					
+					<view class="pd16_15" style="min-height:600rpx;max-height: 1000rpx; overflow-y: scroll;">
+						<view v-for="(item,index) in coupons" :key="index" class="coupon-box" :class="index > 0 ? 'mt16' : ''">
+							<view class="pd16_15 bg-w flex alcenter space" style="border-bottom: 2rpx dashed   #E4E6ED;">
+								<view class="flex alcenter">
+									<view class="cl-orange" style="width: 96rpx;">
+										<text class="ft12">¥</text>
+										<text class="ft24 ftw600 ml4">{{item.num}}</text>
+									</view>
+									<view class="ml15">
+										<view class="ft14 ftw600 cl-main">普通洗剪吹优惠券</view>
+										<view class="mt12 ft12 cl-info2">2020-09-22到期</view>
+									</view>
+								</view>
+								<view class="btn-mini" @click="usedAct" :data-id="item.coupon_id" :style="value == item.coupon_id ? getBtnDisStyle : getBtnStyle">{{value == item.coupon_id ? '已选' : '使用'}}</view>
+							</view>
+							<view class="pd16_15 ft12 cl-notice">满50元可用,不可与其他优惠活动同时使用</view>
+							<view class="coupon-yl"></view>
+							<view class="coupon-yr"></view>
+							<view class="coupon-vip-tag">会员专享</view>
+						</view>
+						
+					</view>
+					
+					<view @click="noUseAct" class="pd16_15 mt30 bg-w text-center ft16 cl-main" style="box-shadow: 0rpx -4rpx 16rpx 0rpx rgba(0, 0, 0, 0.04);">不使用优惠</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			value:{
+				type:Number,
+				default:0
+			},
+			coupons:{
+				type:Array,
+				default:function(){
+					return new Array;
+				}
+			}
+		},
+		data(){
+			return {
+				show:false,
+				showCoupon:false,
+				isSelect:false,
+				selectId:0,
+				
+			}
+		},
+		computed:{
+			showType(){
+				if(this.coupons.length == 0) return 0;
+				if(this.value == 0) return 1;
+				if(this.getSelectItem == null) return 1;
+				return 2;
+			},
+			getSelectItem(){
+				for(var a  in this.coupons){
+					if(this.coupons[a].coupon_id == this.value) return this.coupons[a];
+				}
+				return null;
+			}
+		},
+		created(){
+			
+		},
+		methods:{
+			noUseAct(){
+				this.$emit('input',0);
+				this.closed();
+			},
+			usedAct(e){
+				let id = parseInt(e.currentTarget.dataset.id);
+				if(id == this.value) return;
+				this.$emit('input',id);
+				this.closed();
+			},
+			showAct(){
+				this.showCoupon = true;
+				this.show = true;
+			},
+			
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.showCoupon = false;
+				},400);
+			}
+		}
+	}
+</script>
+
+<style>
+	.coupon-modal{
+		position: relative;
+		z-index: 400;
+	}
+	.coupon-modal .modal-bg{
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+	}
+	.coupon-modal .modal-box{
+		position: fixed;
+		z-index: 401;
+		background:#F5F6FA;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		padding-bottom:0rpx;
+		padding-bottom:constant(safe-area-inset-bottom);
+		padding-bottom:env(safe-area-inset-bottom);
+		border-radius:32rpx 32rpx 0rpx 0rpx;
+	}
+	.coupon-modal .modal-main{
+		position: relative;
+		height: auto;
+		overflow: hidden;
+		padding-top: 64rpx;
+	}
+	.coupon-modal .modal-main .closed{
+		position: absolute;
+		right: 40rpx;
+		top: 40rpx;
+	}
+	
+	.coupon-box{
+		background: #FAFAFA;
+		border-radius: 16rpx;
+		overflow: hidden;
+		position: relative;
+		height: 252rpx;
+	}
+	.coupon-box .coupon-yl,.coupon-box .coupon-yr{
+		width: 20rpx;
+		height: 20rpx;
+		border-radius: 10rpx;
+		position: absolute;
+		top: 148rpx;
+		background: #F5F6FA; 
+		z-index: 2;
+	}
+	.coupon-box .coupon-yl{
+		left: -10rpx;
+	}
+	.coupon-box .coupon-yr{
+		right: -10rpx;
+	}
+</style>

+ 280 - 0
components/select/datetime.vue

@@ -0,0 +1,280 @@
+<template>
+	<view>
+		<view @click="showDiv" class="flex alcenter">
+			<text class="ft16  cl-manage">{{value == 0 ? '请选择' : value}}</text>
+			<text class="iconfont  iconicon_arrow_small ml5 ft14 cl-manage"></text>
+		</view>
+		<view v-show="show" class="selecttime-modal">
+			<view class="modal-bg"></view>
+			<view class="modal-box animated fast" :class="show   ? 'slideInUp' : 'slideOutDown'">
+				<view class="modal-main">
+					<view class="closed">
+						<text @click="closed()" class="iconfont  ft20 cl-notice iconbtn_close"></text>
+					</view>
+					<view class="lh20 ft16 cl-main ftw600 text-center">选择时间</view>
+
+					<view class="mt40">
+						<view class="flex">
+							<view class="col2 flex center">
+								<view class="time-type" @click="changeType(0)" :class="selectType == 0 ? 'on' :''">选择日期</view>
+							</view>
+							<view class="col2 flex center">
+								<view class="time-type" @click="changeType(1)" :class="selectType == 1 ? 'on' :''">选择时分</view>
+							</view>
+						</view>
+						<view v-if="selectType == 0 && show == true " class="pd16_15">
+							<picker-view class="picker-view" indicator-style="height:50px" :value="[selectVal[0],selectVal[1],selectVal[2]]"
+							 @change="bindChange">
+								<picker-view-column>
+									<view class="item text-center" v-for="(item,index) in years" :key="index">{{item}}年</view>
+								</picker-view-column>
+								<picker-view-column>
+									<view class="item text-center" v-for="(item,index) in month" :key="index">{{item}}月</view>
+								</picker-view-column>
+								<picker-view-column>
+									<view class="item text-center" v-for="(item,index) in days" :key="index">{{item}}日</view>
+								</picker-view-column>
+							</picker-view>
+						</view>
+						<view v-if="selectType == 1 && show == true" class="pd16_15">
+							<picker-view class="picker-view" indicator-style="height:50px" :value="[selectVal[3],selectVal[4]]" @change="bindChange2">
+								<picker-view-column>
+									<view class="item text-center" v-for="(item,index) in hours" :key="index">{{item}}时</view>
+								</picker-view-column>
+								<picker-view-column>
+									<view class="item text-center" v-for="(item,index) in mins" :key="index">{{item}}分</view>
+								</picker-view-column>
+
+							</picker-view>
+						</view>
+						<view class="pd16_15">
+							<button @click="submitYes" class="btn-manage">确定选择</button>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import helper from '../../static/js/helper.js';
+	export default {
+		props: {
+
+			value: {
+				type: String,
+				default: ''
+			},
+		},
+		data() {
+			let years = new Array;
+			for (var i = 2000; i <= 2030; i++) {
+				years.push(i);
+			}
+			let month = new Array;
+			for (var i = 1; i <= 12; i++) {
+				var m = i < 10 ? '0' + i : i;
+				month.push(m);
+			}
+			let days = this.makeDays([0, 0]);
+			let hours = new Array;
+			for (var i = 0; i <= 23; i++) {
+				var h = i < 10 ? '0' + i : i;
+				hours.push(h);
+			}
+			let mins = new Array;
+			for (var i = 0; i <= 59; i++) {
+				var min = i < 10 ? '0' + i : i;
+				mins.push(min);
+			}
+
+			return {
+
+				selectType: 0,
+				mydateValue: [0, 0, 0, 0, 0],
+				years: years,
+				month: month,
+				days: days,
+				hours: hours,
+				mins: mins,
+				show: false,
+			}
+		},
+
+		computed: {
+			getValue() {
+				let value = this.value;
+				if (value == '' || value == 0) {
+					let today = helper.getTimeArr();
+					value = today.y + '-' + today.m + '-' + today.d + ' ' + today.h + ':' + today.i;
+				}
+				let v = value.replace(/[-|:]/g, ' ');
+				let val = v.split(' ');
+				return val;
+			},
+			selectVal() {
+				let value = this.getValue;
+				let month = this.month;
+				let days = this.days;
+				let hours = this.hours;
+				let mins = this.mins;
+
+				let res = [0, 0, 0, 0, 0];
+				for (var a in this.years) {
+					if (this.years[a] == value[0]) {
+						res[0] = parseInt(a);
+						break;
+					}
+				}
+				for (var a in month) {
+					if (month[a] == value[1]) {
+						res[1] = parseInt(a);
+						break;
+					}
+				}
+				for (var a in days) {
+					if (days[a] == value[2]) {
+						res[2] = parseInt(a);
+						break;
+					}
+				}
+				for (var a in hours) {
+					if (hours[a] == value[3]) {
+						res[3] = parseInt(a);
+						break;
+					}
+				}
+				for (var a in mins) {
+					if (mins[a] == value[4]) {
+						res[4] = parseInt(a);
+						break;
+					}
+				}
+				return res;
+			},
+		},
+		methods: {
+			showDiv() {
+				this.show = true;
+			},
+			makeDays(value) {
+				let years = value[0];
+				let month = value[1];
+				let dmax = 31;
+				if ((years / 4 == 0) && month == '02') {
+					if ((years / 100 == 0) && (years % 400 !== 0)) {
+						dmax = 28;
+					} else {
+						dmax = 29;
+					}
+				} else {
+					if (month == '04' || month == '06' || month == '09' || month == '11') {
+						dmax = 30;
+					} else if (month == '02') {
+						dmax = 28;
+					}
+				}
+				let days = new Array;
+				for (var i = 1; i <= dmax; i++) {
+					var d = i < 10 ? '0' + i : i;
+					days.push(d);
+				}
+				return days;
+			},
+			makeDays2(selectVal) {
+				let values = [this.years[selectVal[0]], this.month[selectVal[1]]];
+				return this.makeDays(values);
+			},
+			bindChange(e) {
+				let values = e.detail.value;
+				this.days = this.makeDays2(values);
+				this.mydateValue[0] = values[0];
+				this.mydateValue[1] = values[1];
+				this.mydateValue[2] = values[2];
+			},
+			bindChange2(e) {
+				let values = e.detail.value;
+				this.mydateValue[3] = values[0];
+				this.mydateValue[4] = values[1];
+			},
+			submitYes() {
+				for (var a in this.mydateValue) {
+					if (this.mydateValue[a] == 0) {
+						this.mydateValue[a] = this.selectVal[a];
+					}
+				}
+				let date = this.years[this.mydateValue[0]] + '-' +
+					this.month[this.mydateValue[1]] + '-' +
+					this.days[this.mydateValue[2]] + ' ' +
+					this.hours[this.mydateValue[3]] + ':' +
+					this.mins[this.mydateValue[4]];
+				if (date == '2000-01-00 00:00') {
+					this.$emit('input', this.value);
+				} else {
+					this.$emit('input', date);
+				}
+				this.selectType = 0;
+				this.show = false;
+			},
+			closedAct() {
+				this.show = false;
+			},
+			changeType(type) {
+				this.selectType = type;
+			},
+		}
+	}
+</script>
+
+<style>
+	.selecttime-modal{
+		position: relative;
+		z-index: 400;
+	}
+	.selecttime-modal .modal-bg{
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+	}
+	.selecttime-modal .modal-box{
+		position: fixed;
+		z-index: 401;
+		background:#FFFFFF;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		padding-bottom:0rpx;
+		padding-bottom:constant(safe-area-inset-bottom);
+		padding-bottom:env(safe-area-inset-bottom);
+		border-radius:32rpx 32rpx 0rpx 0rpx;
+	}
+	.selecttime-modal .modal-main{
+		position: relative;
+		height: auto;
+		overflow: hidden;
+		padding-top: 64rpx;
+	}
+	.selecttime-modal .modal-main .closed{
+		position: absolute;
+		right: 40rpx;
+		top: 40rpx;
+	}
+	
+	.time-type {
+		height: 66rpx;
+		color: #333333;
+		font-size: 36rpx;
+		font-weight: 600;
+		border-bottom: 6rpx solid #FFFFFF;
+	}
+
+	.time-type.on {
+		border-color: #5E40FF;
+		color: #5E40FF; 
+	}
+</style>

+ 179 - 0
components/select/mendian.vue

@@ -0,0 +1,179 @@
+<template>
+	<view>
+		<view @click="showAct" class="pd16_15 flex alcenter">
+			<view style="width: calc(100% - 40rpx);" class="flex">
+				<text class="iconfont iconicon_location02 ft18" :style="{color:tempColor}"></text>
+				<view class="pl10" style="width: calc(100% - 40rpx);">
+					<view v-if="getSelectItem == null" class="ft14 cl-main ftw600">选择门店</view> 
+					<view v-if="getSelectItem != null" class="ft14 cl-main ftw600 text-over">[{{getSelectItem.name}}]{{getSelectItem.address}}</view>
+					<view v-if="getSelectItem != null" class="ft12 mt12 cl-orange">距离{{getSelectItem.juli}}km</view>
+				</view>
+			</view>
+			<text class="iconfont iconicon_arrow_small ft14 cl-notice"></text>
+		</view>
+		
+		<view v-show="showmendian" class="mendian-modal">
+			<view  class="modal-bg"></view>
+			<view class="modal-box animated fast"  :class="show   ? 'slideInUp' : 'slideOutDown'">
+				<view class="modal-main">
+					<view class="closed">
+						<text @click="closed()" class="iconfont  ft20 cl-notice iconbtn_close"></text>
+					</view>
+					<view class="lh20 ft16 cl-main ftw600 text-center">选择自提门店</view>
+					
+					<view class="pd16_15">
+						
+						<radio-group @change="selectMendian">
+							
+						<view v-for="(item,index) in mendians" :key="index" class="box noshadow pd16_15 mt16 flex alcenter space">
+							<view style="width: calc(100% - 60rpx);">
+								<view class="flex alcenter">
+									<view class="tag-default mr10" v-if="item.is_tuijian == 1" :style="{background:tempColor}">推荐</view>
+									<text class="ft14 ftw600 cl-main text-over" style="width: calc(100% - 88rpx);">[{{item.name}}]{{item.address}}</text>
+								</view>
+								<view class="mt8 ft12 cl-orange ">
+									距离{{item.juli}}km
+								</view>
+							</view>
+							<radio :value="item.mendian_id" :checked="item.mendian_id == getSelectId"  :color="tempColor"  />
+						</view>
+						
+						</radio-group>
+					</view>
+					
+					<view v-if="mendians.length > 0 " class="plr15 mt40">
+						<button class="btn-big" @click="selectYes" :style="getBtnStyle">确定选择</button>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			value:{
+				type:Number,
+				default:0
+			},
+		},
+		data(){
+			return {
+				show:false,
+				showmendian:false,
+				isSelect:false,
+				selectId:0,
+				mendians:[
+					{mendian_id:1,name:'高速店',address:'合肥市包河区万达临湖苑A区16栋1602室',juli:0.6,is_tuijian:1},
+					{mendian_id:2,name:'万达店',address:'合肥市包河区万达临湖苑A区16栋2007室',juli:11,is_tuijian:0}
+				],
+			}
+		},
+		computed:{
+			getDefaultId(){
+				if(this.mendians.length == 0) return 0;
+				for(var a in this.mendians){
+					if(this.mendians[a].is_tuijian == 1){
+						return this.mendians[a].mendian_id;
+					}
+				}
+				if(this.mendians[0]){
+					return this.mendians[0].mendian_id;
+				}
+			},
+			getSelectId(){
+				if(this.isSelect){
+					return this.selectId;
+				}
+				if(this.value > 0){
+					return this.value;
+				}
+				return this.getDefaultId;
+			},
+			getSelectItem(){
+				for(var a  in this.mendians){
+					if(this.mendians[a].mendian_id == this.value){
+						return this.mendians[a];
+					}
+				}
+				return null;
+			}
+		},
+		created(){
+			
+		},
+		methods:{
+			selectMendian(e){
+				this.isSelect = true;
+				this.selectId = parseInt(e.detail.value);
+			},
+			showAct(){
+				this.showmendian = true;
+				this.show = true;
+			},
+			selectYes(){
+				if(this.getSelectId){
+					this.$emit('input',this.getSelectId);
+					this.closed();
+				}
+			},
+			closed(){
+				this.show = false;
+				setTimeout(()=>{
+					this.showmendian = false;
+				},400);
+			}
+		}
+	}
+</script>
+
+<style>
+	.mendian-modal{
+		position: relative;
+		z-index: 400;
+	}
+	.mendian-modal .modal-bg{
+		position: fixed;
+		z-index: 400;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100vh;
+		background: rgba(0,0,0,.5);
+	}
+	.mendian-modal .modal-box{
+		position: fixed;
+		z-index: 401;
+		background:#F5F6FA;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		padding-bottom:0rpx;
+		padding-bottom:constant(safe-area-inset-bottom);
+		padding-bottom:env(safe-area-inset-bottom);
+		border-radius:32rpx 32rpx 0rpx 0rpx;
+	}
+	.mendian-modal .modal-main{
+		position: relative;
+		height: auto;
+		overflow: hidden;
+		padding-top: 64rpx;
+		padding-bottom: 40rpx;
+	}
+	.mendian-modal .modal-main .closed{
+		position: absolute;
+		right: 40rpx;
+		top: 40rpx;
+	}
+	
+	.tag-default{
+		width: 64rpx;
+		height: 36rpx;
+		border-radius: 4rpx;
+		text-align: center;
+		line-height: 36rpx;
+		font-size: 24rpx;
+		color:#FFFFFF;
+	}
+</style>

+ 63 - 0
components/select/star.vue

@@ -0,0 +1,63 @@
+<template>
+	<view class="flex space alcenter star-list" :class="size">
+		<text  v-for="(a,i) in datas" :key="i"  @click="changeStar" :data-value="a" class="star iconfont iconicon_star" :style="{color:a <= getVal ? '#FFD200' : '#E4E6ED' }"></text>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			type:{
+				type:String,
+				default:'star'
+			},
+			size:{
+				type:String,
+				default:'small'
+			},
+			value:{
+				type:Number,
+				default:0,
+			},
+			readOnly:{
+				type:Boolean,
+				default:false
+			}
+		},
+		computed:{
+			getVal(){
+				return this.value;
+			},
+			
+		},
+		data(){
+			return {
+				myValue:0,
+				datas:[1,2,3,4,5], //不同端 可能存在 a in number 得差异 所以用数组
+			}
+		},
+		methods:{
+			changeStar(e){
+				if(this.readOnly) return;
+				let val = parseInt(e.currentTarget.dataset.value);
+				console.log(val);
+				this.$emit('input',val);
+			}
+		}
+	}
+</script>
+
+<style>
+	.star-list{width: 100%;}
+	.star-list.small{width: 380rpx;}
+	.star-list.mini{width: 200rpx;}
+	.star-list .star{
+		font-size: 80rpx;
+	}
+	.star-list.small .star{
+		font-size: 48rpx;
+	}
+	.star-list.mini .star{
+		font-size: 32rpx;
+	}
+</style>

+ 173 - 0
components/share-btn/share-btn.vue

@@ -0,0 +1,173 @@
+<template>
+	<view class="sharebtn">
+		<view class="uni-share">
+			<view class="uni-share-content">
+				<view v-for="(item, index) in bottomData" :key="index" style="position: relative;" class="uni-share-content-box" >
+					<view class="uni-share-content-image">
+						<image :src="item.icon" class="content-image" />
+					</view>
+					<text class="uni-share-content-text">{{ item.text }}</text>
+					<button open-type="share" style="position: absolute; background: none; width: 100%; height: 100%;"  @click='btnShare(item.text)'></button>
+				</view>
+				
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				bottomData: [
+					// #ifdef H5 
+					{
+						text: '复制',
+						icon: '/static/index/copy.png',
+						name: 'copy'
+					}
+					// #endif
+					// #ifdef APP-PLUS || MP-WEIXIN
+					{
+						text: '微信',
+						icon: '/static/index/weixin.png',
+						name: 'wx'
+					},
+					{
+						text: '朋友圈',
+						icon: '/static/index/pengyouquan.png',
+						name: 'copy'
+					}
+					
+					// #endif
+					
+				],
+				// sharedataTemp: {
+				// 	type: 0,
+				// 	strShareUrl: "https://uniapp.dcloud.io",
+				// 	strShareTitle: "分享标题",
+				// 	strShareSummary: "分享总结",
+				// 	strShareImageUrl: "/static/sharemenu/copyurl.png"
+				// }
+			}
+		},
+		props: ["sharedataTemp"],
+		// onLoad() {
+		// 	console.log('sharedataTemp',this.sharedataTemp);
+		// },
+		methods: {
+			btnShare(ind) {
+				console.log(ind);
+				var strProvider = "",
+					strScene = "",
+					mytype = '';
+				switch (ind) {
+					case '复制':
+						uni.setClipboardData({
+							data: this.sharedataTemp.strShareUrl,
+							complete() {
+								uni.showToast({
+									title: "已复制到剪贴板"
+								})
+							}
+						})
+						break;
+					case '微信':
+						strProvider = "weixin"
+						strScene = "WXSceneSession"
+						mytype = 0
+						break;
+					case '朋友圈':
+						strProvider = "weixin"
+						strScene = "WXSenceTimeline"
+						mytype = 0
+						break;
+				}
+				if (strProvider != "") { //点击了0-3序号的这4个按钮
+					uni.share({
+						provider: strProvider,
+						scene: strScene,
+						type: mytype,
+						href: this.sharedataTemp.strShareUrl,
+						title: this.sharedataTemp.strShareTitle,
+						summary: this.sharedataTemp.strShareSummary,
+						imageUrl: this.sharedataTemp.strShareImageUrl,
+						success: function(res) {
+							console.log("success:" + JSON.stringify(res));
+						},
+						fail: function(err) {
+							console.log("fail:" + JSON.stringify(err));
+						}
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	/* 底部分享 */
+	.sharebtn {
+		.uni-share {
+			width: 690rpx;
+			margin: 30rpx;
+			border-radius: 30rpx;
+			/* #ifndef APP-NVUE */
+			display: flex;
+			flex-direction: column;
+			/* #endif */
+			background-color: #fff;
+			.uni-share-content {
+				/* #ifndef APP-NVUE */
+				display: flex;
+				/* #endif */
+				flex-direction: row;
+				flex-wrap: nowrap;
+				justify-content: center;
+				overflow-x: scroll;
+				padding: 15px 50rpx;
+				.uni-share-content-box {
+					/* #ifndef APP-NVUE */
+					display: flex;
+					/* #endif */
+					flex-direction: column;
+					align-items: center;
+					// width: 25%;
+					// justify-content: space-between;
+					margin-right: 60rpx;
+					&:nth-last-child(1) {
+						margin-right: 0;
+					}
+					.uni-share-content-image {
+						/* #ifndef APP-NVUE */
+						display: flex;
+						/* #endif */
+						flex-direction: row;
+						justify-content: center;
+						align-items: center;
+						width: 90rpx;
+						height: 90rpx;
+						overflow: hidden;
+						border-radius: 10rpx;
+						.content-image {
+							width: 90rpx;
+							height: 90rpx;
+						}
+					}
+					&:nth-last-child(1){
+						.uni-share-content-image .content-image {
+							width: 50rpx!important;
+							height: 50rpx!important;
+						}
+					}
+					.uni-share-content-text {
+						font-size: 26rpx;
+						color: #333;
+						padding-top: 5px;
+						padding-bottom: 10px;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 74 - 0
components/show/photo.vue

@@ -0,0 +1,74 @@
+<template>
+	<view>
+		<view v-if="photos.length > 0">
+			<view v-if="showType == 'big'" class="show-big-photo">
+				<image @click="showPic" v-for="(item,index) in photos" :key="index" :data-index="index" :src="item" mode="aspectFill"></image>
+			</view>
+			<view v-if="showType == 'mid'" class="show-mid-photo flex alcenter space">
+				<image @click="showPic" v-for="(item,index) in photos" :key="index" :data-index="index"  :src="item" mode="aspectFill"></image>
+				
+			</view>
+			<view v-if="showType == 'small'" class="show-small-photo flex space wrap">
+				<image @click="showPic" v-for="(item,index) in photos" :key="index" :data-index="index"  :src="item" mode="aspectFill"></image>
+				
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			photos:{
+				type:Array,
+				default:function(){
+					return new Array;
+				}
+			}
+		},
+		computed:{
+			showType(){
+				if(this.photos.length == 1) return 'big';
+				if(this.photos.length == 2) return 'mid';
+				return 'small';
+			}
+		},
+		data(){
+			return {
+				
+			}
+		},
+		methods:{
+			showPic(e){
+				let index = parseInt(e.currentTarget.dataset.index);
+				uni.previewImage({
+					current:index,
+					urls:this.photos
+				});
+			}
+		}
+	}
+</script>
+
+<style>
+	
+	.show-big-photo image{
+		width: 100%;
+		height: 400rpx;
+		background: #F2F2F2;
+	}
+	.show-mid-photo image{
+		width: calc(50% - 8rpx);
+		height: 300rpx;
+		background: #F2F2F2;
+	}
+	.show-small-photo image{
+		width: 190rpx;
+		height: 190rpx;
+		background: #F2F2F2;
+		border-radius: 8rpx;
+	}
+	.show-small-photo image:nth-child(n+4){
+		margin-top: 16rpx;
+	}
+</style>

+ 96 - 0
components/sub/tab.vue

@@ -0,0 +1,96 @@
+<template>
+	<view class="nav-tab-list">
+		<view class="main">
+			<view  v-for="(item,index) in tabs" :key="index" @click="changeTab(index)" :style="getWstyle[index]" :class="selectIndex == index ? 'ft16  ftw600' : 'ft14  ftw500' " class="text-center ">
+				{{item}}
+			</view>
+		</view>
+		<view class="bd" :style="getL"></view>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			isMain:{
+				type:Boolean,
+				default:true
+			},
+			tabs:{
+				type:Array,
+				default:function(){
+					return new Array;
+				}
+			},
+			selectIndex:{
+				type:Number,
+				default:0
+			}
+		},
+		computed:{
+			getW(){
+				if(this.tabs.length == 0) return 0;
+				let len = this.tabs.length;
+				let w = 100/len;
+				return w;
+			},
+			getWstyle(){
+				let arr = new Array;
+				for(var a in this.tabs){
+					let style = 'width:'+this.getW + '%;';
+					if(this.selectIndex == a){
+						style+= 'color:'+ (this.isMain ?  this.tempColor : '#5E40FF')+';';
+					}else{
+						style+='color:#333333;';	
+					}
+					arr.push(style);
+				}
+				return arr;
+			},
+			getL(){
+				let w = this.getW;
+				let w2 = w/2;
+				let l = this.selectIndex  *  w  + w2;
+				let style = 'left:calc('+l+'% - '+uni.upx2px(18)+'px);';
+				if(this.isMain){
+					style += 'background:'+this.tempColor+';';
+				}
+				return style;
+			}
+		},
+		data(){
+			return {
+				
+			}
+		},
+		methods:{
+			changeTab(index){
+				this.$emit('change',index);
+			}
+		}
+	}
+</script>
+
+<style>
+	.nav-tab-list{
+		height:100rpx;
+		position: relative;
+	}
+	.nav-tab-list .main{
+		width: 100%;
+		height: 100rpx;
+		display: flex;
+		align-items: center;
+	}
+	.nav-tab-list .bd{
+		width: 36rpx;
+		height:10rpx;
+		background:#5E40FF;
+		border-radius:6rpx 6rpx 0rpx 0rpx;
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		z-index: 2;
+		transition: left 0.4s;
+	}
+</style>

+ 137 - 0
components/sub/tabnav.vue

@@ -0,0 +1,137 @@
+<template>
+	<view class="tab-nav-plus">
+		<view class="tab-nav-plus-main"  :class="isFixed ? 'fixed' : ''">
+			<scroll-view :scroll-left="getLeft"   :scroll-with-animation="true" :scroll-x="true" class="tab-nav-plus-scroll">
+				<view v-for="(item,index) in tabs" :key="index"  :data-index="index" @click="tabClick" class="item">
+					<view class="tit" :class="selectIndex == index ? 'on' : ''" :style="{color: selectIndex == index ? tempColor: '#353535'}">{{item.name}}</view>
+					<view class="bd" :style="{background:selectIndex == index ? tempColor: 'transparent'}"></view>
+				</view>
+			</scroll-view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			scrollTop:{
+				type:Number,
+				default:0,
+			},
+			selectIndex:{
+				type:Number,
+				default:0,
+			},
+			tabs:{
+				type:Array,
+				default:function(){
+					return new Array;
+				}
+			}
+		},
+		data(){
+			return {
+				myTop:150,
+			}
+		},
+		computed:{
+			isFixed(){
+				return this.scrollTop >= this.myTop; 
+			},
+			getLeft(){ //这个计算不准确 凑合用
+				let w = 0;
+				for(var a  in this.tabs){
+					if(this.selectIndex < a) break;
+					let myw = 0;
+					if(this.selectIndex == a){
+						myw = this.tabs[a].name.length * 32;
+					}else{
+						myw = this.tabs[a].name.length * 28;
+					}
+					w+=myw;
+				}
+				w+= this.selectIndex * 60;
+				if(w > 375){
+					return  uni.upx2px(w - 375);
+				}
+				return 0;
+			},
+		},
+		created(){
+			setTimeout(()=>{
+				const query = uni.createSelectorQuery().in(this);
+				let css = '.tab-nav-plus';
+				query.select(css).boundingClientRect(data => {
+				   this.myTop = data.top;
+				}).exec();
+			},500);
+		},
+		methods:{
+			tabClick(e){
+				let index  = parseInt(e.currentTarget.dataset.index);
+				this.$emit('change',index);
+			}
+		}
+	}
+</script>
+
+<style>
+	.tab-nav-plus{
+		height: 108rpx;
+	}
+	.tab-nav-plus-main{
+		width: 100%;
+		height: 108rpx;
+		padding: 32rpx 30rpx 0rpx 32rpx;
+		background: #FFFFFF;
+		/* border-top: 0rpx solid #E4E6ED; */
+	}
+	.tab-nav-plus-main.fixed{
+		position: fixed;
+
+		left: 0;
+		z-index: 20;
+		background: #f8f8f8;
+		box-shadow:0rpx 4rpx 16rpx 0rpx rgba(0,0,0,0.08);
+	}
+	.tab-nav-plus-scroll{
+		width: 100%;
+		white-space: nowrap;
+		height: 76rpx;
+	}
+
+	.tab-nav-plus-scroll .item{
+		height: 76rpx;
+		display: inline-block;
+		margin-right: 60rpx;
+		position: relative;
+	}
+	.tab-nav-plus-scroll .item:last-child{
+		margin-right: 0;
+	}
+	.tab-nav-plus-scroll .item .tit{
+		text-align: center;
+		height: 48rpx;
+		line-height: 48rpx;
+		font-size: 28rpx;
+		font-weight: 500;
+	}
+	.tab-nav-plus-scroll .item .tit.on{
+		font-size: 32rpx;
+		font-weight: 600;
+	}
+	.tab-nav-plus-main .tab-nav-plus-scroll .item .bd{
+		position: absolute;
+		z-index: 1;
+		left: calc(50% - 18rpx);
+		bottom: 0;
+		width: 36rpx;
+		height: 12rpx;
+		border-radius: 6rpx 6rpx 0rpx 0rpx;
+	}
+	
+	.tab-nav-plus-main.fixed  .tab-nav-plus-scroll .item .bd{
+		background: #FFFFFF;
+	}
+	
+</style>

+ 138 - 0
components/sub/tabvs.vue

@@ -0,0 +1,138 @@
+<template>
+	<view class="tab-nav-plus">
+		<view class="tab-nav-plus-main"  :class="isFixed ? 'fixed' : ''">
+			<scroll-view :scroll-left="getLeft"   :scroll-with-animation="true" :scroll-x="true" class="tab-nav-plus-scroll">
+				<view v-for="(item,index) in tabs" :key="index"  :data-index="index" @click="tabClick" class="item">
+					<view class="tit" :class="selectIndex == index ? 'on' : ''" :style="{color: selectIndex == index ? '#FF6600': '#353535'}">{{item.name}}</view>
+					<!-- <view class="bd" :style="{background:selectIndex == index ? tempColor: 'transparent'}"></view> -->
+				</view>
+			</scroll-view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			scrollTop:{
+				type:Number,
+				default:0,
+			},
+			selectIndex:{
+				type:Number,
+				default:0,
+			},
+			tabs:{
+				type:Array,
+				default:function(){
+					return new Array;
+				}
+			}
+		},
+		data(){
+			return {
+				myTop:150,
+			}
+		},
+		computed:{
+			isFixed(){
+				return this.scrollTop >= this.myTop; 
+			},
+			getLeft(){ //这个计算不准确 凑合用
+				let w = 0;
+				for(var a  in this.tabs){
+					if(this.selectIndex < a) break;
+					let myw = 0;
+					if(this.selectIndex == a){
+						myw = this.tabs[a].name.length * 32;
+					}else{
+						myw = this.tabs[a].name.length * 28;
+					}
+					w+=myw;
+				}
+				w+= this.selectIndex * 60;
+				if(w > 375){
+					return  uni.upx2px(w - 375);
+				}
+				return 0;
+			},
+		},
+		created(){
+			setTimeout(()=>{
+				const query = uni.createSelectorQuery().in(this);
+				let css = '.tab-nav-plus';
+				query.select(css).boundingClientRect(data => {
+				   this.myTop = data.top;
+				}).exec();
+			},500);
+		},
+		methods:{
+			tabClick(e){
+				let index  = parseInt(e.currentTarget.dataset.index);
+				this.$emit('change',index);
+			}
+		}
+	}
+</script>
+
+<style>
+	.tab-nav-plus{
+		height: 80rpx;
+		/* margin-bottom: 20upx; */
+	}
+	.tab-nav-plus-main{
+		width: 100%;
+		height: 80rpx;
+		padding: 14rpx 30rpx 0rpx 32rpx;
+		/* background: #FFFFFF; */
+		/* border-top: 0rpx solid #E4E6ED; */
+	}
+	.tab-nav-plus-main.fixed{
+		position: fixed;
+		left: 0;
+		z-index: 20;
+		background: #FFFFFF;
+		box-shadow:0rpx 4rpx 16rpx 0rpx rgba(0,0,0,0.08);
+	}
+	.tab-nav-plus-scroll{
+		width: 100%;
+		white-space: nowrap;
+		height: 76rpx;
+	}
+
+	.tab-nav-plus-scroll .item{
+		height: 60upx;
+		line-height: 60upx;
+		display: inline-block;
+		margin-right: 60rpx;
+		position: relative;
+	}
+	.tab-nav-plus-scroll .item:last-child{
+		margin-right: 0;
+	}
+	.tab-nav-plus-scroll .item .tit{
+		text-align: center;
+		height: 48rpx;
+		line-height: 48rpx;
+		font-size: 28rpx;
+		font-weight: 500;
+	}
+	.tab-nav-plus-scroll .item .tit.on{
+		font-size: 28rpx;
+		font-weight: 600;
+	}
+	.tab-nav-plus-main .tab-nav-plus-scroll .item .bd{
+		position: absolute;
+		z-index: 1;
+		left: calc(50% - 18rpx);
+		bottom: 0;
+		width: 36rpx;
+		height: 12rpx;
+		border-radius: 6rpx 6rpx 0rpx 0rpx;
+	}
+	
+	.tab-nav-plus-main.fixed  .tab-nav-plus-scroll .item .bd{
+		background: #FFFFFF;
+	}
+	
+</style>

+ 142 - 0
components/sub/tabvsw.vue

@@ -0,0 +1,142 @@
+<template>
+	<view class="tab-nav-plus">
+		<view class="tab-nav-plus-main"  :class="isFixed ? 'fixed' : ''">
+			<scroll-view :scroll-left="getLeft"   :scroll-with-animation="true" :scroll-x="true" class="tab-nav-plus-scroll">
+				<view v-for="(item,index) in tabs" :key="index"  :data-index="index" @click="tabClick" class="item">
+					<view class="tit" :class="selectIndex == index ? 'on' : ''" :style="{color: selectIndex == index ? '#FF6600': '#353535'}">{{item.name}}</view>
+					<!-- <view class="bd" :style="{background:selectIndex == index ? tempColor: 'transparent'}"></view> -->
+				</view>
+			</scroll-view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			scrollTop:{
+				type:Number,
+				default:0,
+			},
+			selectIndex:{
+				type:Number,
+				default:0,
+			},
+			tabs:{
+				type:Array,
+				default:function(){
+					return new Array;
+				}
+			}
+		},
+		data(){
+			return {
+				myTop:150,
+			}
+		},
+		computed:{
+			isFixed(){
+				return this.scrollTop >= this.myTop; 
+			},
+			getLeft(){ //这个计算不准确 凑合用
+				let w = 0;
+				for(var a  in this.tabs){
+					if(this.selectIndex < a) break;
+					let myw = 0;
+					if(this.selectIndex == a){
+						myw = this.tabs[a].name.length * 32;
+					}else{
+						myw = this.tabs[a].name.length * 28;
+					}
+					w+=myw;
+				}
+				w+= this.selectIndex * 60;
+				if(w > 375){
+					return  uni.upx2px(w - 375);
+				}
+				return 0;
+			},
+		},
+		created(){
+			setTimeout(()=>{
+				const query = uni.createSelectorQuery().in(this);
+				let css = '.tab-nav-plus';
+				query.select(css).boundingClientRect(data => {
+				   this.myTop = data.top;
+				}).exec();
+			},500);
+		},
+		methods:{
+			tabClick(e){
+				let index  = parseInt(e.currentTarget.dataset.index);
+				this.$emit('change',index);
+			}
+		}
+	}
+</script>
+
+<style>
+	.tab-nav-plus{
+		height: 80rpx;
+	}
+	.tab-nav-plus-main{
+		width: 100%;
+		height: 80rpx;
+		padding: 20rpx 0rpx 0rpx 0rpx;
+		/* background: #FFFFFF; */
+		/* border-top: 0rpx solid #E4E6ED; */
+	}
+	.tab-nav-plus-main.fixed{
+		//position: fixed;
+		left: 0;
+		z-index: 20;
+		background: #f8f8f8;
+		box-shadow:0rpx 4rpx 16rpx 0rpx rgba(0,0,0,0.08);
+	}
+	.tab-nav-plus-scroll{
+		width: 100%;
+		white-space: nowrap;
+		height: 76rpx;
+	}
+
+	.tab-nav-plus-scroll .item{
+		height: 60upx;
+		line-height: 60upx;
+		display: inline-block;
+		margin-right: 20rpx;
+		position: relative;
+	}
+	.tab-nav-plus-scroll .item:last-child{
+		margin-right: 0;
+	}
+	.tab-nav-plus-scroll .item .tit{
+		text-align: center;
+		height: 48rpx;
+		line-height: 44rpx;
+		font-size: 30rpx;
+		/* border: solid 1upx #ddd; */
+		background: #f0f0f0;
+		padding: 0upx 16upx;
+		border-radius: 12upx;
+		font-weight: 500;
+		color: #909398;
+	}
+	.tab-nav-plus-scroll .item .tit.on{
+		font-size: 28rpx;
+		font-weight: 600;
+	}
+	.tab-nav-plus-main .tab-nav-plus-scroll .item .bd{
+		position: absolute;
+		z-index: 1;
+		left: calc(50% - 18rpx);
+		bottom: 0;
+		width: 36rpx;
+		height: 12rpx;
+		border-radius: 6rpx 6rpx 0rpx 0rpx;
+	}
+	
+	.tab-nav-plus-main.fixed  .tab-nav-plus-scroll .item .bd{
+		background: #FFFFFF;
+	}
+	
+</style>

+ 96 - 0
components/uni-icons1/icons.js

@@ -0,0 +1,96 @@
+export default {
+	'contact': '\ue100',
+	'person': '\ue101',
+	'personadd': '\ue102',
+	'contact-filled': '\ue130',
+	'person-filled': '\ue131',
+	'personadd-filled': '\ue132',
+	'phone': '\ue200',
+	'email': '\ue201',
+	'chatbubble': '\ue202',
+	'chatboxes': '\ue203',
+	'phone-filled': '\ue230',
+	'email-filled': '\ue231',
+	'chatbubble-filled': '\ue232',
+	'chatboxes-filled': '\ue233',
+	'weibo': '\ue260',
+	'weixin': '\ue261',
+	'pengyouquan': '\ue262',
+	'chat': '\ue263',
+	'qq': '\ue264',
+	'videocam': '\ue300',
+	'camera': '\ue301',
+	'mic': '\ue302',
+	'location': '\ue303',
+	'mic-filled': '\ue332',
+	'speech': '\ue332',
+	'location-filled': '\ue333',
+	'micoff': '\ue360',
+	'image': '\ue363',
+	'map': '\ue364',
+	'compose': '\ue400',
+	'trash': '\ue401',
+	'upload': '\ue402',
+	'download': '\ue403',
+	'close': '\ue404',
+	'redo': '\ue405',
+	'undo': '\ue406',
+	'refresh': '\ue407',
+	'star': '\ue408',
+	'plus': '\ue409',
+	'minus': '\ue410',
+	'circle': '\ue411',
+	'checkbox': '\ue411',
+	'close-filled': '\ue434',
+	'clear': '\ue434',
+	'refresh-filled': '\ue437',
+	'star-filled': '\ue438',
+	'plus-filled': '\ue439',
+	'minus-filled': '\ue440',
+	'circle-filled': '\ue441',
+	'checkbox-filled': '\ue442',
+	'closeempty': '\ue460',
+	'refreshempty': '\ue461',
+	'reload': '\ue462',
+	'starhalf': '\ue463',
+	'spinner': '\ue464',
+	'spinner-cycle': '\ue465',
+	'search': '\ue466',
+	'plusempty': '\ue468',
+	'forward': '\ue470',
+	'back': '\ue471',
+	'left-nav': '\ue471',
+	'checkmarkempty': '\ue472',
+	'home': '\ue500',
+	'navigate': '\ue501',
+	'gear': '\ue502',
+	'paperplane': '\ue503',
+	'info': '\ue504',
+	'help': '\ue505',
+	'locked': '\ue506',
+	'more': '\ue507',
+	'flag': '\ue508',
+	'home-filled': '\ue530',
+	'gear-filled': '\ue532',
+	'info-filled': '\ue534',
+	'help-filled': '\ue535',
+	'more-filled': '\ue537',
+	'settings': '\ue560',
+	'list': '\ue562',
+	'bars': '\ue563',
+	'loop': '\ue565',
+	'paperclip': '\ue567',
+	'eye': '\ue568',
+	'arrowup': '\ue580',
+	'arrowdown': '\ue581',
+	'arrowleft': '\ue582',
+	'arrowright': '\ue583',
+	'arrowthinup': '\ue584',
+	'arrowthindown': '\ue585',
+	'arrowthinleft': '\ue586',
+	'arrowthinright': '\ue587',
+	'pulldown': '\ue588',
+	'closefill': '\ue589',
+	'sound': '\ue590',
+	'scan': '\ue612'
+}

File diff suppressed because it is too large
+ 57 - 0
components/uni-icons1/uni-icons.vue


+ 194 - 0
components/uni-load-more/uni-load-more.vue

@@ -0,0 +1,194 @@
+<template>
+	<view class="uni-load-more">
+		<view class="uni-load-more__img" v-show="status === 'loading' && showIcon">
+			<view class="load1">
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+			</view>
+			<view class="load2">
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+			</view>
+			<view class="load3">
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+			</view>
+		</view>
+		<text class="uni-load-more__text" :style="{color:color}">{{status === 'more' ? contentText.contentdown : (status === 'loading' ? contentText.contentrefresh : contentText.contentnomore)}}</text>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "uni-load-more",
+		props: {
+			status: {
+				//上拉的状态:more-loading前;loading-loading中;noMore-没有更多了
+				type: String,
+				default: 'more'
+			},
+			showIcon: {
+				type: Boolean,
+				default: true
+			},
+			color: {
+				type: String,
+				default: "#777777"
+			},
+			contentText: {
+				type: Object,
+				default () {
+					return {
+						contentdown: "上拉显示更多",
+						contentrefresh: "正在加载...",
+						contentnomore: "没有更多数据了"
+					};
+				}
+			}
+		},
+		data() {
+			return {}
+		}
+	}
+</script>
+
+<style>
+	@charset "UTF-8";
+
+	.uni-load-more {
+		display: flex;
+		flex-direction: row;
+		height: 80upx;
+		align-items: center;
+		justify-content: center
+	}
+
+	.uni-load-more__text {
+		font-size: 28upx;
+		color: #999
+	}
+
+	.uni-load-more__img {
+		height: 24px;
+		width: 24px;
+		margin-right: 10px
+	}
+
+	.uni-load-more__img>view {
+		position: absolute
+	}
+
+	.uni-load-more__img>view view {
+		width: 6px;
+		height: 2px;
+		border-top-left-radius: 1px;
+		border-bottom-left-radius: 1px;
+		background: #999;
+		position: absolute;
+		opacity: .2;
+		transform-origin: 50%;
+		animation: load 1.56s ease infinite
+	}
+
+	.uni-load-more__img>view view:nth-child(1) {
+		transform: rotate(90deg);
+		top: 2px;
+		left: 9px
+	}
+
+	.uni-load-more__img>view view:nth-child(2) {
+		transform: rotate(180deg);
+		top: 11px;
+		right: 0
+	}
+
+	.uni-load-more__img>view view:nth-child(3) {
+		transform: rotate(270deg);
+		bottom: 2px;
+		left: 9px
+	}
+
+	.uni-load-more__img>view view:nth-child(4) {
+		top: 11px;
+		left: 0
+	}
+
+	.load1,
+	.load2,
+	.load3 {
+		height: 24px;
+		width: 24px
+	}
+
+	.load2 {
+		transform: rotate(30deg)
+	}
+
+	.load3 {
+		transform: rotate(60deg)
+	}
+
+	.load1 view:nth-child(1) {
+		animation-delay: 0s
+	}
+
+	.load2 view:nth-child(1) {
+		animation-delay: .13s
+	}
+
+	.load3 view:nth-child(1) {
+		animation-delay: .26s
+	}
+
+	.load1 view:nth-child(2) {
+		animation-delay: .39s
+	}
+
+	.load2 view:nth-child(2) {
+		animation-delay: .52s
+	}
+
+	.load3 view:nth-child(2) {
+		animation-delay: .65s
+	}
+
+	.load1 view:nth-child(3) {
+		animation-delay: .78s
+	}
+
+	.load2 view:nth-child(3) {
+		animation-delay: .91s
+	}
+
+	.load3 view:nth-child(3) {
+		animation-delay: 1.04s
+	}
+
+	.load1 view:nth-child(4) {
+		animation-delay: 1.17s
+	}
+
+	.load2 view:nth-child(4) {
+		animation-delay: 1.3s
+	}
+
+	.load3 view:nth-child(4) {
+		animation-delay: 1.43s
+	}
+
+	@-webkit-keyframes load {
+		0% {
+			opacity: 1
+		}
+
+		100% {
+			opacity: .2
+		}
+	}
+</style>

+ 210 - 0
components/uni-pagination/uni-pagination.vue

@@ -0,0 +1,210 @@
+<template>
+	<view class="uni-pagination">
+		<view class="uni-pagination__btns">
+			<view class="uni-pagination__btn" :class="currentIndex === 1 ? 'uni-pagination--disabled' : 'uni-pagination--enabled'"
+			 :hover-class="currentIndex === 1 ? '' : 'uni-pagination--hover'" :hover-start-time="20" :hover-stay-time="70"
+			 @click="clickLeft">
+				<template v-if="showIcon===true || showIcon === 'true'">
+					<uni-icons color="#000" size="20" type="arrowleft" />
+				</template>
+				<template v-else><text class="uni-pagination__child-btn">{{ prevText }}</text></template>
+			</view>
+			<view class="uni-pagination__btn" :class="currentIndex === maxPage ? 'uni-pagination--disabled' : 'uni-pagination--enabled'"
+			 :hover-class="currentIndex === maxPage ? '' : 'uni-pagination--hover'" :hover-start-time="20" :hover-stay-time="70"
+			 @click="clickRight">
+				<template v-if="showIcon===true || showIcon === 'true'">
+					<uni-icons color="#000" size="20" type="arrowright" />
+				</template>
+				<template v-else><text class="uni-pagination__child-btn">{{ nextText }}</text></template>
+			</view>
+		</view>
+		<view class="uni-pagination__num">
+			<view class="uni-pagination__num-current">
+				<text class="uni-pagination__num-current-text" style="color:#007aff">{{ currentIndex }}</text><text class="uni-pagination__num-current-text">/{{ maxPage || 0 }}</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import uniIcons from '../uni-icons1/uni-icons.vue'
+	export default {
+		name: 'UniPagination',
+		components: {
+			uniIcons
+		},
+		props: {
+			prevText: {
+				type: String,
+				default: '上一页'
+			},
+			nextText: {
+				type: String,
+				default: '下一页'
+			},
+			current: {
+				type: [Number, String],
+				default: 1
+			},
+			total: { // 数据总量
+				type: [Number, String],
+				default: 0
+			},
+			pageSize: { // 每页数据量
+				type: [Number, String],
+				default: 10
+			},
+			showIcon: { // 是否以 icon 形式展示按钮
+				type: [Boolean, String],
+				default: false
+			}
+		},
+		data() {
+			return {
+				currentIndex: 1
+			}
+		},
+		computed: {
+			maxPage() {
+				let maxPage = 1
+				let total = Number(this.total)
+				let pageSize = Number(this.pageSize)
+				if (total && pageSize) {
+					maxPage = Math.ceil(total / pageSize)
+				}
+				return maxPage
+			}
+		},
+		watch: {
+			current(val) {
+				this.currentIndex = +val
+			}
+		},
+		created() {
+			this.currentIndex = +this.current
+		},
+		methods: {
+			clickLeft() {
+				if (Number(this.currentIndex) === 1) {
+					return
+				}
+				this.currentIndex -= 1
+				this.change('prev')
+			},
+			clickRight() {
+				if (Number(this.currentIndex) === this.maxPage) {
+					return
+				}
+				this.currentIndex += 1
+				this.change('next')
+			},
+			change(e) {
+				this.$emit('change', {
+					type: e,
+					current: this.currentIndex
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-pagination {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		padding: 0 20px;
+		/* #endif */
+		width: 350px;
+		position: relative;
+		overflow: hidden;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.uni-pagination__btns {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		justify-content: space-between;
+		align-items: center;
+		flex-direction: row;
+	}
+
+	.uni-pagination__btn {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		width: 80px;
+		height: 40px;
+		line-height: 40px;
+		font-size: $uni-font-size-base;
+		position: relative;
+		background-color: $uni-bg-color-grey;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		text-align: center;
+		border-width: 1px;
+		border-style: solid;
+		border-color: $uni-border-color;
+		border-radius: 8px;
+	}
+
+	.uni-pagination__child-btn {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		font-size: $uni-font-size-base;
+		position: relative;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		text-align: center;
+	}
+
+	.uni-pagination__num {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		position: absolute;
+		left: 150px;
+		top: 0;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		width: 50px;
+		height: 30px;
+		line-height: 30px;
+		font-size: $uni-font-size-base;
+		color: $uni-text-color;
+	}
+
+	.uni-pagination__num-current {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-pagination__num-current-text {
+		font-size: 15px;
+	}
+
+	.uni-pagination--enabled {
+		color: #333333;
+		opacity: 1;
+	}
+
+	.uni-pagination--disabled {
+		opacity: 0.3;
+	}
+
+	.uni-pagination--hover {
+		color: rgba(0, 0, 0, .6);
+		background-color: $uni-bg-color-hover;
+	}
+</style>

+ 263 - 0
components/uni-popup/uni-popup.vue

@@ -0,0 +1,263 @@
+<!-- 底部弹窗(分享) -->
+
+<template>
+	<view v-if="showPopup" class="uni-popup" @touchmove.stop.prevent="clear">
+		<uni-transition :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="showTrans" @click="onTap" />
+		<uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
+			<view class="uni-popup__wrapper-box" @click.stop="clear">
+				<slot />
+			</view>
+		</uni-transition>
+	</view>
+</template>
+<script>
+	import uniTransition from '@/components/uni-transition/uni-transition.vue'
+	/**
+	 * PopUp 弹出层
+	 * @description 弹出层组件,为了解决遮罩弹层的问题
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} type = [top|center|bottom] 弹出方式
+	 * 	@value top 顶部弹出
+	 * 	@value center 中间弹出
+	 * 	@value bottom 底部弹出
+	 * @property {Boolean} animation = [ture|false] 是否开启动画
+	 * @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
+	 * @event {Function} change 打开关闭弹窗触发,e={show: false}
+	 */
+
+	export default {
+		name: 'UniPopup',
+		components: {
+			uniTransition
+		},
+		props: {
+			// 开启动画
+			animation: {
+				type: Boolean,
+				default: true
+			},
+			// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
+			type: {
+				type: String,
+				default: 'center'
+			},
+			// maskClick
+			maskClick: {
+				type: Boolean,
+				default: true
+			}
+		},
+		data() {
+			return {
+				duration: 300,
+				ani: [],
+				showPopup: false,
+				showTrans: false,
+				maskClass: {
+					'position': 'fixed',
+					'bottom': 0,
+					'top': 0,
+					'left': 0,
+					'right': 0,
+					'backgroundColor': 'rgba(0, 0, 0, 0.4)'
+				},
+				transClass: {
+					'position': 'fixed',
+					'left': 0,
+					'right': 0,
+				}
+			}
+		},
+		watch: {
+			type: {
+				handler: function(newVal) {
+					switch (this.type) {
+						case 'top':
+							this.ani = ['slide-top']
+							this.transClass = {
+								'position': 'fixed',
+								'left': 0,
+								'right': 0,
+							}
+							break
+						case 'bottom':
+							this.ani = ['slide-bottom']
+							this.transClass = {
+								'position': 'fixed',
+								'left': 0,
+								'right': 0,
+								'bottom': 0
+							}
+							break
+						case 'center':
+							this.ani = ['zoom-out', 'fade']
+							this.transClass = {
+								'position': 'fixed',
+								/* #ifndef APP-NVUE */
+								'display': 'flex',
+								'flexDirection': 'column',
+								/* #endif */
+								'bottom': 0,
+								'left': 0,
+								'right': 0,
+								'top': 0,
+								'justifyContent': 'center',
+								'alignItems': 'center'
+							}
+
+							break
+					}
+				},
+				immediate: true
+			}
+		},
+		created() {
+			if (this.animation) {
+				this.duration = 300
+			} else {
+				this.duration = 0
+			}
+		},
+		methods: {
+			clear(e) {
+				// TODO nvue 取消冒泡
+				e.stopPropagation()
+			},
+			open() {
+				this.showPopup = true
+				this.$nextTick(() => {
+					clearTimeout(this.timer)
+					this.timer = setTimeout(() => {
+						this.showTrans = true
+					}, 50);
+				})
+				this.$emit('change', {
+					show: true
+				})
+			},
+			close(type) {
+				this.showTrans = false
+				this.$nextTick(() => {
+					clearTimeout(this.timer)
+					this.timer = setTimeout(() => {
+						this.$emit('change', {
+							show: false
+						})
+						this.showPopup = false
+					}, 300)
+				})
+			},
+			onTap() {
+				if (!this.maskClick) return
+				this.close()
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	.uni-popup {
+		position: fixed;
+		/* #ifdef H5 */
+		top: var(--window-top);
+		/* #endif */
+		/* #ifndef H5 */
+		top: 0;
+		/* #endif */
+		bottom: 0;
+		left: 0;
+		right: 0;
+		/* #ifndef APP-NVUE */
+		z-index: 99999999999;
+		/* #endif */
+	}
+
+	.uni-popup__mask {
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: $uni-bg-color-mask;
+		opacity: 0;
+	}
+
+	.mask-ani {
+		transition-property: opacity;
+		transition-duration: 0.2s;
+	}
+
+	.uni-top-mask {
+		opacity: 1;
+	}
+
+	.uni-bottom-mask {
+		opacity: 1;
+	}
+
+	.uni-center-mask {
+		opacity: 1;
+	}
+
+	.uni-popup__wrapper {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		position: absolute;
+	}
+
+	.top {
+		top: 0;
+		left: 0;
+		right: 0;
+		transform: translateY(-500px);
+	}
+
+	.bottom {
+		bottom: 0;
+		left: 0;
+		right: 0;
+		transform: translateY(500px);
+	}
+
+	.center {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		flex-direction: column;
+		/* #endif */
+		bottom: 0;
+		left: 0;
+		right: 0;
+		top: 0;
+		justify-content: center;
+		align-items: center;
+		transform: scale(1.2);
+		opacity: 0;
+	}
+
+	.uni-popup__wrapper-box {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		position: relative;
+	}
+
+	.content-ani {
+		// transition: transform 0.3s;
+		transition-property: transform, opacity;
+		transition-duration: 0.2s;
+	}
+
+
+	.uni-top-content {
+		transform: translateY(0);
+	}
+
+	.uni-bottom-content {
+		transform: translateY(0);
+	}
+
+	.uni-center-content {
+		transform: scale(1);
+		opacity: 1;
+	}
+</style>

+ 281 - 0
components/uni-transition/uni-transition.vue

@@ -0,0 +1,281 @@
+<!-- 底部弹窗需要组件(分享) -->
+
+<template>
+	<view v-if="isShow" ref="ani" class="uni-transition" :class="[ani.in]" :style="'transform:' +transform+';'+stylesObject"
+	 @click="change">
+		 <slot></slot>
+	</view>
+</template>
+
+<script>
+	// #ifdef APP-NVUE
+	const animation = uni.requireNativePlugin('animation');
+	// #endif
+	/**
+	 * Transition 过渡动画
+	 * @description 简单过渡动画组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=985
+	 * @property {Boolean} show = [false|true] 控制组件显示或隐藏
+     * @property {Array} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
+     *  @value fade 渐隐渐出过渡
+     *  @value slide-top 由上至下过渡
+     *  @value slide-right 由右至左过渡
+     *  @value slide-bottom 由下至上过渡
+     *  @value slide-left 由左至右过渡
+     *  @value zoom-in 由小到大过渡
+     *  @value zoom-out 由大到小过渡
+	 * @property {Number} duration 过渡动画持续时间
+	 * @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
+	 */
+	export default {
+		name: 'uniTransition',
+		props: {
+			show: {
+				type: Boolean,
+				default: false
+			},
+			modeClass: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			duration: {
+				type: Number,
+				default: 300
+			},
+			styles: {
+				type: Object,
+				default () {
+					return {}
+				}
+			}
+		},
+		data() {
+			return {
+				isShow: false,
+				transform: '',
+				ani: { in: '',
+					active: ''
+				}
+			};
+		},
+		watch: {
+			show: {
+				handler(newVal) {
+					if (newVal) {
+						this.open()
+					} else {
+						this.close()
+					}
+				},
+				immediate: true
+			}
+		},
+		computed: {
+			stylesObject() {
+				let styles = {
+					...this.styles,
+					'transition-duration': this.duration / 1000 + 's'
+				}
+				let transfrom = ''
+				for (let i in styles) {
+					let line = this.toLine(i)
+					transfrom += line + ':' + styles[i] + ';'
+				}
+				return transfrom
+			}
+		},
+		created() {
+			// this.timer = null
+			// this.nextTick = (time = 50) => new Promise(resolve => {
+			// 	clearTimeout(this.timer)
+			// 	this.timer = setTimeout(resolve, time)
+			// 	return this.timer
+			// });
+		},
+		methods: {
+			change() {
+				this.$emit('click', {
+					detail: this.isShow
+				})
+			},
+			open() {
+				clearTimeout(this.timer)
+				this.isShow = true
+				this.transform = ''
+				this.ani.in = ''
+				for (let i in this.getTranfrom(false)) {
+					if (i === 'opacity') {
+						this.ani.in = 'fade-in'
+					} else {
+						this.transform += `${this.getTranfrom(false)[i]} `
+					}
+				}
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this._animation(true)
+					}, 50)
+				})
+
+			},
+			close(type) {
+				clearTimeout(this.timer)
+				this._animation(false)
+			},
+			_animation(type) {
+				let styles = this.getTranfrom(type)
+				// #ifdef APP-NVUE
+				if(!this.$refs['ani']) return
+				animation.transition(this.$refs['ani'].ref, {
+					styles,
+					duration: this.duration, //ms
+					timingFunction: 'ease',
+					needLayout: false,
+					delay: 0 //ms
+				}, () => {
+					if (!type) {
+						this.isShow = false
+					}
+					this.$emit('change', {
+						detail: this.isShow
+					})
+				})
+				// #endif
+				// #ifndef APP-NVUE
+				this.transform = ''
+				for (let i in styles) {
+					if (i === 'opacity') {
+						this.ani.in = `fade-${type?'out':'in'}`
+					} else {
+						this.transform += `${styles[i]} `
+					}
+				}
+				this.timer = setTimeout(() => {
+					if (!type) {
+						this.isShow = false
+					}
+					this.$emit('change', {
+						detail: this.isShow
+					})
+
+				}, this.duration)
+				// #endif
+
+			},
+			getTranfrom(type) {
+				let styles = {
+					transform: ''
+				}
+				this.modeClass.forEach((mode) => {
+					switch (mode) {
+						case 'fade':
+							styles.opacity = type ? 1 : 0
+							break;
+						case 'slide-top':
+							styles.transform += `translateY(${type?'0':'-100%'}) `
+							break;
+						case 'slide-right':
+							styles.transform += `translateX(${type?'0':'100%'}) `
+							break;
+						case 'slide-bottom':
+							styles.transform += `translateY(${type?'0':'100%'}) `
+							break;
+						case 'slide-left':
+							styles.transform += `translateX(${type?'0':'-100%'}) `
+							break;
+						case 'zoom-in':
+							styles.transform += `scale(${type?1:0.8}) `
+							break;
+						case 'zoom-out':
+							styles.transform += `scale(${type?1:1.2}) `
+							break;
+					}
+				})
+				return styles
+			},
+			_modeClassArr(type) {
+				let mode = this.modeClass
+				if (typeof(mode) !== "string") {
+					let modestr = ''
+					mode.forEach((item) => {
+						modestr += (item + '-' + type + ',')
+					})
+					return modestr.substr(0, modestr.length - 1)
+				} else {
+					return mode + '-' + type
+				}
+			},
+			// getEl(el) {
+			// 	console.log(el || el.ref || null);
+			// 	return el || el.ref || null
+			// },
+			toLine(name) {
+				return name.replace(/([A-Z])/g, "-$1").toLowerCase();
+			}
+		}
+	}
+</script>
+
+<style>
+	.uni-transition {
+		transition-timing-function: ease;
+		transition-duration: 0.3s;
+		transition-property: transform, opacity;
+	}
+
+	.fade-in {
+		opacity: 0;
+	}
+
+	.fade-active {
+		opacity: 1;
+	}
+
+	.slide-top-in {
+		/* transition-property: transform, opacity; */
+		transform: translateY(-100%);
+	}
+
+	.slide-top-active {
+		transform: translateY(0);
+		/* opacity: 1; */
+	}
+
+	.slide-right-in {
+		transform: translateX(100%);
+	}
+
+	.slide-right-active {
+		transform: translateX(0);
+	}
+
+	.slide-bottom-in {
+		transform: translateY(100%);
+	}
+
+	.slide-bottom-active {
+		transform: translateY(0);
+	}
+
+	.slide-left-in {
+		transform: translateX(-100%);
+	}
+
+	.slide-left-active {
+		transform: translateX(0);
+		opacity: 1;
+	}
+
+	.zoom-in-in {
+		transform: scale(0.8);
+	}
+
+	.zoom-out-active {
+		transform: scale(1);
+	}
+
+	.zoom-out-in {
+		transform: scale(1.2);
+	}
+</style>

+ 118 - 0
components/upload/face.vue

@@ -0,0 +1,118 @@
+<template>
+	<view class="upload-face">
+		<view v-if="value == ''" @click="uploadAct" class="upload-main">
+			<view class="upload-btn">
+				<text class="iconfont iconicon_photo  cl-w"></text>
+			</view>
+		</view>
+		<view v-else class="upload-show">
+			<image @click="uploadAct"></image>
+			<view @click="delPic" class="del">
+				<text class="iconfont iconicon_close12 ft12"></text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import qiniu from '../../static/js/qiniu.js';
+	export default{
+		props:{
+			value:{
+				type:String,
+				default:'',
+			}
+		},
+		data(){
+			return {
+				
+			}
+		},
+		methods:{
+			delPic(){
+				this.$emit('input','');
+			},
+			uploadAct(){
+				uni.chooseImage({
+					count:1,
+					success:(chooseImageRes)=>{
+						if(chooseImageRes.tempFilePaths.length > 0){
+							 // this.$http.api('child.upload/imageAuth').then(auth=>{
+								//  let domain = auth.url;
+								//  let token = auth.token;
+								//  let region = auth.region_mini;
+								
+								// 	let file  = chooseImageRes.tempFilePaths[0];
+								// 	let index = file.lastIndexOf('/');
+								// 	let len   = file.length
+								// 	let name  = file.substring(index + 1, len);
+								// 	qiniu.upload(file, (res) => {
+								// 		let url = res.imageURL;
+								// 		this.$emit('input',url);
+								// 	}, (error) => {
+								// 		console.log(error);
+								// 	}, {
+								// 		region: region,
+								// 		key: name,
+								// 		domain:domain,
+								// 		uptoken: token, 
+								// 	});
+							
+							 // }).catch(res=>{
+								//  console.log(res);
+							 // });
+						}
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+	.upload-face{
+		width: 210rpx;
+		height: 210rpx;
+		background: rgba(94, 64, 255, 0.06);
+		border-radius: 110rpx;
+	}
+	.upload-face .upload-main{
+		width: 210rpx;
+		height: 210rpx;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+	}
+	.upload-face .upload-btn{
+		width: 64rpx;
+		height: 64rpx;
+		background: #5E40FF;
+		border-radius: 32rpx;
+		text-align: center;
+		line-height: 64rpx;
+	}
+	.upload-face .upload-show{
+		width: 210rpx;
+		height: 210rpx;
+		border-radius: 110rpx;
+		position: relative;
+	}
+	.upload-face .upload-show image{
+		width: 210rpx;
+		height: 210rpx;
+		border-radius: 110rpx;
+		background: rgba(94, 64, 255, 0.06);
+	}
+	.upload-face .upload-show .del{
+		position: absolute;
+		right: 0;
+		top: 0rpx;
+		width: 56rpx;
+		height: 56rpx;
+		background: rgba(0,0,0,.4);
+		border-radius: 28rpx;
+		text-align: center;
+		line-height: 56rpx;
+		color:#FFFFFF;
+	}
+</style>

+ 147 - 0
components/upload/list.vue

@@ -0,0 +1,147 @@
+<template>
+	<view class="flex wrap">
+		<view @click="uploadAct" v-if="value.length < maxNum" class="upload-list-photo camera flex center alcenter">
+			<view class="upload" :style="{background:isMain ? tempColor : '#5E40FF'}">
+				<text class="iconfont iconicon_photo  cl-w"></text>
+			</view>
+		</view>
+		
+		<view v-for="(item,index) in  value" :key="index" class="upload-list-photo">
+			<image class="photo" :src="item"></image>
+			<view :data-index="index" @click="delPic"  class="del">
+				<text class="iconfont iconbtn_close cl-w"></text>
+			</view>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	import qiniu from '../../static/js/qiniu.js';
+	export default{
+		props:{
+			value:{
+				type:Array,
+				default:function(){
+					return new Array;
+				}
+			},
+			isMain:{
+				type:Boolean,
+				default:true,
+			},
+			maxNum:{ //最多上传的数量
+				type:Number,
+				default:9
+			}
+		},
+		data(){
+			return {
+				
+			}
+		},
+		computed:{
+			getNum(){
+				return this.maxNum - this.value.length;
+			}
+		},
+		created(){
+			
+		},
+		methods:{
+			delPic(e){
+				let index = parseInt(e.currentTarget.dataset.index);
+				let oldImgs = JSON.parse(JSON.stringify(this.value));
+				oldImgs.splice(index,1);
+				this.$emit('input',oldImgs);
+			},
+			uploadAct(){
+				uni.chooseImage({
+					count:this.getNum,
+					success:(chooseImageRes)=>{
+						if(chooseImageRes.tempFilePaths.length > 0){
+							 // this.$http.api('child.upload/imageAuth').then(auth=>{
+								//  let domain = auth.url;
+								//  let token = auth.token;
+								//  let region = auth.region_mini;
+								// for (var i = 0; i < chooseImageRes.tempFilePaths.length; i++) {
+								// 	let file  = chooseImageRes.tempFilePaths[i];
+								// 	let index = file.lastIndexOf('/');
+								// 	let len   = file.length
+								// 	let name  = file.substring(index + 1, len);
+								// 	qiniu.upload(file, (res) => {
+								// 		let url = res.imageURL;
+								// 		let oldImgs = JSON.parse(JSON.stringify(this.value));
+								// 		oldImgs.push(url);
+								// 		this.$emit('input',oldImgs);
+								// 	}, (error) => {
+								// 		console.log(error);
+								// 	}, {
+								// 		region: region,
+								// 		key: name,
+								// 		domain:domain,
+								// 		uptoken: token, 
+								// 	});
+								// }	
+							 // }).catch(res=>{
+								//  console.log(res);
+							 // });
+						}
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+	
+	.upload-list-photo{
+		width:190rpx;
+		height:190rpx;
+		border-radius:16rpx;
+		position: relative;
+		margin-right: 30rpx;
+		margin-bottom: 30rpx;
+
+	}
+	
+	
+	.upload-list-photo.camera{
+	
+		background:#FFFFFF;
+		border:2rpx dashed #C5CADB;
+	}
+	.upload-list-photo.camera .upload{
+		width: 64rpx;
+		height: 64rpx;
+		border-radius: 32rpx;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+	}
+	
+	.upload-list-photo:nth-child(3n){
+		margin-right: 0rpx;
+	}
+	.upload-list-photo .photo{
+		width:190rpx;
+		height:190rpx;
+		border-radius:16rpx;
+		background: #f2f2f2;
+	}
+	.upload-list-photo .del{
+		width: 56rpx;
+		height: 56rpx;
+		position: absolute;
+		border-radius: 28rpx;
+		background: rgba(0,0,0,0.5);
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		z-index: 2;
+		right: 0;
+		top: 0;
+	}
+	
+</style>

+ 0 - 21
components/uview-ui/LICENSE

@@ -1,21 +0,0 @@
-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.

+ 0 - 106
components/uview-ui/README.md

@@ -1,106 +0,0 @@
-<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://uviewui.com/components/quickstart.html)了解更详细的内容 
-
-## 使用方法
-配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
-
-```html
-<template>
-	<u-button>按钮</u-button>
-</template>
-```
-
-请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容 
-
-## 链接
-
-- [官方文档](https://uviewui.com/)
-- [更新日志](https://uviewui.com/components/changelog.html)
-- [升级指南](https://uviewui.com/components/changelog.html)
-- [关于我们](https://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/wechat.png" width="220" >
-<img style="margin-left: 100px;" src="https://uviewui.com/common/alipay.png" width="220" >
- -->
-## 版权信息
-uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。

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

@@ -1,190 +0,0 @@
-<template>
-	<u-popup mode="bottom" :border-radius="borderRadius" :popup="false" v-model="value" :maskCloseAble="maskCloseAble"
-	    length="auto" :safeAreaInsetBottom="safeAreaInsetBottom" @close="popupClose" :z-index="uZIndex">
-		<view class="u-tips u-border-bottom" v-if="tips.text" :style="[tipsStyle]">
-			{{tips.text}}
-		</view>
-		<block v-for="(item, index) in list" :key="index">
-			<view 
-				@touchmove.stop.prevent 
-				@tap="itemClick(index)" 
-				:style="[itemStyle(index)]" 
-				class="u-action-sheet-item u-line-1" 
-				:class="[index < list.length - 1 ? 'u-border-bottom' : '']"
-				:hover-stay-time="150"
-			>
-				<text>{{item.text}}</text>
-				<text class="u-action-sheet-item__subtext u-line-1" v-if="item.subText">{{item.subText}}</text>
-			</view>
-		</block>
-		<view class="u-gab" v-if="cancelBtn">
-		</view>
-		<view @touchmove.stop.prevent class="u-actionsheet-cancel u-action-sheet-item" hover-class="u-hover-class"
-		    :hover-stay-time="150" v-if="cancelBtn" @tap="close">{{cancelText}}</view>
-	</u-popup>
-</template>
-
-<script>
-	/**
-	 * actionSheet 操作菜单
-	 * @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
-	 * @tutorial https://www.uviewui.com/components/actionSheet.html
-	 * @property {Array<Object>} list 按钮的文字数组,见官方文档示例
-	 * @property {Object} tips 顶部的提示文字,见官方文档示例
-	 * @property {String} cancel-text 取消按钮的提示文字
-	 * @property {Boolean} cancel-btn 是否显示底部的取消按钮(默认true)
-	 * @property {Number String} border-radius 弹出部分顶部左右的圆角值,单位rpx(默认0)
-	 * @property {Boolean} mask-close-able 点击遮罩是否可以关闭(默认true)
-	 * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
-	 * @property {Number String} z-index z-index值(默认1075)
-	 * @property {String} cancel-text 取消按钮的提示文字
-	 * @event {Function} click 点击ActionSheet列表项时触发
-	 * @event {Function} close 点击取消按钮时触发
-	 * @example <u-action-sheet :list="list" @click="click" v-model="show"></u-action-sheet>
-	 */
-	export default {
-		name: "u-action-sheet",
-		props: {
-			// 点击遮罩是否可以关闭actionsheet
-			maskCloseAble: {
-				type: Boolean,
-				default: true
-			},
-			// 按钮的文字数组,可以自定义颜色和字体大小,字体单位为rpx
-			list: {
-				type: Array,
-				default () {
-					// 如下
-					// return [{
-					// 	text: '确定',
-					// 	color: '',
-					// 	fontSize: ''
-					// }]
-					return [];
-				}
-			},
-			// 顶部的提示文字
-			tips: {
-				type: Object,
-				default () {
-					return {
-						text: '',
-						color: '',
-						fontSize: '26'
-					}
-				}
-			},
-			// 底部的取消按钮
-			cancelBtn: {
-				type: Boolean,
-				default: true
-			},
-			// 是否开启底部安全区适配,开启的话,会在iPhoneX机型底部添加一定的内边距
-			safeAreaInsetBottom: {
-				type: Boolean,
-				default: false
-			},
-			// 通过双向绑定控制组件的弹出与收起
-			value: {
-				type: Boolean,
-				default: false
-			},
-			// 弹出的顶部圆角值
-			borderRadius: {
-				type: [String, Number],
-				default: 0
-			},
-			// 弹出的z-index值
-			zIndex: {
-				type: [String, Number],
-				default: 0
-			},
-			// 取消按钮的文字提示
-			cancelText: {
-				type: String,
-				default: '取消'
-			}
-		},
-		computed: {
-			// 顶部提示的样式
-			tipsStyle() {
-				let style = {};
-				if (this.tips.color) style.color = this.tips.color;
-				if (this.tips.fontSize) style.fontSize = this.tips.fontSize + 'rpx';
-				return style;
-			},
-			// 操作项目的样式
-			itemStyle() {
-				return (index) => {
-					let style = {};
-					if (this.list[index].color) style.color = this.list[index].color;
-					if (this.list[index].fontSize) style.fontSize = this.list[index].fontSize + 'rpx';
-					// 选项被禁用的样式
-					if (this.list[index].disabled) style.color = '#c0c4cc';
-					return style;
-				}
-			},
-			uZIndex() {
-				// 如果用户有传递z-index值,优先使用
-				return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
-			}
-		},
-		methods: {
-			// 点击取消按钮
-			close() {
-				// 发送input事件,并不会作用于父组件,而是要设置组件内部通过props传递的value参数
-				// 这是一个vue发送事件的特殊用法
-				this.popupClose();
-				this.$emit('close');
-			},
-			// 弹窗关闭
-			popupClose() {
-				this.$emit('input', false);
-			},
-			// 点击某一个item
-			itemClick(index) {
-				// disabled的项禁止点击
-				if(this.list[index].disabled) return;
-				this.$emit('click', index);
-				this.$emit('input', false);
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-
-	.u-tips {
-		font-size: 26rpx;
-		text-align: center;
-		padding: 34rpx 0;
-		line-height: 1;
-		color: $u-tips-color;
-	}
-
-	.u-action-sheet-item {
-		@include vue-flex;;
-		line-height: 1;
-		justify-content: center;
-		align-items: center;
-		font-size: 32rpx;
-		padding: 34rpx 0;
-		flex-direction: column;
-	}
-	
-	.u-action-sheet-item__subtext {
-		font-size: 24rpx;
-		color: $u-tips-color;
-		margin-top: 20rpx;
-	}
-
-	.u-gab {
-		height: 12rpx;
-		background-color: rgb(234, 234, 236);
-	}
-
-	.u-actionsheet-cancel {
-		color: $u-main-color;
-	}
-</style>

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

@@ -1,256 +0,0 @@
-<template>
-	<view class="u-alert-tips" v-if="show" :class="[
-		!show ? 'u-close-alert-tips': '',
-		type ? 'u-alert-tips--bg--' + type + '-light' : '',
-		type ? 'u-alert-tips--border--' + type + '-disabled' : '',
-	]" :style="{
-		backgroundColor: bgColor,
-		borderColor: borderColor
-	}">
-		<view class="u-icon-wrap">
-			<u-icon v-if="showIcon" :name="uIcon" :size="description ? 40 : 32" class="u-icon" :color="uIconType" :custom-style="iconStyle"></u-icon>
-		</view>
-		<view class="u-alert-content" @tap.stop="click">
-			<view class="u-alert-title" :style="[uTitleStyle]">
-				{{title}}
-			</view>
-			<view v-if="description" class="u-alert-desc" :style="[descStyle]">
-				{{description}}
-			</view>
-		</view>
-		<view class="u-icon-wrap">
-			<u-icon @click="close" v-if="closeAble && !closeText" hoverClass="u-type-error-hover-color" name="close" color="#c0c4cc"
-			 :size="22" class="u-close-icon" :style="{
-				top: description ? '18rpx' : '24rpx'
-			}"></u-icon>
-		</view>
-		<text v-if="closeAble && closeText" class="u-close-text" :style="{
-			top: description ? '18rpx' : '24rpx'
-		}">{{closeText}}</text>
-	</view>
-</template>
-
-<script>
-	/**
-	 * alertTips 警告提示
-	 * @description 警告提示,展现需要关注的信息
-	 * @tutorial https://uviewui.com/components/alertTips.html
-	 * @property {String} title 显示的标题文字
-	 * @property {String} description 辅助性文字,颜色比title浅一点,字号也小一点,可选
-	 * @property {String} type 关闭按钮(默认为叉号icon图标)
-	 * @property {String} icon 图标名称
-	 * @property {Object} icon-style 图标的样式,对象形式
-	 * @property {Object} title-style 标题的样式,对象形式
-	 * @property {Object} desc-style 描述的样式,对象形式
-	 * @property {String} close-able 用文字替代关闭图标,close-able为true时有效
-	 * @property {Boolean} show-icon 是否显示左边的辅助图标
-	 * @property {Boolean} show 显示或隐藏组件
-	 * @event {Function} click 点击组件时触发
-	 * @event {Function} close 点击关闭按钮时触发
-	 */
-	export default {
-		name: 'u-alert-tips',
-		props: {
-			// 显示文字
-			title: {
-				type: String,
-				default: ''
-			},
-			// 主题,success/warning/info/error
-			type: {
-				type: String,
-				default: 'warning'
-			},
-			// 辅助性文字
-			description: {
-				type: String,
-				default: ''
-			},
-			// 是否可关闭
-			closeAble: {
-				type: Boolean,
-				default: false
-			},
-			// 关闭按钮自定义文本
-			closeText: {
-				type: String,
-				default: ''
-			},
-			// 是否显示图标
-			showIcon: {
-				type: Boolean,
-				default: false
-			},
-			// 文字颜色,如果定义了color值,icon会失效
-			color: {
-				type: String,
-				default: ''
-			},
-			// 背景颜色
-			bgColor: {
-				type: String,
-				default: ''
-			},
-			// 边框颜色
-			borderColor: {
-				type: String,
-				default: ''
-			},
-			// 是否显示
-			show: {
-				type: Boolean,
-				default: true
-			},
-			// 左边显示的icon
-			icon: {
-				type: String,
-				default: ''
-			},
-			// icon的样式
-			iconStyle: {
-				type: Object,
-				default() {
-					return {}
-				}
-			},
-			// 标题的样式
-			titleStyle: {
-				type: Object,
-				default() {
-					return {}
-				}
-			},
-			// 描述文字的样式
-			descStyle: {
-				type: Object,
-				default() {
-					return {}
-				}
-			},
-		},
-		data() {
-			return {
-			}
-		},
-		computed: {
-			uTitleStyle() {
-				let style = {};
-				// 如果有描述文字的话,标题进行加粗
-				style.fontWeight = this.description ? 500 : 'normal';
-				// 将用户传入样式对象和style合并,传入的优先级比style高,同属性会被覆盖
-				return this.$u.deepMerge(style, this.titleStyle);
-			},
-			uIcon() {
-				// 如果有设置icon名称就使用,否则根据type主题,推定一个默认的图标
-				return this.icon ? this.icon : this.$u.type2icon(this.type);
-			},
-			uIconType() {
-				// 如果有设置图标的样式,优先使用,没有的话,则用type的样式
-				return Object.keys(this.iconStyle).length ? '' : this.type;
-			}
-		},
-		methods: {
-			// 点击内容
-			click() {
-				this.$emit('click');
-			},
-			// 点击关闭按钮
-			close() {
-				this.$emit('close');
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-	
-	.u-alert-tips {
-		@include vue-flex;
-		align-items: center;
-		padding: 16rpx 30rpx;
-		border-radius: 8rpx;
-		position: relative;
-		transition: all 0.3s linear;
-		border: 1px solid #fff;
-		
-		&--bg--primary-light {
-			background-color: $u-type-primary-light;
-		}
-		
-		&--bg--info-light {
-			background-color: $u-type-info-light;
-		}
-		
-		&--bg--success-light {
-			background-color: $u-type-success-light;
-		}
-		
-		&--bg--warning-light {
-			background-color: $u-type-warning-light;
-		}
-		
-		&--bg--error-light {
-			background-color: $u-type-error-light;
-		}
-		
-		&--border--primary-disabled {
-			border-color: $u-type-primary-disabled;
-		}
-		
-		&--border--success-disabled {
-			border-color: $u-type-success-disabled;
-		}
-		
-		&--border--error-disabled {
-			border-color: $u-type-error-disabled;
-		}
-		
-		&--border--warning-disabled {
-			border-color: $u-type-warning-disabled;
-		}
-		
-		&--border--info-disabled {
-			border-color: $u-type-info-disabled;
-		}
-	}
-
-	.u-close-alert-tips {
-		opacity: 0;
-		visibility: hidden;
-	}
-
-	.u-icon {
-		margin-right: 16rpx;
-	}
-
-	.u-alert-title {
-		font-size: 28rpx;
-		color: $u-main-color;
-	}
-
-	.u-alert-desc {
-		font-size: 26rpx;
-		text-align: left;
-		color: $u-content-color;
-	}
-
-	.u-close-icon {
-		position: absolute;
-		top: 20rpx;
-		right: 20rpx;
-	}
-
-	.u-close-hover {
-		color: red;
-	}
-	
-	.u-close-text {
-		font-size: 24rpx;
-		color: $u-tips-color;
-		position: absolute;
-		top: 20rpx;
-		right: 20rpx;
-		line-height: 1;
-	}
-</style>

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

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

File diff suppressed because it is too large
+ 0 - 1265
components/uview-ui/components/u-avatar-cropper/weCropper.js


File diff suppressed because it is too large
+ 0 - 244
components/uview-ui/components/u-avatar/u-avatar.vue


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

@@ -1,153 +0,0 @@
-<template>
-	<view @tap="backToTop" class="u-back-top" :class="['u-back-top--mode--' + mode]" :style="[{
-		bottom: bottom + 'rpx',
-		right: right + 'rpx',
-		borderRadius: mode == 'circle' ? '10000rpx' : '8rpx',
-		zIndex: uZIndex,
-		opacity: opacity
-	}, customStyle]">
-		<view class="u-back-top__content" v-if="!$slots.default && !$slots.$default">
-			<u-icon @click="backToTop" :name="icon" :custom-style="iconStyle"></u-icon>
-			<view class="u-back-top__content__tips">
-				{{tips}}
-			</view>
-		</view>
-		<slot v-else />
-	</view>
-</template>
-
-<script>
-	export default {
-		name: 'u-back-top',
-		props: {
-			// 返回顶部的形状,circle-圆形,square-方形
-			mode: {
-				type: String,
-				default: 'circle'
-			},
-			// 自定义图标
-			icon: {
-				type: String,
-				default: 'arrow-upward'
-			},
-			// 提示文字
-			tips: {
-				type: String,
-				default: ''
-			},
-			// 返回顶部滚动时间
-			duration: {
-				type: [Number, String],
-				default: 100
-			},
-			// 滚动距离
-			scrollTop: {
-				type: [Number, String],
-				default: 0
-			},
-			// 距离顶部多少距离显示,单位rpx
-			top: {
-				type: [Number, String],
-				default: 400
-			},
-			// 返回顶部按钮到底部的距离,单位rpx
-			bottom: {
-				type: [Number, String],
-				default: 200
-			},
-			// 返回顶部按钮到右边的距离,单位rpx
-			right: {
-				type: [Number, String],
-				default: 40
-			},
-			// 层级
-			zIndex: {
-				type: [Number, String],
-				default: '9'
-			},
-			// 图标的样式,对象形式
-			iconStyle: {
-				type: Object,
-				default() {
-					return {
-						color: '#909399',
-						fontSize: '38rpx'
-					}
-				}
-			},
-			// 整个组件的样式
-			customStyle: {
-				type: Object,
-				default() {
-					return {}
-				}
-			}
-		},
-		watch: {
-			showBackTop(nVal, oVal) {
-				// 当组件的显示与隐藏状态发生跳变时,修改组件的层级和不透明度
-				// 让组件有显示和消失的动画效果,如果用v-if控制组件状态,将无设置动画效果
-				if(nVal) {
-					this.uZIndex = this.zIndex;
-					this.opacity = 1;
-				} else {
-					this.uZIndex = -1;
-					this.opacity = 0;
-				}
-			}
-		},
-		computed: {
-			showBackTop() {
-				// 由于scrollTop为页面的滚动距离,默认为px单位,这里将用于传入的top(rpx)值
-				// 转为px用于比较,如果滚动条到顶的距离大于设定的距离,就显示返回顶部的按钮
-				return this.scrollTop > uni.upx2px(this.top);
-			},
-		},
-		data() {
-			return {
-				// 不透明度,为了让组件有一个显示和隐藏的过渡动画
-				opacity: 0,
-				// 组件的z-index值,隐藏时设置为-1,就会看不到
-				uZIndex: -1
-			}
-		},
-		methods: {
-			backToTop() {
-				uni.pageScrollTo({
-					scrollTop: 0,
-					duration: this.duration
-				});
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-	
-	.u-back-top {
-		width: 80rpx;
-		height: 80rpx;
-		position: fixed;
-		z-index: 9;
-		@include vue-flex;
-		flex-direction: column;
-		justify-content: center;
-		background-color: #E1E1E1;
-		color: $u-content-color;
-		align-items: center;
-		transition: opacity 0.4s;
-		
-		&__content {
-			@include vue-flex;
-			flex-direction: column;
-			align-items: center;
-			
-			&__tips {
-				font-size: 24rpx;
-				transform: scale(0.8);
-				line-height: 1;
-			}
-		}
-	}
-</style>

+ 0 - 216
components/uview-ui/components/u-badge/u-badge.vue

@@ -1,216 +0,0 @@
-<template>
-	<view v-if="show" class="u-badge" :class="[
-			isDot ? 'u-badge-dot' : '', 
-			size == 'mini' ? 'u-badge-mini' : '',
-			type ? 'u-badge--bg--' + type : ''
-		]" :style="[{
-			top: offset[0] + 'rpx',
-			right: offset[1] + 'rpx',
-			fontSize: fontSize + 'rpx',
-			position: absolute ? 'absolute' : 'static',
-			color: color,
-			backgroundColor: bgColor
-		}, boxStyle]"
-	>
-		{{showText}}
-	</view>
-</template>
-
-<script>
-	/**
-	 * badge 角标
-	 * @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
-	 * @tutorial https://www.uviewui.com/components/badge.html
-	 * @property {String Number} count 展示的数字,大于 overflowCount 时显示为 ${overflowCount}+,为0且show-zero为false时隐藏
-	 * @property {Boolean} is-dot 不展示数字,只有一个小点(默认false)
-	 * @property {Boolean} absolute 组件是否绝对定位,为true时,offset参数才有效(默认true)
-	 * @property {String Number} overflow-count 展示封顶的数字值(默认99)
-	 * @property {String} type 使用预设的背景颜色(默认error)
-	 * @property {Boolean} show-zero 当数值为 0 时,是否展示 Badge(默认false)
-	 * @property {String} size Badge的尺寸,设为mini会得到小一号的Badge(默认default)
-	 * @property {Array} offset 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,单位rpx。absolute为true时有效(默认[20, 20])
-	 * @property {String} color 字体颜色(默认#ffffff)
-	 * @property {String} bgColor 背景颜色,优先级比type高,如设置,type参数会失效
-	 * @property {Boolean} is-center 组件中心点是否和父组件右上角重合,优先级比offset高,如设置,offset参数会失效(默认false)
-	 * @example <u-badge type="error" count="7"></u-badge>
-	 */
-	export default {
-		name: 'u-badge',
-		props: {
-			// primary,warning,success,error,info
-			type: {
-				type: String,
-				default: 'error'
-			},
-			// default, mini
-			size: {
-				type: String,
-				default: 'default'
-			},
-			//是否是圆点
-			isDot: {
-				type: Boolean,
-				default: false
-			},
-			// 显示的数值内容
-			count: {
-				type: [Number, String],
-			},
-			// 展示封顶的数字值
-			overflowCount: {
-				type: Number,
-				default: 99
-			},
-			// 当数值为 0 时,是否展示 Badge
-			showZero: {
-				type: Boolean,
-				default: false
-			},
-			// 位置偏移
-			offset: {
-				type: Array,
-				default: () => {
-					return [20, 20]
-				}
-			},
-			// 是否开启绝对定位,开启了offset才会起作用
-			absolute: {
-				type: Boolean,
-				default: true
-			},
-			// 字体大小
-			fontSize: {
-				type: [String, Number],
-				default: '24'
-			},
-			// 字体演示
-			color: {
-				type: String,
-				default: '#ffffff'
-			},
-			// badge的背景颜色
-			bgColor: {
-				type: String,
-				default: ''
-			},
-			// 是否让badge组件的中心点和父组件右上角重合,配置的话,offset将会失效
-			isCenter: {
-				type: Boolean,
-				default: false
-			}
-		},
-		computed: {
-			// 是否将badge中心与父组件右上角重合
-			boxStyle() {
-				let style = {};
-				if(this.isCenter) {
-					style.top = 0;
-					style.right = 0;
-					// Y轴-50%,意味着badge向上移动了badge自身高度一半,X轴50%,意味着向右移动了自身宽度一半
-					style.transform = "translateY(-50%) translateX(50%)";
-				} else {
-					style.top = this.offset[0] + 'rpx';
-					style.right = this.offset[1] + 'rpx';
-					style.transform = "translateY(0) translateX(0)";
-				}
-				// 如果尺寸为mini,后接上scal()
-				if(this.size == 'mini') {
-					style.transform = style.transform + " scale(0.8)";
-				}
-				return style;
-			},
-			// isDot类型时,不显示文字
-			showText() {
-				if(this.isDot) return '';
-				else {
-					if(this.count > this.overflowCount) return `${this.overflowCount}+`;
-					else return this.count;
-				}
-			},
-			// 是否显示组件
-			show() {
-				// 如果count的值为0,并且showZero设置为false,不显示组件
-				if(this.count == 0 && this.showZero == false) return false;
-				else return true;
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-	
-	.u-badge {
-		/* #ifndef APP-NVUE */
-		display: inline-flex;
-		/* #endif */
-		justify-content: center;
-		align-items: center;
-		line-height: 24rpx;
-		padding: 4rpx 8rpx;
-		border-radius: 100rpx;
-		z-index: 9;
-		
-		&--bg--primary {
-			background-color: $u-type-primary;
-		}
-		
-		&--bg--error {
-			background-color: $u-type-error;
-		}
-		
-		&--bg--success {
-			background-color: $u-type-success;
-		}
-		
-		&--bg--info {
-			background-color: $u-type-info;
-		}
-		
-		&--bg--warning {
-			background-color: $u-type-warning;
-		}
-	}
-	
-	.u-badge-dot {
-		height: 16rpx;
-		width: 16rpx;
-		border-radius: 100rpx;
-		line-height: 1;
-	}
-	
-	.u-badge-mini {
-		transform: scale(0.8);
-		transform-origin: center center;
-	}
-	
-	// .u-primary {
-	// 	background: $u-type-primary;
-	// 	color: #fff;
-	// }
-	
-	// .u-error {
-	// 	background: $u-type-error;
-	// 	color: #fff;
-	// }
-	
-	// .u-warning {
-	// 	background: $u-type-warning;
-	// 	color: #fff;
-	// }
-	
-	// .u-success {
-	// 	background: $u-type-success;
-	// 	color: #fff;
-	// }
-	
-	// .u-black {
-	// 	background: #585858;
-	// 	color: #fff;
-	// }
-	
-	.u-info {
-		background-color: $u-type-info;
-		color: #fff;
-	}
-</style>

+ 0 - 596
components/uview-ui/components/u-button/u-button.vue

@@ -1,596 +0,0 @@
-<template>
-	<button
-		id="u-wave-btn"
-		class="u-btn u-line-1 u-fix-ios-appearance"
-		:class="[
-			'u-size-' + size,
-			plain ? 'u-btn--' + type + '--plain' : '',
-			loading ? 'u-loading' : '',
-			shape == 'circle' ? 'u-round-circle' : '',
-			hairLine ? showHairLineBorder : 'u-btn--bold-border',
-			'u-btn--' + type,
-			disabled ? `u-btn--${type}--disabled` : '',
-		]"
-		:hover-start-time="Number(hoverStartTime)"
-		:hover-stay-time="Number(hoverStayTime)"
-		:disabled="disabled"
-		: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"
-		:style="[customStyle, {
-			overflow: ripple ? 'hidden' : 'visible'
-		}]"
-		@tap.stop="click($event)"
-		:hover-class="getHoverClass"
-		:loading="loading"
-	>
-		<slot></slot>
-		<view
-			v-if="ripple"
-			class="u-wave-ripple"
-			:class="[waveActive ? 'u-wave-active' : '']"
-			:style="{
-				top: rippleTop + 'px',
-				left: rippleLeft + 'px',
-				width: fields.targetWidth + 'px',
-				height: fields.targetWidth + 'px',
-				'background-color': rippleBgColor || 'rgba(0, 0, 0, 0.15)'
-			}"
-		></view>
-	</button>
-</template>
-
-<script>
-/**
- * button 按钮
- * @description Button 按钮
- * @tutorial https://www.uviewui.com/components/button.html
- * @property {String} size 按钮的大小
- * @property {Boolean} ripple 是否开启点击水波纹效果
- * @property {String} ripple-bg-color 水波纹的背景色,ripple为true时有效
- * @property {String} type 按钮的样式类型
- * @property {Boolean} plain 按钮是否镂空,背景色透明
- * @property {Boolean} disabled 是否禁用
- * @property {Boolean} hair-line 是否显示按钮的细边框(默认true)
- * @property {Boolean} shape 按钮外观形状,见文档说明
- * @property {Boolean} loading 按钮名称前是否带 loading 图标(App-nvue 平台,在 ios 上为雪花,Android上为圆圈)
- * @property {String} form-type 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件
- * @property {String} open-type 开放能力
- * @property {String} data-name 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
- * @property {String} hover-class 指定按钮按下去的样式类。当 hover-class="none" 时,没有点击态效果(App-nvue 平台暂不支持)
- * @property {Number} hover-start-time 按住后多久出现点击态,单位毫秒
- * @property {Number} hover-stay-time 手指松开后点击态保留时间,单位毫秒
- * @property {Object} custom-style 对按钮的自定义样式,对象形式,见文档说明
- * @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',
-	props: {
-		// 是否细边框
-		hairLine: {
-			type: Boolean,
-			default: true
-		},
-		// 按钮的预置样式,default,primary,error,warning,success
-		type: {
-			type: String,
-			default: 'default'
-		},
-		// 按钮尺寸,default,medium,mini
-		size: {
-			type: String,
-			default: 'default'
-		},
-		// 按钮形状,circle(两边为半圆),square(带圆角)
-		shape: {
-			type: String,
-			default: 'square'
-		},
-		// 按钮是否镂空
-		plain: {
-			type: Boolean,
-			default: false
-		},
-		// 是否禁止状态
-		disabled: {
-			type: Boolean,
-			default: false
-		},
-		// 是否加载中
-		loading: {
-			type: Boolean,
-			default: false
-		},
-		// 开放能力,具体请看uniapp稳定关于button组件部分说明
-		// https://uniapp.dcloud.io/component/button
-		openType: {
-			type: String,
-			default: ''
-		},
-		// 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件
-		// 取值为submit(提交表单),reset(重置表单)
-		formType: {
-			type: String,
-			default: ''
-		},
-		// 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效
-		// 只微信小程序、QQ小程序有效
-		appParameter: {
-			type: String,
-			default: ''
-		},
-		// 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效
-		hoverStopPropagation: {
-			type: Boolean,
-			default: false
-		},
-		// 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效
-		lang: {
-			type: String,
-			default: 'en'
-		},
-		// 会话来源,open-type="contact"时有效。只微信小程序有效
-		sessionFrom: {
-			type: String,
-			default: ''
-		},
-		// 会话内消息卡片标题,open-type="contact"时有效
-		// 默认当前标题,只微信小程序有效
-		sendMessageTitle: {
-			type: String,
-			default: ''
-		},
-		// 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效
-		// 默认当前分享路径,只微信小程序有效
-		sendMessagePath: {
-			type: String,
-			default: ''
-		},
-		// 会话内消息卡片图片,open-type="contact"时有效
-		// 默认当前页面截图,只微信小程序有效
-		sendMessageImg: {
-			type: String,
-			default: ''
-		},
-		// 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,
-		// 用户点击后可以快速发送小程序消息,open-type="contact"时有效
-		showMessageCard: {
-			type: Boolean,
-			default: false
-		},
-		// 手指按(触摸)按钮时按钮时的背景颜色
-		hoverBgColor: {
-			type: String,
-			default: ''
-		},
-		// 水波纹的背景颜色
-		rippleBgColor: {
-			type: String,
-			default: ''
-		},
-		// 是否开启水波纹效果
-		ripple: {
-			type: Boolean,
-			default: false
-		},
-		// 按下的类名
-		hoverClass: {
-			type: String,
-			default: ''
-		},
-		// 自定义样式,对象形式
-		customStyle: {
-			type: Object,
-			default() {
-				return {};
-			}
-		},
-		// 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
-		dataName: {
-			type: String,
-			default: ''
-		},
-		// 节流,一定时间内只能触发一次
-		throttleTime: {
-			type: [String, Number],
-			default: 1000
-		},
-		// 按住后多久出现点击态,单位毫秒
-		hoverStartTime: {
-			type: [String, Number],
-			default: 20
-		},
-		// 手指松开后点击态保留时间,单位毫秒
-		hoverStayTime: {
-			type: [String, Number],
-			default: 150
-		},
-	},
-	computed: {
-		// 当没有传bgColor变量时,按钮按下去的颜色类名
-		getHoverClass() {
-			// 如果开启水波纹效果,则不启用hover-class效果
-			if (this.loading || this.disabled || this.ripple || this.hoverClass) return '';
-			let hoverClass = '';
-			hoverClass = this.plain ? 'u-' + this.type + '-plain-hover' : 'u-' + this.type + '-hover';
-			return hoverClass;
-		},
-		// 在'primary', 'success', 'error', 'warning'类型下,不显示边框,否则会造成四角有毛刺现象
-		showHairLineBorder() {
-			if (['primary', 'success', 'error', 'warning'].indexOf(this.type) >= 0 && !this.plain) {
-				return '';
-			} else {
-				return 'u-hairline-border';
-			}
-		}
-	},
-	data() {
-		return {
-			rippleTop: 0, // 水波纹的起点Y坐标到按钮上边界的距离
-			rippleLeft: 0, // 水波纹起点X坐标到按钮左边界的距离
-			fields: {}, // 波纹按钮节点信息
-			waveActive: false // 激活水波纹
-		};
-	},
-	methods: {
-		// 按钮点击
-		click(e) {
-			// 进行节流控制,每this.throttle毫秒内,只在开始处执行
-			this.$u.throttle(() => {
-				// 如果按钮时disabled和loading状态,不触发水波纹效果
-				if (this.loading === true || this.disabled === true) return;
-				// 是否开启水波纹效果
-				if (this.ripple) {
-					// 每次点击时,移除上一次的类,再次添加,才能触发动画效果
-					this.waveActive = false;
-					this.$nextTick(function() {
-						this.getWaveQuery(e);
-					});
-				}
-				this.$emit('click', e);
-			}, this.throttleTime);
-		},
-		// 查询按钮的节点信息
-		getWaveQuery(e) {
-			this.getElQuery().then(res => {
-				// 查询返回的是一个数组节点
-				let data = res[0];
-				// 查询不到节点信息,不操作
-				if (!data.width || !data.width) return;
-				// 水波纹的最终形态是一个正方形(通过border-radius让其变为一个圆形),这里要保证正方形的边长等于按钮的最长边
-				// 最终的方形(变换后的圆形)才能覆盖整个按钮
-				data.targetWidth = data.height > data.width ? data.height : data.width;
-				if (!data.targetWidth) return;
-				this.fields = data;
-				let touchesX = '',
-					touchesY = '';
-				// #ifdef MP-BAIDU
-				touchesX = e.changedTouches[0].clientX;
-				touchesY = e.changedTouches[0].clientY;
-				// #endif
-				// #ifdef MP-ALIPAY
-				touchesX = e.detail.clientX;
-				touchesY = e.detail.clientY;
-				// #endif
-				// #ifndef MP-BAIDU || MP-ALIPAY
-				touchesX = e.touches[0].clientX;
-				touchesY = e.touches[0].clientY;
-				// #endif
-				// 获取触摸点相对于按钮上边和左边的x和y坐标,原理是通过屏幕的触摸点(touchesY),减去按钮的上边界data.top
-				// 但是由于`transform-origin`默认是center,所以这里再减去半径才是水波纹view应该的位置
-				// 总的来说,就是把水波纹的矩形(变换后的圆形)的中心点,移动到我们的触摸点位置
-				this.rippleTop = touchesY - data.top - data.targetWidth / 2;
-				this.rippleLeft = touchesX - data.left - data.targetWidth / 2;
-				this.$nextTick(() => {
-					this.waveActive = true;
-				});
-			});
-		},
-		// 获取节点信息
-		getElQuery() {
-			return new Promise(resolve => {
-				let queryInfo = '';
-				// 获取元素节点信息,请查看uniapp相关文档
-				// https://uniapp.dcloud.io/api/ui/nodes-info?id=nodesrefboundingclientrect
-				queryInfo = uni.createSelectorQuery().in(this);
-				//#ifdef MP-ALIPAY
-				queryInfo = uni.createSelectorQuery();
-				//#endif
-				queryInfo.select('.u-btn').boundingClientRect();
-				queryInfo.exec(data => {
-					resolve(data);
-				});
-			});
-		},
-		// 下面为对接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 scoped lang="scss">
-@import '../../libs/css/style.components.scss';
-.u-btn::after {
-	border: none;
-}
-
-.u-btn {
-	position: relative;
-	border: 0;
-	//border-radius: 10rpx;
-	/* #ifndef APP-NVUE */
-	display: inline-flex;		
-	/* #endif */
-	// 避免边框某些场景可能被“裁剪”,不能设置为hidden
-	overflow: visible;
-	line-height: 1;
-	@include vue-flex;
-	align-items: center;
-	justify-content: center;
-	cursor: pointer;
-	padding: 0 40rpx;
-	z-index: 1;
-	box-sizing: border-box;
-	transition: all 0.15s;
-	
-	&--bold-border {
-		border: 1px solid #ffffff;
-	}
-	
-	&--default {
-		color: $u-content-color;
-		border-color: #c0c4cc;
-		background-color: #ffffff;
-	}
-	
-	&--primary {
-		color: #ffffff;
-		border-color: $u-type-primary;
-		background-color: $u-type-primary;
-	}
-	
-	&--success {
-		color: #ffffff;
-		border-color: $u-type-success;
-		background-color: $u-type-success;
-	}
-	
-	&--error {
-		color: #ffffff;
-		border-color: $u-type-error;
-		background-color: $u-type-error;
-	}
-	
-	&--warning {
-		color: #ffffff;
-		border-color: $u-type-warning;
-		background-color: $u-type-warning;
-	}
-	
-	&--default--disabled {
-		color: #ffffff;
-		border-color: #e4e7ed;
-		background-color: #ffffff;
-	}
-	
-	&--primary--disabled {
-		color: #ffffff!important;
-		border-color: $u-type-primary-disabled!important;
-		background-color: $u-type-primary-disabled!important;
-	}
-	
-	&--success--disabled {
-		color: #ffffff!important;
-		border-color: $u-type-success-disabled!important;
-		background-color: $u-type-success-disabled!important;
-	}
-	
-	&--error--disabled {
-		color: #ffffff!important;
-		border-color: $u-type-error-disabled!important;
-		background-color: $u-type-error-disabled!important;
-	}
-	
-	&--warning--disabled {
-		color: #ffffff!important;
-		border-color: $u-type-warning-disabled!important;
-		background-color: $u-type-warning-disabled!important;
-	}
-	
-	&--primary--plain {
-		color: $u-type-primary!important;
-		border-color: $u-type-primary-disabled!important;
-		background-color: $u-type-primary-light!important;
-	}
-	
-	&--success--plain {
-		color: $u-type-success!important;
-		border-color: $u-type-success-disabled!important;
-		background-color: $u-type-success-light!important;
-	}
-	
-	&--error--plain {
-		color: $u-type-error!important;
-		border-color: $u-type-error-disabled!important;
-		background-color: $u-type-error-light!important;
-	}
-	
-	&--warning--plain {
-		color: $u-type-warning!important;
-		border-color: $u-type-warning-disabled!important;
-		background-color: $u-type-warning-light!important;
-	}
-}
-
-.u-hairline-border:after {
-	content: ' ';
-	position: absolute;
-	pointer-events: none;
-	// 设置为border-box,意味着下面的scale缩小为0.5,实际上缩小的是伪元素的内容(border-box意味着内容不含border)
-	box-sizing: border-box;
-	// 中心点作为变形(scale())的原点
-	-webkit-transform-origin: 0 0;
-	transform-origin: 0 0;
-	left: 0;
-	top: 0;
-	width: 199.8%;
-	height: 199.7%;
-	-webkit-transform: scale(0.5, 0.5);
-	transform: scale(0.5, 0.5);
-	border: 1px solid currentColor;
-	z-index: 1;
-}
-
-.u-wave-ripple {
-	z-index: 0;
-	position: absolute;
-	border-radius: 100%;
-	background-clip: padding-box;
-	pointer-events: none;
-	user-select: none;
-	transform: scale(0);
-	opacity: 1;
-	transform-origin: center;
-}
-
-.u-wave-ripple.u-wave-active {
-	opacity: 0;
-	transform: scale(2);
-	transition: opacity 1s linear, transform 0.4s linear;
-}
-
-.u-round-circle {
-	border-radius: 100rpx;
-}
-
-.u-round-circle::after {
-	border-radius: 100rpx;
-}
-
-.u-loading::after {
-	background-color: hsla(0, 0%, 100%, 0.35);
-}
-
-.u-size-default {
-	font-size: 30rpx;
-	height: 80rpx;
-	line-height: 80rpx;
-}
-
-.u-size-medium {
-	/* #ifndef APP-NVUE */
-	display: inline-flex;		
-	/* #endif */
-	width: auto;
-	font-size: 26rpx;
-	height: 70rpx;
-	line-height: 70rpx;
-	padding: 0 80rpx;
-}
-
-.u-size-mini {
-	/* #ifndef APP-NVUE */
-	display: inline-flex;		
-	/* #endif */
-	width: auto;
-	font-size: 22rpx;
-	padding-top: 1px;
-	height: 50rpx;
-	line-height: 50rpx;
-	padding: 0 20rpx;
-}
-
-.u-primary-plain-hover {
-	color: #ffffff !important;
-	background: $u-type-primary-dark !important;
-}
-
-.u-default-plain-hover {
-	color: $u-type-primary-dark !important;
-	background: $u-type-primary-light !important;
-}
-
-.u-success-plain-hover {
-	color: #ffffff !important;
-	background: $u-type-success-dark !important;
-}
-
-.u-warning-plain-hover {
-	color: #ffffff !important;
-	background: $u-type-warning-dark !important;
-}
-
-.u-error-plain-hover {
-	color: #ffffff !important;
-	background: $u-type-error-dark !important;
-}
-
-.u-info-plain-hover {
-	color: #ffffff !important;
-	background: $u-type-info-dark !important;
-}
-
-.u-default-hover {
-	color: $u-type-primary-dark !important;
-	border-color: $u-type-primary-dark !important;
-	background-color: $u-type-primary-light !important;
-}
-
-.u-primary-hover {
-	background: $u-type-primary-dark !important;
-	color: #fff;
-}
-
-.u-success-hover {
-	background: $u-type-success-dark !important;
-	color: #fff;
-}
-
-.u-info-hover {
-	background: $u-type-info-dark !important;
-	color: #fff;
-}
-
-.u-warning-hover {
-	background: $u-type-warning-dark !important;
-	color: #fff;
-}
-
-.u-error-hover {
-	background: $u-type-error-dark !important;
-	color: #fff;
-}
-</style>

+ 0 - 639
components/uview-ui/components/u-calendar/u-calendar.vue

@@ -1,639 +0,0 @@
-<template>
-	<u-popup closeable :maskCloseAble="maskCloseAble" mode="bottom" :popup="false" v-model="value" length="auto"
-	 :safeAreaInsetBottom="safeAreaInsetBottom" @close="close" :z-index="uZIndex" :border-radius="borderRadius" :closeable="closeable">
-		<view class="u-calendar">
-			<view class="u-calendar__header">
-				<view class="u-calendar__header__text" v-if="!$slots['tooltip']">
-					{{toolTip}}
-				</view>
-				<slot v-else name="tooltip" />
-			</view>
-			<view class="u-calendar__action u-flex u-row-center">
-				<view class="u-calendar__action__icon">
-					<u-icon v-if="changeYear" name="arrow-left-double" :color="yearArrowColor" @click="changeYearHandler(0)"></u-icon>
-				</view>
-				<view class="u-calendar__action__icon">
-					<u-icon v-if="changeMonth" name="arrow-left" :color="monthArrowColor" @click="changeMonthHandler(0)"></u-icon>
-				</view>
-				<view class="u-calendar__action__text">{{ showTitle }}</view>
-				<view class="u-calendar__action__icon">
-					<u-icon v-if="changeMonth" name="arrow-right" :color="monthArrowColor" @click="changeMonthHandler(1)"></u-icon>
-				</view>
-				<view class="u-calendar__action__icon">
-					<u-icon v-if="changeYear" name="arrow-right-double" :color="yearArrowColor" @click="changeYearHandler(1)"></u-icon>
-				</view>
-			</view>
-			<view class="u-calendar__week-day">
-				<view class="u-calendar__week-day__text" v-for="(item, index) in weekDayZh" :key="index">{{item}}</view>
-			</view>
-			<view class="u-calendar__content">
-				<!-- 前置空白部分 -->
-				<block v-for="(item, index) in weekdayArr" :key="index">
-					<view class="u-calendar__content__item"></view>
-				</block>
-				<view class="u-calendar__content__item" :class="{
-					'u-hover-class':openDisAbled(year,month,index+1),
-					'u-calendar__content--start-date': (mode == 'range' && startDate==`${year}-${month}-${index+1}`) || mode== 'date',
-					'u-calendar__content--end-date':(mode== 'range' && endDate==`${year}-${month}-${index+1}`) || mode == 'date'
-				}" :style="{backgroundColor: getColor(index,1)}" v-for="(item, index) in daysArr" :key="index"
-				 @tap="dateClick(index)">
-					<view class="u-calendar__content__item__inner" :style="{color: getColor(index,2)}">
-						<view>{{ index + 1 }}</view>
-					</view>
-					<view class="u-calendar__content__item__tips" :style="{color:activeColor}" v-if="mode== 'range' && startDate==`${year}-${month}-${index+1}` && startDate!=endDate">{{startText}}</view>
-					<view class="u-calendar__content__item__tips" :style="{color:activeColor}" v-if="mode== 'range' && endDate==`${year}-${month}-${index+1}`">{{endText}}</view>
-				</view>
-				<view class="u-calendar__content__bg-month">{{month}}</view>
-			</view>
-			<view class="u-calendar__bottom">
-				<view class="u-calendar__bottom__choose">
-					<text>{{mode == 'date' ? activeDate : startDate}}</text>
-					<text v-if="endDate">至{{endDate}}</text>
-				</view>
-				<view class="u-calendar__bottom__btn">
-					<u-button :type="btnType" shape="circle" size="default" @click="btnFix(false)">确定</u-button>
-				</view>
-			</view>
-		</view>
-	</u-popup>
-</template>
-<script>
-	/**
-	 * calendar 日历
-	 * @description 此组件用于单个选择日期,范围选择日期等,日历被包裹在底部弹起的容器中。
-	 * @tutorial http://uviewui.com/components/calendar.html
-	 * @property {String} mode 选择日期的模式,date-为单个日期,range-为选择日期范围
-	 * @property {Boolean} v-model 布尔值变量,用于控制日历的弹出与收起
-	 * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)
-	 * @property {Boolean} change-year 是否显示顶部的切换年份方向的按钮(默认true)
-	 * @property {Boolean} change-month 是否显示顶部的切换月份方向的按钮(默认true)
-	 * @property {String Number} max-year 可切换的最大年份(默认2050)
-	 * @property {String Number} min-year 可切换的最小年份(默认1950)
-	 * @property {String Number} min-date 最小可选日期(默认1950-01-01)
-	 * @property {String Number} max-date 最大可选日期(默认当前日期)
-	 * @property {String Number} 弹窗顶部左右两边的圆角值,单位rpx(默认20)
-	 * @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭日历(默认true)
-	 * @property {String} month-arrow-color 月份切换按钮箭头颜色(默认#606266)
-	 * @property {String} year-arrow-color 年份切换按钮箭头颜色(默认#909399)
-	 * @property {String} color 日期字体的默认颜色(默认#303133)
-	 * @property {String} active-bg-color 起始/结束日期按钮的背景色(默认#2979ff)
-	 * @property {String Number} z-index 弹出时的z-index值(默认10075)
-	 * @property {String} active-color 起始/结束日期按钮的字体颜色(默认#ffffff)
-	 * @property {String} range-bg-color 起始/结束日期之间的区域的背景颜色(默认rgba(41,121,255,0.13))
-	 * @property {String} range-color 选择范围内字体颜色(默认#2979ff)
-	 * @property {String} start-text 起始日期底部的提示文字(默认 '开始')
-	 * @property {String} end-text 结束日期底部的提示文字(默认 '结束')
-	 * @property {String} btn-type 底部确定按钮的主题(默认 'primary')
-	 * @property {String} toolTip 顶部提示文字,如设置名为tooltip的slot,此参数将失效(默认 '选择日期')
-	 * @property {Boolean} closeable 是否显示右上角的关闭图标(默认true)
-	 * @example <u-calendar v-model="show" :mode="mode"></u-calendar>
-	 */
-	
-	export default {
-		name: 'u-calendar',
-		props: {
-			safeAreaInsetBottom: {
-				type: Boolean,
-				default: false
-			},
-			// 是否允许通过点击遮罩关闭Picker
-			maskCloseAble: {
-				type: Boolean,
-				default: true
-			},
-			// 通过双向绑定控制组件的弹出与收起
-			value: {
-				type: Boolean,
-				default: false
-			},
-			// 弹出的z-index值
-			zIndex: {
-				type: [String, Number],
-				default: 0
-			},
-			// 是否允许切换年份
-			changeYear: {
-				type: Boolean,
-				default: true
-			},
-			// 是否允许切换月份
-			changeMonth: {
-				type: Boolean,
-				default: true
-			},
-			// date-单个日期选择,range-开始日期+结束日期选择
-			mode: {
-				type: String,
-				default: 'date'
-			},
-			// 可切换的最大年份
-			maxYear: {
-				type: [Number, String],
-				default: 2050
-			},
-			// 可切换的最小年份
-			minYear: {
-				type: [Number, String],
-				default: 1950
-			},
-			// 最小可选日期(不在范围内日期禁用不可选)
-			minDate: {
-				type: [Number, String],
-				default: '1950-01-01'
-			},
-			/**
-			 * 最大可选日期
-			 * 默认最大值为今天,之后的日期不可选
-			 * 2030-12-31
-			 * */
-			maxDate: {
-				type: [Number, String],
-				default: ''
-			},
-			// 弹窗顶部左右两边的圆角值
-			borderRadius: {
-				type: [String, Number],
-				default: 20
-			},
-			// 月份切换按钮箭头颜色
-			monthArrowColor: {
-				type: String,
-				default: '#606266'
-			},
-			// 年份切换按钮箭头颜色
-			yearArrowColor: {
-				type: String,
-				default: '#909399'
-			},
-			// 默认日期字体颜色
-			color: {
-				type: String,
-				default: '#303133'
-			},
-			// 选中|起始结束日期背景色
-			activeBgColor: {
-				type: String,
-				default: '#2979ff'
-			},
-			// 选中|起始结束日期字体颜色
-			activeColor: {
-				type: String,
-				default: '#ffffff'
-			},
-			// 范围内日期背景色
-			rangeBgColor: {
-				type: String,
-				default: 'rgba(41,121,255,0.13)'
-			}, 
-			// 范围内日期字体颜色
-			rangeColor: {
-				type: String,
-				default: '#2979ff'
-			},
-			// mode=range时生效,起始日期自定义文案
-			startText: {
-				type: String,
-				default: '开始'
-			},
-			// mode=range时生效,结束日期自定义文案
-			endText: {
-				type: String,
-				default: '结束'
-			},
-			//按钮样式类型
-			btnType: {
-				type: String,
-				default: 'primary'
-			},
-			// 当前选中日期带选中效果
-			isActiveCurrent: {
-				type: Boolean,
-				default: true
-			},
-			// 切换年月是否触发事件 mode=date时生效
-			isChange: {
-				type: Boolean,
-				default: false
-			},
-			// 是否显示右上角的关闭图标
-			closeable: {
-				type: Boolean,
-				default: true
-			},
-			// 顶部的提示文字
-			toolTip: {
-				type: String,
-				default: '选择日期'
-			}
-		},
-		data() {
-			return {
-				// 星期几,值为1-7
-				weekday: 1, 
-				weekdayArr:[],
-				// 当前月有多少天
-				days: 0, 
-				daysArr:[],
-				showTitle: '',
-				year: 2020,
-				month: 0,
-				day: 0,
-				startYear: 0,
-				startMonth: 0,
-				startDay: 0,
-				endYear: 0,
-				endMonth: 0,
-				endDay: 0,
-				today: '',
-				activeDate: '',
-				startDate: '',
-				endDate: '',
-				isStart: true,
-				min: null,
-				max: null,
-				weekDayZh: ['日', '一', '二', '三', '四', '五', '六']
-			};
-		},
-		computed: {
-			dataChange() {
-				return `${this.mode}-${this.minDate}-${this.maxDate}`;
-			},
-			uZIndex() {
-				// 如果用户有传递z-index值,优先使用
-				return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
-			}
-		},
-		watch: {
-			dataChange(val) {
-				this.init()
-			}
-		},
-		created() {
-			this.init()
-		},
-		methods: {
-			getColor(index, type) {
-				let color = type == 1 ? '' : this.color;
-				let day = index + 1
-				let date = `${this.year}-${this.month}-${day}`
-				let timestamp = new Date(date.replace(/\-/g, '/')).getTime();
-				let start = this.startDate.replace(/\-/g, '/')
-				let end = this.endDate.replace(/\-/g, '/')
-				if ((this.isActiveCurrent && this.activeDate == date) || this.startDate == date || this.endDate == date) {
-					color = type == 1 ? this.activeBgColor : this.activeColor;
-				} else if (this.endDate && timestamp > new Date(start).getTime() && timestamp < new Date(end).getTime()) {
-					color = type == 1 ? this.rangeBgColor : this.rangeColor;
-				}
-				return color;
-			},
-			init() {
-				let now = new Date();
-				this.year = now.getFullYear();
-				this.month = now.getMonth() + 1;
-				this.day = now.getDate();
-				this.today = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
-				this.activeDate = this.today;
-				this.min = this.initDate(this.minDate);
-				this.max = this.initDate(this.maxDate || this.today);
-				this.startDate = "";
-				this.startYear = 0;
-				this.startMonth = 0;
-				this.startDay = 0;
-				this.endYear = 0;
-				this.endMonth = 0;
-				this.endDay = 0;
-				this.endDate = "";
-				this.isStart = true;
-				this.changeData();
-			},
-			//日期处理
-			initDate(date) {
-				let fdate = date.split('-');
-				return {
-					year: Number(fdate[0] || 1920),
-					month: Number(fdate[1] || 1),
-					day: Number(fdate[2] || 1)
-				}
-			},
-			openDisAbled: function(year, month, day) {
-				let bool = true;
-				let date = `${year}/${month}/${day}`;
-				// let today = this.today.replace(/\-/g, '/');
-				let min = `${this.min.year}/${this.min.month}/${this.min.day}`;
-				let max = `${this.max.year}/${this.max.month}/${this.max.day}`;
-				let timestamp = new Date(date).getTime();
-				if (timestamp >= new Date(min).getTime() && timestamp <= new Date(max).getTime()) {
-					bool = false;
-				}
-				return bool;
-			},
-			generateArray: function(start, end) {
-				return Array.from(new Array(end + 1).keys()).slice(start);
-			},
-			formatNum: function(num) {
-				return num < 10 ? '0' + num : num + '';
-			},
-			//一个月有多少天
-			getMonthDay(year, month) {
-				let days = new Date(year, month, 0).getDate();
-				return days;
-			},
-			getWeekday(year, month) {
-				let date = new Date(`${year}/${month}/01 00:00:00`);
-				return date.getDay();
-			},
-			checkRange(year) {
-				let overstep = false;
-				if (year < this.minYear || year > this.maxYear) {
-					uni.showToast({
-						title: "日期超出范围啦~",
-						icon: 'none'
-					})
-					overstep = true;
-				}
-				return overstep;
-			},
-			changeMonthHandler(isAdd) {
-				if (isAdd) {
-					let month = this.month + 1;
-					let year = month > 12 ? this.year + 1 : this.year;
-					if (!this.checkRange(year)) {
-						this.month = month > 12 ? 1 : month;
-						this.year = year;
-						this.changeData();
-					}
-
-				} else {
-					let month = this.month - 1;
-					let year = month < 1 ? this.year - 1 : this.year;
-					if (!this.checkRange(year)) {
-						this.month = month < 1 ? 12 : month;
-						this.year = year;
-						this.changeData();
-					}
-				}
-			},
-			changeYearHandler(isAdd) {
-				let year = isAdd ? this.year + 1 : this.year - 1;
-				if (!this.checkRange(year)) {
-					this.year = year;
-					this.changeData();
-				}
-			},
-			changeData() {
-				this.days = this.getMonthDay(this.year, this.month);
-				this.daysArr=this.generateArray(1,this.days)
-				this.weekday = this.getWeekday(this.year, this.month);
-				this.weekdayArr=this.generateArray(1,this.weekday)
-				this.showTitle = `${this.year}年${this.month}月`;
-				if (this.isChange && this.mode == 'date') {
-					this.btnFix(true);
-				}
-			},
-			dateClick: function(day) {
-				day += 1;
-				if (!this.openDisAbled(this.year, this.month, day)) {
-					this.day = day;
-					let date = `${this.year}-${this.month}-${day}`;
-					if (this.mode == 'date') {
-						this.activeDate = date;
-					} else {
-						let compare = new Date(date.replace(/\-/g, '/')).getTime() < new Date(this.startDate.replace(/\-/g, '/')).getTime()
-						if (this.isStart || compare) {
-							this.startDate = date;
-							this.startYear = this.year;
-							this.startMonth = this.month;
-							this.startDay = this.day;
-							this.endYear = 0;
-							this.endMonth = 0;
-							this.endDay = 0;
-							this.endDate = "";
-							this.activeDate = "";
-							this.isStart = false;
-						} else {
-							this.endDate = date;
-							this.endYear = this.year;
-							this.endMonth = this.month;
-							this.endDay = this.day;
-							this.isStart = true;
-						}
-					}
-				}
-			},
-			close() {
-				// 修改通过v-model绑定的父组件变量的值为false,从而隐藏日历弹窗
-				this.$emit('input', false);
-			},
-			getWeekText(date) {
-				date = new Date(`${date.replace(/\-/g, '/')} 00:00:00`);
-				let week = date.getDay();
-				return '星期' + ['日', '一', '二', '三', '四', '五', '六'][week];
-			},
-			btnFix(show) {
-				if (!show) {
-					this.close();
-				}
-				if (this.mode == 'date') {
-					let arr = this.activeDate.split('-')
-					let year = this.isChange ? this.year : Number(arr[0]);
-					let month = this.isChange ? this.month : Number(arr[1]);
-					let day = this.isChange ? this.day : Number(arr[2]);
-					//当前月有多少天
-					let days = this.getMonthDay(year, month);
-					let result = `${year}-${this.formatNum(month)}-${this.formatNum(day)}`;
-					let weekText = this.getWeekText(result);
-					let isToday = false;
-					if (`${year}-${month}-${day}` == this.today) {
-						//今天
-						isToday = true;
-					}
-					this.$emit('change', {
-						year: year,
-						month: month,
-						day: day,
-						days: days,
-						result: result,
-						week: weekText,
-						isToday: isToday,
-						// switch: show //是否是切换年月操作
-					});
-				} else {
-					if (!this.startDate || !this.endDate) return;
-					let startMonth = this.formatNum(this.startMonth);
-					let startDay = this.formatNum(this.startDay);
-					let startDate = `${this.startYear}-${startMonth}-${startDay}`;
-					let startWeek = this.getWeekText(startDate)
-
-					let endMonth = this.formatNum(this.endMonth);
-					let endDay = this.formatNum(this.endDay);
-					let endDate = `${this.endYear}-${endMonth}-${endDay}`;
-					let endWeek = this.getWeekText(endDate);
-					this.$emit('change', {
-						startYear: this.startYear,
-						startMonth: this.startMonth,
-						startDay: this.startDay,
-						startDate: startDate,
-						startWeek: startWeek,
-						endYear: this.endYear,
-						endMonth: this.endMonth,
-						endDay: this.endDay,
-						endDate: endDate,
-						endWeek: endWeek
-					});
-				}
-			}
-		}
-	};
-</script>
-
-<style scoped lang="scss">
-	@import "../../libs/css/style.components.scss";
-	
-	.u-calendar {
-		color: $u-content-color;
-		
-		&__header {
-			width: 100%;
-			box-sizing: border-box;
-			font-size: 30rpx;
-			background-color: #fff;
-			color: $u-main-color;
-			
-			&__text {
-				margin-top: 30rpx;
-				padding: 0 60rpx;
-				@include vue-flex;
-				justify-content: center;
-				align-items: center;
-			}
-		}
-		
-		&__action {
-			padding: 40rpx 0 40rpx 0;
-			
-			&__icon {
-				margin: 0 16rpx;
-			}
-			
-			&__text {
-				padding: 0 16rpx;
-				color: $u-main-color;
-				font-size: 32rpx;
-				line-height: 32rpx;
-				font-weight: bold;
-			}
-		}
-	
-		&__week-day {
-			@include vue-flex;
-			align-items: center;
-			justify-content: center;
-			padding: 6px 0;
-			overflow: hidden;
-			
-			&__text {
-				flex: 1;
-				text-align: center;
-			}
-		}
-	
-		&__content {
-			width: 100%;
-			@include vue-flex;
-			flex-wrap: wrap;
-			padding: 6px 0;
-			box-sizing: border-box;
-			background-color: #fff;
-			position: relative;
-			
-			&--end-date {
-				border-top-right-radius: 8rpx;
-				border-bottom-right-radius: 8rpx;
-			}
-			
-			&--start-date {
-				border-top-left-radius: 8rpx;
-				border-bottom-left-radius: 8rpx;
-			}
-			
-			&__item {
-				width: 14.2857%;
-				@include vue-flex;
-				align-items: center;
-				justify-content: center;
-				padding: 6px 0;
-				overflow: hidden;
-				position: relative;
-				z-index: 2;
-				
-				&__inner {
-					height: 84rpx;
-					@include vue-flex;
-					align-items: center;
-					justify-content: center;
-					flex-direction: column;
-					font-size: 32rpx;
-					position: relative;
-					border-radius: 50%;
-					
-					&__desc {
-						width: 100%;
-						font-size: 24rpx;
-						line-height: 24rpx;
-						transform: scale(0.75);
-						transform-origin: center center;
-						position: absolute;
-						left: 0;
-						text-align: center;
-						bottom: 2rpx;
-					}
-				}
-				
-				&__tips {
-					width: 100%;
-					font-size: 24rpx;
-					line-height: 24rpx;
-					position: absolute;
-					left: 0;
-					transform: scale(0.8);
-					transform-origin: center center;
-					text-align: center;
-					bottom: 8rpx;
-					z-index: 2;
-				}
-			}
-			
-			&__bg-month {
-				position: absolute;
-				font-size: 130px;
-				line-height: 130px;
-				left: 50%;
-				top: 50%;
-				transform: translate(-50%, -50%);
-				color: #e4e7ed;
-				z-index: 1;
-			}
-		}
-	
-		&__bottom {
-			width: 100%;
-			@include vue-flex;
-			align-items: center;
-			justify-content: center;
-			flex-direction: column;
-			background-color: #fff;
-			padding: 0 40rpx 30rpx;
-			box-sizing: border-box;
-			font-size: 24rpx;
-			color: $u-tips-color;
-			
-			&__choose {
-				height: 50rpx;
-			}
-			
-			&__btn {
-				width: 100%;
-			}
-		}
-	}
-</style>

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

@@ -1,257 +0,0 @@
-<template>
-	<view class="u-keyboard" @touchmove.stop.prevent="() => {}">
-		<view class="u-keyboard-grids">
-			<block>
-				<view class="u-keyboard-grids-item" v-for="(group, i) in abc ? EngKeyBoardList : areaList" :key="i">
-					<view :hover-stay-time="100" @tap="carInputClick(i, j)" hover-class="u-carinput-hover" class="u-keyboard-grids-btn"
-					 v-for="(item, j) in group" :key="j">
-						{{ item }}
-					</view>
-				</view>
-				<view @touchstart="backspaceClick" @touchend="clearTimer" :hover-stay-time="100" class="u-keyboard-back"
-				 hover-class="u-hover-class">
-					<u-icon :size="38" name="backspace" :bold="true"></u-icon>
-				</view>
-				<view :hover-stay-time="100" class="u-keyboard-change" hover-class="u-carinput-hover" @tap="changeCarInputMode">
-					<text class="zh" :class="[!abc ? 'active' : 'inactive']">中</text>
-					/
-					<text class="en" :class="[abc ? 'active' : 'inactive']">英</text>
-				</view>
-			</block>
-		</view>
-	</view>
-</template>
-
-<script>
-	export default {
-		name: "u-keyboard",
-		props: {
-			// 是否打乱键盘按键的顺序
-			random: {
-				type: Boolean,
-				default: false
-			}
-		},
-		data() {
-			return {
-				// 车牌输入时,abc=true为输入车牌号码,bac=false为输入省份中文简称
-				abc: false
-			};
-		},
-		computed: {
-			areaList() {
-				let data = [
-					'京',
-					'沪',
-					'粤',
-					'津',
-					'冀',
-					'豫',
-					'云',
-					'辽',
-					'黑',
-					'湘',
-					'皖',
-					'鲁',
-					'苏',
-					'浙',
-					'赣',
-					'鄂',
-					'桂',
-					'甘',
-					'晋',
-					'陕',
-					'蒙',
-					'吉',
-					'闽',
-					'贵',
-					'渝',
-					'川',
-					'青',
-					'琼',
-					'宁',
-					'挂',
-					'藏',
-					'港',
-					'澳',
-					'新',
-					'使',
-					'学'
-				];
-				let tmp = [];
-				// 打乱顺序
-				if (this.random) data = this.$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 = this.$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];
-				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/style.components.scss";
-
-	.u-keyboard-grids {
-		background: rgb(215, 215, 217);
-		padding: 24rpx 0;
-		position: relative;
-	}
-
-	.u-keyboard-grids-item {
-		@include vue-flex;
-		align-items: center;
-		justify-content: center;
-	}
-
-	.u-keyboard-grids-btn {
-		text-decoration: none;
-		width: 62rpx;
-		flex: 0 0 64rpx;
-		height: 80rpx;
-		/* #ifndef APP-NVUE */
-		display: inline-flex;		
-		/* #endif */
-		font-size: 36rpx;
-		text-align: center;
-		line-height: 80rpx;
-		background-color: #fff;
-		margin: 8rpx 5rpx;
-		border-radius: 8rpx;
-		box-shadow: 0 2rpx 0rpx #888992;
-		font-weight: 500;
-		justify-content: center;
-	}
-
-	.u-carinput-hover {
-		background-color: rgb(185, 188, 195) !important;
-	}
-
-	.u-keyboard-back {
-		position: absolute;
-		width: 96rpx;
-		right: 22rpx;
-		bottom: 32rpx;
-		height: 80rpx;
-		background-color: rgb(185, 188, 195);
-		@include vue-flex;
-		align-items: center;
-		border-radius: 8rpx;
-		justify-content: center;
-		box-shadow: 0 2rpx 0rpx #888992;
-	}
-
-	.u-keyboard-change {
-		font-size: 24rpx;
-		box-shadow: 0 2rpx 0rpx #888992;
-		position: absolute;
-		width: 96rpx;
-		left: 22rpx;
-		line-height: 1;
-		bottom: 32rpx;
-		height: 80rpx;
-		background-color: #ffffff;
-		@include vue-flex;
-		align-items: center;
-		border-radius: 8rpx;
-		justify-content: center;
-	}
-
-	.u-keyboard-change .inactive.zh {
-		transform: scale(0.85) translateY(-10rpx);
-	}
-
-	.u-keyboard-change .inactive.en {
-		transform: scale(0.85) translateY(10rpx);
-	}
-
-	.u-keyboard-change .active {
-		color: rgb(237, 112, 64);
-		font-size: 30rpx;
-	}
-
-	.u-keyboard-change .zh {
-		transform: translateY(-10rpx);
-	}
-
-	.u-keyboard-change .en {
-		transform: translateY(10rpx);
-	}
-</style>

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

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

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

@@ -1,70 +0,0 @@
-<template>
-	<view class="u-cell-box">
-		<view class="u-cell-title" v-if="title" :style="[titleStyle]">
-			{{title}}
-		</view>
-		<view class="u-cell-item-box" :class="{'u-border-bottom u-border-top': border}">
-			<slot />
-		</view>
-	</view>
-</template>
-
-<script>
-	/**
-	 * cellGroup 单元格父组件Group
-	 * @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。搭配u-cell-item
-	 * @tutorial https://www.uviewui.com/components/cell.html
-	 * @property {String} title 分组标题
-	 * @property {Boolean} border 是否显示外边框(默认true)
-	 * @property {Object} title-style 分组标题的的样式,对象形式,如{'font-size': '24rpx'} 或 {'fontSize': '24rpx'}
-	 * @example <u-cell-group title="设置喜好">
-	 */
-	export default {
-		name: "u-cell-group",
-		props: {
-			// 分组标题
-			title: {
-				type: String,
-				default: ''
-			},
-			// 是否显示分组list上下边框
-			border: {
-				type: Boolean,
-				default: true
-			},
-			// 分组标题的样式,对象形式,注意驼峰属性写法
-			// 类似 {'font-size': '24rpx'} 和 {'fontSize': '24rpx'}
-			titleStyle: {
-				type: Object,
-				default () {
-					return {};
-				}
-			}
-		},
-		data() {
-			return {
-				index: 0,
-			}
-		},
-	}
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-	
-	.u-cell-box {
-		width: 100%;
-	}
-
-	.u-cell-title {
-		padding: 30rpx 32rpx 10rpx 32rpx;
-		font-size: 30rpx;
-		text-align: left;
-		color: $u-tips-color;
-	}
-
-	.u-cell-item-box {
-		background-color: #FFFFFF;
-		flex-direction: row;
-	}
-</style>

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

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

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

@@ -1,123 +0,0 @@
-<template>
-	<view class="u-checkbox-group u-clearfix">
-		<slot></slot>
-	</view>
-</template>
-
-<script>
-	import Emitter from '../../libs/util/emitter.js';
-	/**
-	 * checkboxGroup 开关选择器父组件Group
-	 * @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
-	 * @tutorial https://www.uviewui.com/components/checkbox.html
-	 * @property {String Number} max 最多能选中多少个checkbox(默认999)
-	 * @property {String Number} size 组件整体的大小,单位rpx(默认40)
-	 * @property {Boolean} disabled 是否禁用所有checkbox(默认false)
-	 * @property {String Number} icon-size 图标大小,单位rpx(默认20)
-	 * @property {Boolean} label-disabled 是否禁止点击文本操作checkbox(默认false)
-	 * @property {String} width 宽度,需带单位
-	 * @property {String} width 宽度,需带单位
-	 * @property {String} shape 外观形状,shape-方形,circle-圆形(默认circle)
-	 * @property {Boolean} wrap 是否每个checkbox都换行(默认false)
-	 * @property {String} active-color 选中时的颜色,应用到所有子Checkbox组件(默认#2979ff)
-	 * @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
-	 * @example <u-checkbox-group></u-checkbox-group>
-	 */
-	export default {
-		name: 'u-checkbox-group',
-		mixins: [Emitter],
-		props: {
-			// 最多能选中多少个checkbox
-			max: {
-				type: [Number, String],
-				default: 999
-			},
-			// 所有选中项的 name
-			// value: {
-			// 	default: Array,
-			// 	default() {
-			// 		return []
-			// 	}
-			// },
-			// 是否禁用所有复选框
-			disabled: {
-				type: Boolean,
-				default: false
-			},
-			// 在表单内提交时的标识符
-			name: {
-				type: [Boolean, String],
-				default: ''
-			},
-			// 是否禁止点击提示语选中复选框
-			labelDisabled: {
-				type: Boolean,
-				default: false
-			},
-			// 形状,square为方形,circle为原型
-			shape: {
-				type: String,
-				default: 'square'
-			},
-			// 选中状态下的颜色
-			activeColor: {
-				type: String,
-				default: '#2979ff'
-			},
-			// 组件的整体大小
-			size: {
-				type: [String, Number],
-				default: 34
-			},
-			// 每个checkbox占u-checkbox-group的宽度
-			width: {
-				type: String,
-				default: 'auto'
-			},
-			// 是否每个checkbox都换行
-			wrap: { 
-				type: Boolean,
-				default: false
-			},
-			// 图标的大小,单位rpx
-			iconSize: {
-				type: [String, Number],
-				default: 20
-			},
-		},
-		data() {
-			return {
-			}
-		},
-		created() {
-			// 如果将children定义在data中,在微信小程序会造成循环引用而报错
-			this.children = [];
-		},
-		methods: {
-			emitEvent() {
-				let values = [];
-				this.children.map(val => {
-					if(val.value) values.push(val.name);
-				})
-				this.$emit('change', values);
-				// 发出事件,用于在表单组件中嵌入checkbox的情况,进行验证
-				// 由于头条小程序执行迟钝,故需要用几十毫秒的延时
-				setTimeout(() => {
-					// 将当前的值发送到 u-form-item 进行校验
-					this.dispatch('u-form-item', 'on-form-change', values);
-				}, 60)
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-
-	.u-checkbox-group {
-		/* #ifndef MP || APP-NVUE */
-		display: inline-flex;
-		flex-wrap: wrap;
-		/* #endif */
-	}
-</style>

+ 0 - 284
components/uview-ui/components/u-checkbox/u-checkbox.vue

@@ -1,284 +0,0 @@
-<template>
-	<view class="u-checkbox" :style="[checkboxStyle]">
-		<view class="u-checkbox__icon-wrap" @tap="toggle" :class="[iconClass]" :style="[iconStyle]">
-			<u-icon class="u-checkbox__icon-wrap__icon" name="checkbox-mark" :size="checkboxIconSize" :color="iconColor"/>
-		</view>
-		<view class="u-checkbox__label" @tap="onClickLabel" :style="{
-			fontSize: $u.addUnit(labelSize)
-		}">
-			<slot />
-		</view>
-	</view>
-</template>
-
-<script>
-	/**
-	 * checkbox 复选框
-	 * @description 该组件需要搭配checkboxGroup组件使用,以便用户进行操作时,获得当前复选框组的选中情况。
-	 * @tutorial https://www.uviewui.com/components/checkbox.html
-	 * @property {String Number} icon-size 图标大小,单位rpx(默认20)
-	 * @property {String Number} label-size label字体大小,单位rpx(默认28)
-	 * @property {String Number} name checkbox组件的标示符
-	 * @property {String} shape 形状,见官网说明(默认circle)
-	 * @property {Boolean} disabled 是否禁用
-	 * @property {Boolean} label-disabled 是否禁止点击文本操作checkbox
-	 * @property {String} active-color 选中时的颜色,如设置CheckboxGroup的active-color将失效
-	 * @event {Function} change 某个checkbox状态发生变化时触发,回调为一个对象
-	 * @example <u-checkbox v-model="checked" :disabled="false">天涯</u-checkbox>
-	 */
-	export default {
-		name: "u-checkbox",
-		props: {
-			// checkbox的名称
-			name: {
-				type: [String, Number],
-				default: ''
-			},
-			// 形状,square为方形,circle为原型
-			shape: {
-				type: String,
-				default: ''
-			},
-			// 是否为选中状态
-			value: {
-				type: Boolean,
-				default: false
-			},
-			// 是否禁用
-			disabled: {
-				type: [String, Boolean],
-				default: ''
-			},
-			// 是否禁止点击提示语选中复选框
-			labelDisabled: {
-				type: [String, Boolean],
-				default: ''
-			},
-			// 选中状态下的颜色,如设置此值,将会覆盖checkboxGroup的activeColor值
-			activeColor: {
-				type: String,
-				default: ''
-			},
-			// 图标的大小,单位rpx
-			iconSize: {
-				type: [String, Number],
-				default: ''
-			},
-			// label的字体大小,rpx单位
-			labelSize: {
-				type: [String, Number],
-				default: ''
-			},
-			// 组件的整体大小
-			size: {
-				type: [String, Number],
-				default: ''
-			},
-		},
-		data() {
-			return {
-				parentDisabled: false,
-				newParams: {},
-			};
-		},
-		created() {
-			// 支付宝小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环应用
-			this.parent = this.$u.$parent.call(this, 'u-checkbox-group');
-			// 如果存在u-checkbox-group,将本组件的this塞进父组件的children中
-			this.parent && this.parent.children.push(this);
-		},
-		computed: {
-			// 是否禁用,如果父组件u-checkbox-group禁用的话,将会忽略子组件的配置
-			isDisabled() {
-				return this.disabled !== '' ? this.disabled : this.parent ? this.parent.disabled : false;
-			},
-			// 是否禁用label点击
-			isLabelDisabled() {
-				return this.labelDisabled !== '' ? this.labelDisabled : this.parent ? this.parent.labelDisabled : false;
-			},
-			// 组件尺寸,对应size的值,默认值为34rpx
-			checkboxSize() {
-				return this.size ? this.size : (this.parent ? this.parent.size : 34);
-			},
-			// 组件的勾选图标的尺寸,默认20
-			checkboxIconSize() {
-				return this.iconSize ? this.iconSize : (this.parent ? this.parent.iconSize : 20);
-			},
-			// 组件选中激活时的颜色
-			elActiveColor() {
-				return this.activeColor ? this.activeColor : (this.parent ? this.parent.activeColor : 'primary');
-			},
-			// 组件的形状
-			elShape() {
-				return this.shape ? this.shape : (this.parent ? this.parent.shape : 'square');
-			},
-			iconStyle() {
-				let style = {};
-				// 既要判断是否手动禁用,还要判断用户v-model绑定的值,如果绑定为false,那么也无法选中
-				if (this.elActiveColor && this.value && !this.isDisabled) {
-					style.borderColor = this.elActiveColor; 
-					style.backgroundColor = this.elActiveColor;
-				}
-				style.width = this.$u.addUnit(this.checkboxSize);
-				style.height = this.$u.addUnit(this.checkboxSize);
-				return style;
-			},
-			// checkbox内部的勾选图标,如果选中状态,为白色,否则为透明色即可
-			iconColor() {
-				return this.value ? '#ffffff' : 'transparent';
-			},
-			iconClass() {
-				let classes = [];
-				classes.push('u-checkbox__icon-wrap--' + this.elShape);
-				if (this.value == true) classes.push('u-checkbox__icon-wrap--checked');
-				if (this.isDisabled) classes.push('u-checkbox__icon-wrap--disabled');
-				if (this.value && this.isDisabled) classes.push('u-checkbox__icon-wrap--disabled--checked');
-				// 支付宝小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
-				return classes.join(' ');
-			},
-			checkboxStyle() {
-				let style = {};
-				if(this.parent && this.parent.width) {
-					style.width = this.parent.width;
-					// #ifdef MP
-					// 各家小程序因为它们特殊的编译结构,使用float布局
-					style.float = 'left';
-					// #endif
-					// #ifndef MP
-					// H5和APP使用flex布局
-					style.flex = `0 0 ${this.parent.width}`;
-					// #endif
-				}
-				if(this.parent && this.parent.wrap) {
-					style.width = '100%';
-					// #ifndef MP
-					// H5和APP使用flex布局,将宽度设置100%,即可自动换行
-					style.flex = '0 0 100%';
-					// #endif
-				}
-				return style;
-			}
-		},
-		methods: {
-			onClickLabel() {
-				if (!this.isLabelDisabled && !this.isDisabled) {
-					this.setValue();
-				}
-			},
-			toggle() {
-				if (!this.isDisabled) {
-					this.setValue();
-				}
-			},
-			emitEvent() {
-				this.$emit('change', {
-					value: !this.value,
-					name: this.name
-				})
-				// 执行父组件u-checkbox-group的事件方法
-				// 等待下一个周期再执行,因为this.$emit('input')作用于父组件,再反馈到子组件内部,需要时间
-				setTimeout(() => {
-					if(this.parent && this.parent.emitEvent) this.parent.emitEvent();
-				}, 80);
-			},
-			// 设置input的值,这里通过input事件,设置通过v-model绑定的组件的值
-			setValue() {
-				// 判断是否超过了可选的最大数量
-				let checkedNum = 0;
-				if(this.parent && this.parent.children) {
-					// 只要父组件的某一个子元素的value为true,就加1(已有的选中数量)
-					this.parent.children.map(val => {
-						if (val.value) checkedNum++;
-					})
-				}
-				// 如果原来为选中状态,那么可以取消
-				if (this.value == true) {
-					this.emitEvent();
-					this.$emit('input', !this.value);
-				} else {
-					// 如果超出最多可选项,提示
-					if(this.parent && checkedNum >= this.parent.max) {
-						return this.$u.toast(`最多可选${this.parent.max}项`);
-					}
-					// 如果原来为未选中状态,需要选中的数量少于父组件中设置的max值,才可以选中
-					this.emitEvent();
-					this.$emit('input', !this.value);
-				}
-			}
-		}
-	};
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-
-	.u-checkbox {
-		/* #ifndef APP-NVUE */
-		display: inline-flex;
-		/* #endif */
-		align-items: center;
-		overflow: hidden;
-		user-select: none;
-		line-height: 1.8;
-		
-		&__icon-wrap {
-			color: $u-content-color;
-			flex: none;
-			display: -webkit-flex;
-			@include vue-flex;
-			align-items: center;
-			justify-content: center;
-			box-sizing: border-box;
-			width: 42rpx;
-			height: 42rpx;
-			color: transparent;
-			text-align: center;
-			transition-property: color, border-color, background-color;
-			font-size: 20px;
-			border: 1px solid #c8c9cc;
-			transition-duration: 0.2s;
-			
-			/* #ifdef MP-TOUTIAO */
-			// 头条小程序兼容性问题,需要设置行高为0,否则图标偏下
-			&__icon {
-				line-height: 0;
-			}
-			/* #endif */
-			
-			&--circle {
-				border-radius: 100%;
-			}
-			
-			&--square {
-				border-radius: 6rpx;
-			}
-			
-			&--checked {
-				color: #fff;
-				background-color: $u-type-primary;
-				border-color: $u-type-primary;
-			}
-			
-			&--disabled {
-				background-color: #ebedf0;
-				border-color: #c8c9cc;
-			}
-			
-			&--disabled--checked {
-				color: #c8c9cc !important;
-			}
-		}
-	
-		&__label {
-			word-wrap: break-word;
-			margin-left: 10rpx;
-			margin-right: 24rpx;
-			color: $u-content-color;
-			font-size: 30rpx;
-			
-			&--disabled {
-				color: #c8c9cc;
-			}
-		}
-	}
-</style>

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

@@ -1,220 +0,0 @@
-<template>
-	<view
-		class="u-circle-progress"
-		:style="{
-			width: widthPx + 'px',
-			height: widthPx + 'px',
-			backgroundColor: bgColor
-		}"
-	>
-		<!-- 支付宝小程序不支持canvas-id属性,必须用id属性 -->
-		<canvas
-			class="u-canvas-bg"
-			:canvas-id="elBgId"
-			:id="elBgId"
-			:style="{
-				width: widthPx + 'px',
-				height: widthPx + 'px'
-			}"
-		></canvas>
-		<canvas
-			class="u-canvas"
-			:canvas-id="elId"
-			:id="elId"
-			:style="{
-				width: widthPx + 'px',
-				height: widthPx + 'px'
-			}"
-		></canvas>
-		<slot></slot>
-	</view>
-</template>
-
-<script>
-/**
- * circleProgress 环形进度条
- * @description 展示操作或任务的当前进度,比如上传文件,是一个圆形的进度条。注意:此组件的percent值只能动态增加,不能动态减少。
- * @tutorial https://www.uviewui.com/components/circleProgress.html
- * @property {String Number} percent 圆环进度百分比值,为数值类型,0-100
- * @property {String} inactive-color 圆环的底色,默认为灰色(该值无法动态变更)(默认#ececec)
- * @property {String} active-color 圆环激活部分的颜色(该值无法动态变更)(默认#19be6b)
- * @property {String Number} width 整个圆环组件的宽度,高度默认等于宽度值,单位rpx(默认200)
- * @property {String Number} border-width 圆环的边框宽度,单位rpx(默认14)
- * @property {String Number} duration 整个圆环执行一圈的时间,单位ms(默认呢1500)
- * @property {String} type 如设置,active-color值将会失效
- * @property {String} bg-color 整个组件背景颜色,默认为白色
- * @example <u-circle-progress active-color="#2979ff" :percent="80"></u-circle-progress>
- */
-export default {
-	name: 'u-circle-progress',
-	props: {
-		// 圆环进度百分比值
-		percent: {
-			type: Number,
-			default: 0,
-			// 限制值在0到100之间
-			validator: val => {
-				return val >= 0 && val <= 100;
-			}
-		},
-		// 底部圆环的颜色(灰色的圆环)
-		inactiveColor: {
-			type: String,
-			default: '#ececec'
-		},
-		// 圆环激活部分的颜色
-		activeColor: {
-			type: String,
-			default: '#19be6b'
-		},
-		// 圆环线条的宽度,单位rpx
-		borderWidth: {
-			type: [Number, String],
-			default: 14
-		},
-		// 整个圆形的宽度,单位rpx
-		width: {
-			type: [Number, String],
-			default: 200
-		},
-		// 整个圆环执行一圈的时间,单位ms
-		duration: {
-			type: [Number, String],
-			default: 1500
-		},
-		// 主题类型
-		type: {
-			type: String,
-			default: ''
-		},
-		// 整个圆环进度区域的背景色
-		bgColor: {
-			type: String,
-			default: '#ffffff'
-		}
-	},
-	data() {
-		return {
-			// #ifdef MP-WEIXIN
-			elBgId: 'uCircleProgressBgId', // 微信小程序中不能使用this.$u.guid()形式动态生成id值,否则会报错
-			elId: 'uCircleProgressElId',
-			// #endif
-			// #ifndef MP-WEIXIN
-			elBgId: this.$u.guid(), // 非微信端的时候,需用动态的id,否则一个页面多个圆形进度条组件数据会混乱
-			elId: this.$u.guid(),
-			// #endif
-			widthPx: uni.upx2px(this.width), // 转成px后的整个组件的背景宽度
-			borderWidthPx: uni.upx2px(this.borderWidth), // 转成px后的圆环的宽度
-			startAngle: -Math.PI / 2, // canvas画圆的起始角度,默认为3点钟方向,定位到12点钟方向
-			progressContext: null, // 活动圆的canvas上下文
-			newPercent: 0, // 当动态修改进度值的时候,保存进度值的变化前后值,用于比较用
-			oldPercent: 0 // 当动态修改进度值的时候,保存进度值的变化前后值,用于比较用
-		};
-	},
-	watch: {
-		percent(nVal, oVal = 0) {
-			if (nVal > 100) nVal = 100;
-			if (nVal < 0) oVal = 0;
-			// 此值其实等于this.percent,命名一个新
-			this.newPercent = nVal;
-			this.oldPercent = oVal;
-			setTimeout(() => {
-				// 无论是百分比值增加还是减少,需要操作还是原来的旧的百分比值
-				// 将此值减少或者新增到新的百分比值
-				this.drawCircleByProgress(oVal);
-			}, 50);
-		}
-	},
-	created() {
-		// 赋值,用于加载后第一个画圆使用
-		this.newPercent = this.percent;
-		this.oldPercent = 0;
-	},
-	computed: {
-		// 有type主题时,优先起作用
-		circleColor() {
-			if (['success', 'error', 'info', 'primary', 'warning'].indexOf(this.type) >= 0) return this.$u.color[this.type];
-			else return this.activeColor;
-		}
-	},
-	mounted() {
-		// 在h5端,必须要做一点延时才起作用,this.$nextTick()无效(HX2.4.7)
-		setTimeout(() => {
-			this.drawProgressBg();
-			this.drawCircleByProgress(this.oldPercent);
-		}, 50);
-	},
-	methods: {
-		drawProgressBg() {
-			let ctx = uni.createCanvasContext(this.elBgId, this);
-			ctx.setLineWidth(this.borderWidthPx); // 设置圆环宽度
-			ctx.setStrokeStyle(this.inactiveColor); // 线条颜色
-			ctx.beginPath(); // 开始描绘路径
-			// 设置一个原点(110,110),半径为100的圆的路径到当前路径
-			let radius = this.widthPx / 2;
-			ctx.arc(radius, radius, radius - this.borderWidthPx, 0, 2 * Math.PI, false);
-			ctx.stroke(); // 对路径进行描绘
-			ctx.draw();
-		},
-		drawCircleByProgress(progress) {
-			// 第一次操作进度环时将上下文保存到了this.data中,直接使用即可
-			let ctx = this.progressContext;
-			if (!ctx) {
-				ctx = uni.createCanvasContext(this.elId, this);
-				this.progressContext = ctx;
-			}
-			// 表示进度的两端为圆形
-			ctx.setLineCap('round');
-			// 设置线条的宽度和颜色
-			ctx.setLineWidth(this.borderWidthPx);
-			ctx.setStrokeStyle(this.circleColor);
-			// 将总过渡时间除以100,得出每修改百分之一进度所需的时间
-			let time = Math.floor(this.duration / 100);
-			// 结束角的计算依据为:将2π分为100份,乘以当前的进度值,得出终止点的弧度值,加起始角,为整个圆从默认的
-			// 3点钟方向开始画图,转为更好理解的12点钟方向开始作图,这需要起始角和终止角同时加上this.startAngle值
-			let endAngle = ((2 * Math.PI) / 100) * progress + this.startAngle;
-			ctx.beginPath();
-			// 半径为整个canvas宽度的一半
-			let radius = this.widthPx / 2;
-			ctx.arc(radius, radius, radius - this.borderWidthPx, this.startAngle, endAngle, false);
-			ctx.stroke();
-			ctx.draw();
-			// 如果变更后新值大于旧值,意味着增大了百分比
-			if (this.newPercent > this.oldPercent) {
-				// 每次递增百分之一
-				progress++;
-				// 如果新增后的值,大于需要设置的值百分比值,停止继续增加
-				if (progress > this.newPercent) return;
-			} else {
-				// 同理于上面
-				progress--;
-				if (progress < this.newPercent) return;
-			}
-			setTimeout(() => {
-				// 定时器,每次操作间隔为time值,为了让进度条有动画效果
-				this.drawCircleByProgress(progress);
-			}, time);
-		}
-	}
-};
-</script>
-
-<style lang="scss" scoped>
-@import "../../libs/css/style.components.scss";
-.u-circle-progress {
-	position: relative;
-	/* #ifndef APP-NVUE */
-	display: inline-flex;		
-	/* #endif */
-	align-items: center;
-	justify-content: center;
-}
-
-.u-canvas-bg {
-	position: absolute;
-}
-
-.u-canvas {
-	position: absolute;
-}
-</style>

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

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

+ 0 - 156
components/uview-ui/components/u-col/u-col.vue

@@ -1,156 +0,0 @@
-<template>
-	<view class="u-col" :class="[
-		'u-col-' + span
-	]" :style="{
-		padding: `0 ${Number(gutter)/2 + 'rpx'}`,
-		marginLeft: 100 / 12 * offset + '%',
-		flex: `0 0 ${100 / 12 * span}%`,
-		alignItems: uAlignItem,
-		justifyContent: uJustify,
-		textAlign: textAlign
-	}"
-	 @tap="click">
-		<slot></slot>
-	</view>
-</template>
-
-<script>
-	/**
-	 * col 布局单元格
-	 * @description 通过基础的 12 分栏,迅速简便地创建布局(搭配<u-row>使用)
-	 * @tutorial https://www.uviewui.com/components/layout.html
-	 * @property {String Number} span 栅格占据的列数,总12等分(默认0)
-	 * @property {String} text-align 文字水平对齐方式(默认left)
-	 * @property {String Number} offset 分栏左边偏移,计算方式与span相同(默认0)
-	 * @example <u-col span="3"><view class="demo-layout bg-purple"></view></u-col>
-	 */
-	export default {
-		name: "u-col",
-		props: {
-			// 占父容器宽度的多少等分,总分为12份
-			span: {
-				type: [Number, String],
-				default: 12
-			},
-			// 指定栅格左侧的间隔数(总12栏)
-			offset: {
-				type: [Number, String],
-				default: 0
-			},
-			// 水平排列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`)
-			justify: {
-				type: String,
-				default: 'start'
-			},
-			// 垂直对齐方式,可选值为top、center、bottom
-			align: {
-				type: String,
-				default: 'center'
-			},
-			// 文字对齐方式
-			textAlign: {
-				type: String,
-				default: 'left'
-			},
-			// 是否阻止事件传播
-			stop: {
-				type: Boolean,
-				default: true
-			}
-		},
-		data() {
-			return {
-				gutter: 20, // 给col添加间距,左右边距各占一半,从父组件u-row获取
-			}
-		},
-		created() {
-			this.parent = false;
-		},
-		mounted() {
-			// 获取父组件实例,并赋值给对应的参数
-			this.parent = this.$u.$parent.call(this, 'u-row');
-			if (this.parent) {
-				this.gutter = this.parent.gutter;
-			}
-		},
-		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;
-			}
-		},
-		methods: {
-			click(e) {
-				this.$emit('click');
-			}
-		}
-	}
-</script>
-
-<style lang="scss">
-	@import "../../libs/css/style.components.scss";
-
-	.u-col {
-		/* #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO */
-		float: left;
-		/* #endif */
-	}
-
-	.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);
-	}
-</style>

+ 0 - 204
components/uview-ui/components/u-collapse-item/u-collapse-item.vue

@@ -1,204 +0,0 @@
-<template>
-	<view class="u-collapse-item" :style="[itemStyle]">
-		<view :hover-stay-time="200" class="u-collapse-head" @tap.stop="headClick" :hover-class="hoverClass" :style="[headStyle]">
-			<block v-if="!$slots['title-all']">
-				<view v-if="!$slots['title']" class="u-collapse-title u-line-1" :style="[{ textAlign: align ? align : 'left' },
-					isShow && activeStyle && !arrow ? activeStyle : '']">
-					{{ title }}
-				</view>
-				<slot v-else name="title" />
-				<view class="u-icon-wrap">
-					<u-icon v-if="arrow" :color="arrowColor" :class="{ 'u-arrow-down-icon-active': isShow }"
-					 class="u-arrow-down-icon" name="arrow-down"></u-icon>
-				</view>
-			</block>
-			<slot v-else name="title-all" />
-		</view>
-		<view class="u-collapse-body" :style="[{
-				height: isShow ? height + 'px' : '0'
-			}]">
-			<view class="u-collapse-content" :id="elId" :style="[bodyStyle]">
-				<slot></slot>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	/**
-	 * collapseItem 手风琴Item
-	 * @description 通过折叠面板收纳内容区域(搭配u-collapse使用)
-	 * @tutorial https://www.uviewui.com/components/collapse.html
-	 * @property {String} title 面板标题
-	 * @property {String Number} index 主要用于事件的回调,标识那个Item被点击
-	 * @property {Boolean} disabled 面板是否可以打开或收起(默认false)
-	 * @property {Boolean} open 设置某个面板的初始状态是否打开(默认false)
-	 * @property {String Number} name 唯一标识符,如不设置,默认用当前collapse-item的索引值
-	 * @property {String} align 标题的对齐方式(默认left)
-	 * @property {Object} active-style 不显示箭头时,可以添加当前选择的collapse-item活动样式,对象形式
-	 * @event {Function} change 某个item被打开或者收起时触发
-	 * @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item>
-	 */
-	export default {
-		name: "u-collapse-item",
-		props: {
-			// 标题
-			title: {
-				type: String,
-				default: ''
-			},
-			// 标题的对齐方式
-			align: {
-				type: String,
-				default: 'left'
-			},
-			// 是否可以点击收起
-			disabled: {
-				type: Boolean,
-				default: false
-			},
-			// collapse显示与否
-			open: {
-				type: Boolean,
-				default: false
-			},
-			// 唯一标识符
-			name: {
-				type: [Number, String],
-				default: ''
-			},
-			//活动样式
-			activeStyle: {
-				type: Object,
-				default () {
-					return {}
-				}
-			},
-			// 标识当前为第几个
-			index: {
-				type: [String, Number],
-				default: ''
-			}
-		},
-		data() {
-			return {
-				isShow: false,
-				elId: this.$u.guid(),
-				height: 0, // body内容的高度
-				headStyle: {}, // 头部样式,对象形式
-				bodyStyle: {}, // 主体部分样式
-				itemStyle: {}, // 每个item的整体样式
-				arrowColor: '', // 箭头的颜色
-				hoverClass: '', // 头部按下时的效果样式类
-				arrow: true, // 是否显示右侧箭头
-				
-			};
-		},
-		watch: {
-			open(val) {
-				this.isShow = val;
-			}
-		},
-		created() {
-			this.parent = false;
-			// 获取u-collapse的信息,放在u-collapse是为了方便,不用每个u-collapse-item写一遍
-			this.isShow = this.open;
-		},
-		methods: {
-			// 异步获取内容,或者动态修改了内容时,需要重新初始化
-			init() {
-				this.parent = this.$u.$parent.call(this, 'u-collapse');
-				if(this.parent) {
-					this.nameSync = this.name ? this.name : this.parent.childrens.length;
-					this.parent.childrens.push(this);
-					this.headStyle = this.parent.headStyle;
-					this.bodyStyle = this.parent.bodyStyle;
-					this.arrowColor = this.parent.arrowColor;
-					this.hoverClass = this.parent.hoverClass;
-					this.arrow = this.parent.arrow;
-					this.itemStyle = this.parent.itemStyle;
-				}
-				this.$nextTick(() => {
-					this.queryRect();
-				});
-			},
-			// 点击collapsehead头部
-			headClick() {
-				if (this.disabled) return;
-				if (this.parent && this.parent.accordion == true) {
-					this.parent.childrens.map(val => {
-						// 自身不设置为false,因为后面有this.isShow = !this.isShow;处理了
-						if (this != val) {
-							val.isShow = false;
-						}
-					});
-				}
-
-				this.isShow = !this.isShow;
-				// 触发本组件的事件
-				this.$emit('change', {
-					index: this.index,
-					show: this.isShow
-				})
-				// 只有在打开时才发出事件
-				if (this.isShow) this.parent && this.parent.onChange();
-				this.$forceUpdate();
-			},
-			// 查询内容高度
-			queryRect() {
-				// $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://www.uviewui.com/js/getRect.html
-				// 组件内部一般用this.$uGetRect,对外的为this.$u.getRect,二者功能一致,名称不同
-				this.$uGetRect('#' + this.elId).then(res => {
-					this.height = res.height;
-				})
-			}
-		},
-		mounted() {
-			this.init();
-		}
-	};
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-	
-	.u-collapse-head {
-		position: relative;
-		@include vue-flex;
-		justify-content: space-between;
-		align-items: center;
-		color: $u-main-color;
-		font-size: 30rpx;
-		line-height: 1;
-		padding: 24rpx 0;
-		text-align: left;
-	}
-
-	.u-collapse-title {
-		flex: 1;
-		overflow: hidden;
-	}
-
-	.u-arrow-down-icon {
-		transition: all 0.3s;
-		margin-right: 20rpx;
-		margin-left: 14rpx;
-	}
-
-	.u-arrow-down-icon-active {
-		transform: rotate(180deg);
-		transform-origin: center center;
-	}
-
-	.u-collapse-body {
-		overflow: hidden;
-		transition: all 0.3s;
-	}
-
-	.u-collapse-content {
-		overflow: hidden;
-		font-size: 28rpx;
-		color: $u-tips-color;
-		text-align: left;
-	}
-</style>

+ 0 - 99
components/uview-ui/components/u-collapse/u-collapse.vue

@@ -1,99 +0,0 @@
-<template>
-	<view class="u-collapse">
-		<slot />
-	</view>
-</template>
-
-<script>
-	/**
-	 * collapse 手风琴
-	 * @description 通过折叠面板收纳内容区域
-	 * @tutorial https://www.uviewui.com/components/collapse.html
-	 * @property {Boolean} accordion 是否手风琴模式(默认true)
-	 * @property {Boolean} arrow 是否显示标题右侧的箭头(默认true)
-	 * @property {String} arrow-color 标题右侧箭头的颜色(默认#909399)
-	 * @property {Object} head-style 标题自定义样式,对象形式
-	 * @property {Object} body-style 主体自定义样式,对象形式
-	 * @property {String} hover-class 样式类名,按下时有效(默认u-hover-class)
-	 * @event {Function} change 当前激活面板展开时触发(如果是手风琴模式,参数activeNames类型为String,否则为Array)
-	 * @example <u-collapse></u-collapse>
-	 */
-	export default {
-		name:"u-collapse",
-		props: {
-			// 是否手风琴模式
-			accordion: {
-				type: Boolean,
-				default: true
-			},
-			// 头部的样式
-			headStyle: {
-				type: Object,
-				default () {
-					return {}
-				}
-			},
-			// 主体的样式
-			bodyStyle: {
-				type: Object,
-				default () {
-					return {}
-				}
-			},
-			// 每一个item的样式
-			itemStyle: {
-				type: Object,
-				default () {
-					return {}
-				}
-			},
-			// 是否显示右侧的箭头
-			arrow: {
-				type: Boolean,
-				default: true
-			},
-			// 箭头的颜色
-			arrowColor: {
-				type: String,
-				default: '#909399'
-			},
-			// 标题部分按压时的样式类,"none"为无效果
-			hoverClass: {
-				type: String,
-				default: 'u-hover-class'
-			}
-		},
-		created() {
-			this.childrens = []
-		},
-		data() {
-			return {
-
-			}
-		},
-		methods: {
-			// 重新初始化一次内部的所有子元素的高度计算,用于异步获取数据渲染的情况
-			init() {
-				this.childrens.forEach((vm, index) => {
-					vm.init();
-				})
-			},
-			// collapse item被点击,由collapse item调用父组件方法
-			onChange() {
-				let activeItem = [];
-				this.childrens.forEach((vm, index) => {
-					if (vm.isShow) {
-						activeItem.push(vm.nameSync);
-					}
-				})
-				// 如果是手风琴模式,只有一个匹配结果,也即activeItem长度为1,将其转为字符串
-				if (this.accordion) activeItem = activeItem.join('');
-				this.$emit('change', activeItem);
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-</style>

+ 0 - 237
components/uview-ui/components/u-column-notice/u-column-notice.vue

@@ -1,237 +0,0 @@
-<template>
-	<view
-		class="u-notice-bar"
-		:style="{
-			background: computeBgColor,
-			padding: padding
-		}"
-		:class="[
-			type ? `u-type-${type}-light-bg` : ''
-		]"
-	>
-		<view class="u-icon-wrap">
-			<u-icon class="u-left-icon" v-if="volumeIcon" name="volume-fill" :size="volumeSize" :color="computeColor"></u-icon>
-		</view>
-		<swiper :disable-touch="disableTouch" @change="change" :autoplay="autoplay && playState == 'play'" :vertical="vertical" circular :interval="duration" class="u-swiper">
-			<swiper-item v-for="(item, index) in list" :key="index" class="u-swiper-item">
-				<view
-					class="u-news-item u-line-1"
-					:style="[textStyle]"
-					@tap="click(index)"
-					:class="['u-type-' + type]"
-				>
-					{{ item }}
-				</view>
-			</swiper-item>
-		</swiper>
-		<view class="u-icon-wrap">
-			<u-icon @click="getMore" class="u-right-icon" v-if="moreIcon" name="arrow-right" :size="26" :color="computeColor"></u-icon>
-			<u-icon @click="close" class="u-right-icon" v-if="closeIcon" name="close" :size="24" :color="computeColor"></u-icon>
-		</view>
-	</view>
-</template>
-
-<script>
-export default {
-	props: {
-		// 显示的内容,数组
-		list: {
-			type: Array,
-			default() {
-				return [];
-			}
-		},
-		// 显示的主题,success|error|primary|info|warning
-		type: {
-			type: String,
-			default: 'warning'
-		},
-		// 是否显示左侧的音量图标
-		volumeIcon: {
-			type: Boolean,
-			default: true
-		},
-		// 是否显示右侧的右箭头图标
-		moreIcon: {
-			type: Boolean,
-			default: false
-		},
-		// 是否显示右侧的关闭图标
-		closeIcon: {
-			type: Boolean,
-			default: false
-		},
-		// 是否自动播放
-		autoplay: {
-			type: Boolean,
-			default: true
-		},
-		// 文字颜色,各图标也会使用文字颜色
-		color: {
-			type: String,
-			default: ''
-		},
-		// 背景颜色
-		bgColor: {
-			type: String,
-			default: ''
-		},
-		// 滚动方向,row-水平滚动,column-垂直滚动
-		direction: {
-			type: String,
-			default: 'row'
-		},
-		// 是否显示
-		show: {
-			type: Boolean,
-			default: true
-		},
-		// 字体大小,单位rpx
-		fontSize: {
-			type: [Number, String],
-			default: 26
-		},
-		// 滚动一个周期的时间长,单位ms
-		duration: {
-			type: [Number, String],
-			default: 2000
-		},
-		// 音量喇叭的大小
-		volumeSize: {
-			type: [Number, String],
-			default: 34
-		},
-		// 水平滚动时的滚动速度,即每秒滚动多少rpx,这有利于控制文字无论多少时,都能有一个恒定的速度
-		speed: {
-			type: Number,
-			default: 160
-		},
-		// 水平滚动时,是否采用衔接形式滚动
-		isCircular: {
-			type: Boolean,
-			default: true
-		},
-		// 滚动方向,horizontal-水平滚动,vertical-垂直滚动
-		mode: {
-			type: String,
-			default: 'horizontal'
-		},
-		// 播放状态,play-播放,paused-暂停
-		playState: {
-			type: String,
-			default: 'play'
-		},
-		// 是否禁止用手滑动切换
-		// 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序
-		disableTouch: {
-			type: Boolean,
-			default: true
-		},
-		// 通知的边距
-		padding: {
-			type: [Number, String],
-			default: '18rpx 24rpx'
-		}
-	},
-	computed: {
-		// 计算字体颜色,如果没有自定义的,就用uview主题颜色
-		computeColor() {
-			if (this.color) return this.color;
-			// 如果是无主题,就默认使用content-color
-			else if(this.type == 'none') return '#606266';
-			else return this.type;
-		},
-		// 文字内容的样式
-		textStyle() {
-			let style = {};
-			if (this.color) style.color = this.color;
-			else if(this.type == 'none') style.color = '#606266';
-			style.fontSize = this.fontSize + 'rpx';
-			return style;
-		},
-		// 垂直或者水平滚动
-		vertical() {
-			if(this.mode == 'horizontal') return false;
-			else return true;
-		},
-		// 计算背景颜色
-		computeBgColor() {
-			if (this.bgColor) return this.bgColor;
-			else if(this.type == 'none') return 'transparent';
-		}
-	},
-	data() {
-		return {
-			// animation: false
-		};
-	},
-	methods: {
-		// 点击通告栏
-		click(index) {
-			this.$emit('click', index);
-		},
-		// 点击关闭按钮
-		close() {
-			this.$emit('close');
-		},
-		// 点击更多箭头按钮
-		getMore() {
-			this.$emit('getMore');
-		},
-		change(e) {
-			let index = e.detail.current;
-			if(index == this.list.length - 1) {
-				this.$emit('end');
-			}
-		}
-	}
-};
-</script>
-
-<style lang="scss" scoped>
-@import "../../libs/css/style.components.scss";
-
-.u-notice-bar {
-	width: 100%;
-	@include vue-flex;
-	align-items: center;
-	justify-content: center;
-	flex-wrap: nowrap;
-	padding: 18rpx 24rpx;
-	overflow: hidden;
-}
-
-.u-swiper {
-	font-size: 26rpx;
-	height: 32rpx;
-	@include vue-flex;
-	align-items: center;
-	flex: 1;
-	margin-left: 12rpx;
-}
-
-.u-swiper-item {
-	@include vue-flex;
-	align-items: center;
-	overflow: hidden;
-}
-
-.u-news-item {
-	overflow: hidden;
-}
-
-.u-right-icon {
-	margin-left: 12rpx;
-	/* #ifndef APP-NVUE */
-	display: inline-flex;		
-	/* #endif */
-	align-items: center;
-}
-
-.u-left-icon {
-	/* #ifndef APP-NVUE */
-	display: inline-flex;		
-	/* #endif */
-	align-items: center;
-}
-</style>

+ 0 - 318
components/uview-ui/components/u-count-down/u-count-down.vue

@@ -1,318 +0,0 @@
-<template>
-	<view class="u-countdown">
-		<view class="u-countdown-item" :style="[itemStyle]" v-if="showDays && (hideZeroDay || (!hideZeroDay && d != '00'))">
-			<view class="u-countdown-time" :style="[letterStyle]">
-				{{ d }}
-			</view>
-		</view>
-		<view
-			class="u-countdown-colon"
-			:style="{fontSize: separatorSize + 'rpx', color: separatorColor, paddingBottom: separator == 'colon' ? '4rpx' : 0}"
-			v-if="showDays && (hideZeroDay || (!hideZeroDay && d != '00'))"
-		>
-			{{ separator == 'colon' ? ':' : '天' }}
-		</view>
-		<view class="u-countdown-item" :style="[itemStyle]" v-if="showHours">
-			<view class="u-countdown-time" :style="{ fontSize: fontSize + 'rpx', color: color}">
-				{{ h }}
-			</view>
-		</view>
-		<view
-			class="u-countdown-colon"
-			:style="{fontSize: separatorSize + 'rpx', color: separatorColor, paddingBottom: separator == 'colon' ? '4rpx' : 0}"
-			v-if="showHours"
-		>
-			{{ separator == 'colon' ? ':' : '时' }}
-		</view>
-		<view class="u-countdown-item" :style="[itemStyle]" v-if="showMinutes">
-			<view class="u-countdown-time" :style="{ fontSize: fontSize + 'rpx', color: color}">
-				{{ i }}
-			</view>
-		</view>
-		<view
-			class="u-countdown-colon"
-			:style="{fontSize: separatorSize + 'rpx', color: separatorColor, paddingBottom: separator == 'colon' ? '4rpx' : 0}"
-			v-if="showMinutes"
-		>
-			{{ separator == 'colon' ? ':' : '分' }}
-		</view>
-		<view class="u-countdown-item" :style="[itemStyle]" v-if="showSeconds">
-			<view class="u-countdown-time" :style="{ fontSize: fontSize + 'rpx', color: color}">
-				{{ s }}
-			</view>
-		</view>
-		<view
-			class="u-countdown-colon"
-			:style="{fontSize: separatorSize + 'rpx', color: separatorColor, paddingBottom: separator == 'colon' ? '4rpx' : 0}"
-			v-if="showSeconds && separator == 'zh'"
-		>
-			秒
-		</view>
-	</view>
-</template>
-
-<script>
-/**
- * countDown 倒计时
- * @description 该组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。
- * @tutorial https://www.uviewui.com/components/countDown.html
- * @property {String Number} timestamp 倒计时,单位为秒
- * @property {Boolean} autoplay 是否自动开始倒计时,如果为false,需手动调用开始方法。见官网说明(默认true)
- * @property {String} separator 分隔符,colon为英文冒号,zh为中文(默认colon)
- * @property {String Number} separator-size 分隔符的字体大小,单位rpx(默认30)
- * @property {String} separator-color 分隔符的颜色(默认#303133)
- * @property {String Number} font-size 倒计时字体大小,单位rpx(默认30)
- * @property {Boolean} show-border 是否显示倒计时数字的边框(默认false)
- * @property {Boolean} hide-zero-day 当"天"的部分为0时,隐藏该字段 (默认true)
- * @property {String} border-color 数字边框的颜色(默认#303133)
- * @property {String} bg-color 倒计时数字的背景颜色(默认#ffffff)
- * @property {String} color 倒计时数字的颜色(默认#303133)
- * @property {String} height 数字高度值(宽度等同此值),设置边框时看情况是否需要设置此值,单位rpx(默认auto)
- * @property {Boolean} show-days 是否显示倒计时的"天"部分(默认true)
- * @property {Boolean} show-hours 是否显示倒计时的"时"部分(默认true)
- * @property {Boolean} show-minutes 是否显示倒计时的"分"部分(默认true)
- * @property {Boolean} show-seconds 是否显示倒计时的"秒"部分(默认true)
- * @event {Function} end 倒计时结束
- * @event {Function} change 每秒触发一次,回调为当前剩余的倒计秒数
- * @example <u-count-down ref="uCountDown" :timestamp="86400" :autoplay="false"></u-count-down>
- */
-export default {
-	name: 'u-count-down',
-	props: {
-		// 倒计时的时间,秒为单位
-		timestamp: {
-			type: [Number, String],
-			default: 0
-		},
-		// 是否自动开始倒计时
-		autoplay: {
-			type: Boolean,
-			default: true
-		},
-		// 用英文冒号(colon)或者中文(zh)当做分隔符,false的时候为中文,如:"11:22"或"11时22秒"
-		separator: {
-			type: String,
-			default: 'colon'
-		},
-		// 分隔符的大小,单位rpx
-		separatorSize: {
-			type: [Number, String],
-			default: 30
-		},
-		// 分隔符颜色
-		separatorColor: {
-			type: String,
-			default: "#303133"
-		},
-		// 字体颜色
-		color: {
-			type: String,
-			default: '#303133'
-		},
-		// 字体大小,单位rpx
-		fontSize: {
-			type: [Number, String],
-			default: 30
-		},
-		// 背景颜色
-		bgColor: {
-			type: String,
-			default: '#fff'
-		},
-		// 数字框高度,单位rpx
-		height: {
-			type: [Number, String],
-			default: 'auto'
-		},
-		// 是否显示数字框
-		showBorder: {
-			type: Boolean,
-			default: false
-		},
-		// 边框颜色
-		borderColor: {
-			type: String,
-			default: '#303133'
-		},
-		// 是否显示秒
-		showSeconds: {
-			type: Boolean,
-			default: true
-		},
-		// 是否显示分钟
-		showMinutes: {
-			type: Boolean,
-			default: true
-		},
-		// 是否显示小时
-		showHours: {
-			type: Boolean,
-			default: true
-		},
-		// 是否显示“天”
-		showDays: {
-			type: Boolean,
-			default: true
-		},
-		// 当"天"的部分为0时,不显示
-		hideZeroDay: {
-			type: Boolean,
-			default: false
-		}
-	},
-	watch: {
-		// 监听时间戳的变化
-		timestamp(newVal, oldVal) {
-			// 如果倒计时间发生变化,清除定时器,重新开始倒计时
-			this.clearTimer();
-			this.start();
-		}
-	},
-	data() {
-		return {
-			d: '00', // 天的默认值
-			h: '00', // 小时的默认值
-			i: '00', // 分钟的默认值
-			s: '00', // 秒的默认值
-			timer: null ,// 定时器
-			seconds: 0, // 记录不停倒计过程中变化的秒数
-		};
-	},
-	computed: {
-		// 倒计时item的样式,item为分别的时分秒部分的数字
-		itemStyle() {
-			let style = {};
-			if(this.height) {
-				style.height = this.height + 'rpx';
-				style.width = this.height + 'rpx';
-			}
-			if(this.showBorder) {
-				style.borderStyle = 'solid';
-				style.borderColor = this.borderColor;
-				style.borderWidth = '1px';
-			}
-			if(this.bgColor) {
-				style.backgroundColor = this.bgColor;
-			}
-			return style;
-		},
-		// 倒计时数字的样式
-		letterStyle() {
-			let style = {};
-			if(this.fontSize) style.fontSize = this.fontSize +  'rpx';
-			if(this.color) style.color = this.color;
-			return style;
-		}
-	},
-	mounted() {
-		// 如果自动倒计时
-		this.autoplay && this.timestamp && this.start();
-	},
-	methods: {
-		// 倒计时
-		start() {
-			// 避免可能出现的倒计时重叠情况
-			this.clearTimer();
-			if (this.timestamp <= 0) return;
-			this.seconds = Number(this.timestamp);
-			this.formatTime(this.seconds);
-			this.timer = setInterval(() => {
-				this.seconds--;
-				// 发出change事件
-				this.$emit('change', this.seconds);
-				if (this.seconds < 0) {
-					return this.end();
-				}
-				this.formatTime(this.seconds);
-			}, 1000);
-		},
-		// 格式化时间
-		formatTime(seconds) {
-			// 小于等于0的话,结束倒计时
-			seconds <= 0 && this.end();
-			let [day, hour, minute, second] = [0, 0, 0, 0];
-			day = Math.floor(seconds / (60 * 60 * 24));
-			// 判断是否显示“天”参数,如果不显示,将天部分的值,加入到小时中
-			// hour为给后面计算秒和分等用的(基于显示天的前提下计算)
-			hour = Math.floor(seconds / (60 * 60)) - day * 24;
-			// showHour为需要显示的小时
-			let showHour = null;
-			if(this.showDays) {
-				showHour = hour;
-			} else {
-				// 如果不显示天数,将“天”部分的时间折算到小时中去
-				showHour = Math.floor(seconds / (60 * 60));
-			}
-			minute = Math.floor(seconds / 60) - hour * 60 - day * 24 * 60;
-			second = Math.floor(seconds) - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60;
-			// 如果小于10,在前面补上一个"0"
-			showHour = showHour < 10 ? '0' + showHour : showHour;
-			minute = minute < 10 ? '0' + minute : minute;
-			second = second < 10 ? '0' + second : second;
-			day = day < 10 ? '0' + day : day;
-			this.d = day;
-			this.h = showHour;
-			this.i = minute;
-			this.s = second;
-		},
-		// 停止倒计时
-		end() {
-			this.clearTimer();
-			this.$emit('end', {});
-		},
-		// 清除定时器
-		clearTimer() {
-			if(this.timer) {
-				// 清除定时器
-				clearInterval(this.timer);
-				this.timer = null;
-			}
-		}
-	},
-	beforeDestroy() {
-		clearInterval(this.timer);
-		this.timer = null;
-	}
-};
-</script>
-
-<style scoped lang="scss">
-	@import "../../libs/css/style.components.scss";
-
-	.u-countdown {
-		/* #ifndef APP-NVUE */
-		display: inline-flex;		
-		/* #endif */
-		align-items: center;
-	}
-
-	.u-countdown-item {
-		@include vue-flex;
-		align-items: center;
-		justify-content: center;
-		padding: 2rpx;
-		border-radius: 6rpx;
-		white-space: nowrap;
-		transform: translateZ(0);
-	}
-
-	.u-countdown-time {
-		margin: 0;
-		padding: 0;
-		line-height: 1;
-	}
-
-	.u-countdown-colon {
-		@include vue-flex;
-		justify-content: center;
-		padding: 0 5rpx;
-		line-height: 1;
-		align-items: center;
-		padding-bottom: 4rpx;
-	}
-
-	.u-countdown-scale {
-		transform: scale(0.9);
-		transform-origin: center center;
-	}
-</style>

+ 0 - 241
components/uview-ui/components/u-count-to/u-count-to.vue

@@ -1,241 +0,0 @@
-<template>
-	<view
-		class="u-count-num"
-		:style="{
-			fontSize: fontSize + 'rpx',
-			fontWeight: bold ? 'bold' : 'normal',
-			color: color
-		}"
-	>
-		{{ displayValue }}
-	</view>
-</template>
-
-<script>
-/**
- * countTo 数字滚动
- * @description 该组件一般用于需要滚动数字到某一个值的场景,目标要求是一个递增的值。
- * @tutorial https://www.uviewui.com/components/countTo.html
- * @property {String Number} start-val 开始值
- * @property {String Number} end-val 结束值
- * @property {String Number} duration 滚动过程所需的时间,单位ms(默认2000)
- * @property {Boolean} autoplay 是否自动开始滚动(默认true)
- * @property {String Number} decimals 要显示的小数位数,见官网说明(默认0)
- * @property {Boolean} use-easing 滚动结束时,是否缓动结尾,见官网说明(默认true)
- * @property {String} separator 千位分隔符,见官网说明
- * @property {String} color 字体颜色(默认#303133)
- * @property {String Number} font-size 字体大小,单位rpx(默认50)
- * @property {Boolean} bold 字体是否加粗(默认false)
- * @event {Function} end 数值滚动到目标值时触发
- * @example <u-count-to ref="uCountTo" :end-val="endVal" :autoplay="autoplay"></u-count-to>
- */
-export default {
-	name: 'u-count-to',
-	props: {
-		// 开始的数值,默认从0增长到某一个数
-		startVal: {
-			type: [Number, String],
-			default: 0
-		},
-		// 要滚动的目标数值,必须
-		endVal: {
-			type: [Number, String],
-			default: 0,
-			required: true
-		},
-		// 滚动到目标数值的动画持续时间,单位为毫秒(ms)
-		duration: {
-			type: [Number, String],
-			default: 2000
-		},
-		// 设置数值后是否自动开始滚动
-		autoplay: {
-			type: Boolean,
-			default: true
-		},
-		// 要显示的小数位数
-		decimals: {
-			type: [Number, String],
-			default: 0
-		},
-		// 是否在即将到达目标数值的时候,使用缓慢滚动的效果
-		useEasing: {
-			type: Boolean,
-			default: true
-		},
-		// 十进制分割
-		decimal: {
-			type: [Number, String],
-			default: '.'
-		},
-		// 字体颜色
-		color: {
-			type: String,
-			default: '#303133'
-		},
-		// 字体大小
-		fontSize: {
-			type: [Number, String],
-			default: 50
-		},
-		// 是否加粗字体
-		bold: {
-			type: Boolean,
-			default: false
-		},
-		// 千位分隔符,类似金额的分割(¥23,321.05中的",")
-		separator: {
-			type: String,
-			default: ''
-		}
-	},
-	data() {
-		return {
-			localStartVal: this.startVal,
-			displayValue: this.formatNumber(this.startVal),
-			printVal: null,
-			paused: false, // 是否暂停
-			localDuration: Number(this.duration),
-			startTime: null, // 开始的时间
-			timestamp: null, // 时间戳
-			remaining: null, // 停留的时间
-			rAF: null,
-			lastTime: 0 // 上一次的时间
-		};
-	},
-	computed: {
-		countDown() {
-			return this.startVal > this.endVal;
-		}
-	},
-	watch: {
-		startVal() {
-			this.autoplay && this.start();
-		},
-		endVal() {
-			this.autoplay && this.start();
-		}
-	},
-	mounted() {
-		this.autoplay && this.start();
-	},
-	methods: {
-		easingFn(t, b, c, d) {
-			return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;
-		},
-		requestAnimationFrame(callback) {
-			const currTime = new Date().getTime();
-			// 为了使setTimteout的尽可能的接近每秒60帧的效果
-			const timeToCall = Math.max(0, 16 - (currTime - this.lastTime));
-			const id = setTimeout(() => {
-				callback(currTime + timeToCall);
-			}, timeToCall);
-			this.lastTime = currTime + timeToCall;
-			return id;
-		},
-
-		cancelAnimationFrame(id) {
-			clearTimeout(id);
-		},
-		// 开始滚动数字
-		start() {
-			this.localStartVal = this.startVal;
-			this.startTime = null;
-			this.localDuration = this.duration;
-			this.paused = false;
-			this.rAF = this.requestAnimationFrame(this.count);
-		},
-		// 暂定状态,重新再开始滚动;或者滚动状态下,暂停
-		reStart() {
-			if (this.paused) {
-				this.resume();
-				this.paused = false;
-			} else {
-				this.stop();
-				this.paused = true;
-			}
-		},
-		// 暂停
-		stop() {
-			this.cancelAnimationFrame(this.rAF);
-		},
-		// 重新开始(暂停的情况下)
-		resume() {
-			this.startTime = null;
-			this.localDuration = this.remaining;
-			this.localStartVal = this.printVal;
-			this.requestAnimationFrame(this.count);
-		},
-		// 重置
-		reset() {
-			this.startTime = null;
-			this.cancelAnimationFrame(this.rAF);
-			this.displayValue = this.formatNumber(this.startVal);
-		},
-		count(timestamp) {
-			if (!this.startTime) this.startTime = timestamp;
-			this.timestamp = timestamp;
-			const progress = timestamp - this.startTime;
-			this.remaining = this.localDuration - progress;
-			if (this.useEasing) {
-				if (this.countDown) {
-					this.printVal = this.localStartVal - this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration);
-				} else {
-					this.printVal = this.easingFn(progress, this.localStartVal, this.endVal - this.localStartVal, this.localDuration);
-				}
-			} else {
-				if (this.countDown) {
-					this.printVal = this.localStartVal - (this.localStartVal - this.endVal) * (progress / this.localDuration);
-				} else {
-					this.printVal = this.localStartVal + (this.endVal - this.localStartVal) * (progress / this.localDuration);
-				}
-			}
-			if (this.countDown) {
-				this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal;
-			} else {
-				this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal;
-			}
-			this.displayValue = this.formatNumber(this.printVal);
-			if (progress < this.localDuration) {
-				this.rAF = this.requestAnimationFrame(this.count);
-			} else {
-				this.$emit('end');
-			}
-		},
-		// 判断是否数字
-		isNumber(val) {
-			return !isNaN(parseFloat(val));
-		},
-		formatNumber(num) {
-			// 将num转为Number类型,因为其值可能为字符串数值,调用toFixed会报错
-			num = Number(num);
-			num = num.toFixed(Number(this.decimals));
-			num += '';
-			const x = num.split('.');
-			let x1 = x[0];
-			const x2 = x.length > 1 ? this.decimal + x[1] : '';
-			const rgx = /(\d+)(\d{3})/;
-			if (this.separator && !this.isNumber(this.separator)) {
-				while (rgx.test(x1)) {
-					x1 = x1.replace(rgx, '$1' + this.separator + '$2');
-				}
-			}
-			return x1 + x2;
-		},
-		destroyed() {
-			this.cancelAnimationFrame(this.rAF);
-		}
-	}
-};
-</script>
-
-<style lang="scss" scoped>
-@import "../../libs/css/style.components.scss";
-
-.u-count-num {
-	/* #ifndef APP-NVUE */
-	display: inline-flex;		
-	/* #endif */
-	text-align: center;
-}
-</style>

+ 0 - 153
components/uview-ui/components/u-divider/u-divider.vue

@@ -1,153 +0,0 @@
-<template>
-	<view class="u-divider" :style="{
-		height: height == 'auto' ? 'auto' : height + 'rpx',
-		backgroundColor: bgColor,
-		marginBottom: marginBottom + 'rpx',
-		marginTop: marginTop + 'rpx'
-	}" @tap="click">
-		<view class="u-divider-line" :class="[type ? 'u-divider-line--bordercolor--' + type : '']" :style="[lineStyle]"></view>
-		<view v-if="useSlot" class="u-divider-text" :style="{
-			color: color,
-			fontSize: fontSize + 'rpx'
-		}"><slot /></view>
-		<view class="u-divider-line" :class="[type ? 'u-divider-line--bordercolor--' + type : '']" :style="[lineStyle]"></view>
-	</view>
-</template>
-
-<script>
-/**
- * divider 分割线
- * @description 区隔内容的分割线,一般用于页面底部"没有更多"的提示。
- * @tutorial https://www.uviewui.com/components/divider.html
- * @property {String Number} half-width 文字左或右边线条宽度,数值或百分比,数值时单位为rpx
- * @property {String} border-color 线条颜色,优先级高于type(默认#dcdfe6)
- * @property {String} color 文字颜色(默认#909399)
- * @property {String Number} fontSize 字体大小,单位rpx(默认26)
- * @property {String} bg-color 整个divider的背景颜色(默认呢#ffffff)
- * @property {String Number} height 整个divider的高度,单位rpx(默认40)
- * @property {String} type 将线条设置主题色(默认primary)
- * @property {Boolean} useSlot 是否使用slot传入内容,如果不传入,中间不会有空隙(默认true)
- * @property {String Number} margin-top 与前一个组件的距离,单位rpx(默认0)
- * @property {String Number} margin-bottom 与后一个组件的距离,单位rpx(0)
- * @event {Function} click divider组件被点击时触发
- * @example <u-divider color="#fa3534">长河落日圆</u-divider>
- */
-export default {
-	name: 'u-divider',
-	props: {
-		// 单一边divider横线的宽度(数值),单位rpx。或者百分比
-		halfWidth: {
-			type: [Number, String],
-			default: 150
-		},
-		// divider横线的颜色,如设置,
-		borderColor: {
-			type: String,
-			default: '#dcdfe6'
-		},
-		// 主题色,可以是primary|info|success|warning|error之一值
-		type: {
-			type: String,
-			default: 'primary'
-		},
-		// 文字颜色
-		color: {
-			type: String,
-			default: '#909399'
-		},
-		// 文字大小,单位rpx
-		fontSize: {
-			type: [Number, String],
-			default: 26
-		},
-		// 整个divider的背景颜色
-		bgColor: {
-			type: String,
-			default: '#ffffff'
-		},
-		// 整个divider的高度单位rpx
-		height: {
-			type: [Number, String],
-			default: 'auto'
-		},
-		// 上边距
-		marginTop: {
-			type: [String, Number],
-			default: 0
-		},
-		// 下边距
-		marginBottom: {
-			type: [String, Number],
-			default: 0
-		},
-		// 是否使用slot传入内容,如果不用slot传入内容,先的中间就不会有空隙
-		useSlot: {
-			type: Boolean,
-			default: true
-		}
-	},
-	computed: {
-		lineStyle() {
-			let style = {};
-			if(String(this.halfWidth).indexOf('%') != -1) style.width = this.halfWidth;
-			else style.width = this.halfWidth + 'rpx';
-			// borderColor优先级高于type值
-			if(this.borderColor) style.borderColor = this.borderColor;
-			return style;
-		}
-	},
-	methods: {
-		click() {
-			this.$emit('click');
-		}
-	}
-};
-</script>
-
-<style lang="scss" scoped>
-@import "../../libs/css/style.components.scss";
-.u-divider {
-	width: 100%;
-	position: relative;
-	text-align: center;
-	@include vue-flex;
-	justify-content: center;
-	align-items: center;
-	overflow: hidden;
-	flex-direction: row;
-}
-
-.u-divider-line {
-	border-bottom: 1px solid $u-border-color;
-	transform: scale(1, 0.5);
-	transform-origin: center;
-	
-	&--bordercolor--primary {
-		border-color: $u-type-primary;
-	}
-	
-	&--bordercolor--success {
-		border-color: $u-type-success;
-	}
-	
-	&--bordercolor--error {
-		border-color: $u-type-primary;
-	}
-	
-	&--bordercolor--info {
-		border-color: $u-type-info;
-	}
-	
-	&--bordercolor--warning {
-		border-color: $u-type-warning;
-	}
-}
-
-.u-divider-text {
-	white-space: nowrap;
-	padding: 0 16rpx;
-	/* #ifndef APP-NVUE */
-	display: inline-flex;		
-	/* #endif */
-}
-</style>

+ 0 - 132
components/uview-ui/components/u-dropdown-item/u-dropdown-item.vue

@@ -1,132 +0,0 @@
-<template>
-	<view class="u-dropdown-item" v-if="active" @touchmove.stop.prevent="() => {}" @tap.stop.prevent="() => {}">
-		<block v-if="!$slots.default && !$slots.$default">
-			<scroll-view scroll-y="true" :style="{
-				height: $u.addUnit(height)
-			}">
-				<view class="u-dropdown-item__options">
-					<u-cell-group>
-						<u-cell-item @click="cellClick(item.value)" :arrow="false" :title="item.label" v-for="(item, index) in options"
-						 :key="index" :title-style="{
-							color: value == item.value ? activeColor : inactiveColor
-						}">
-							<u-icon v-if="value == item.value" name="checkbox-mark" :color="activeColor" size="32"></u-icon>
-						</u-cell-item>
-					</u-cell-group>
-				</view>
-			</scroll-view>
-		</block>
-		<slot v-else />
-	</view>
-</template>
-
-<script>
-	/**
-	 * dropdown-item 下拉菜单
-	 * @description 该组件一般用于向下展开菜单,同时可切换多个选项卡的场景
-	 * @tutorial http://uviewui.com/components/dropdown.html
-	 * @property {String | Number} v-model 双向绑定选项卡选择值
-	 * @property {String} title 菜单项标题
-	 * @property {Array[Object]} options 选项数据,如果传入了默认slot,此参数无效
-	 * @property {Boolean} disabled 是否禁用此选项卡(默认false)
-	 * @property {String | Number} duration 选项卡展开和收起的过渡时间,单位ms(默认300)
-	 * @property {String | Number} height 弹窗下拉内容的高度(内容超出将会滚动)(默认auto)
-	 * @example <u-dropdown-item title="标题"></u-dropdown-item>
-	 */
-	export default {
-		name: 'u-dropdown-item',
-		props: {
-			// 当前选中项的value值
-			value: {
-				type: [Number, String, Array],
-				default: ''
-			},
-			// 菜单项标题
-			title: {
-				type: [String, Number],
-				default: ''
-			},
-			// 选项数据,如果传入了默认slot,此参数无效
-			options: {
-				type: Array,
-				default () {
-					return []
-				}
-			},
-			// 是否禁用此菜单项
-			disabled: {
-				type: Boolean,
-				default: false
-			},
-			// 下拉弹窗的高度
-			height: {
-				type: [Number, String],
-				default: 'auto'
-			},
-		},
-		data() {
-			return {
-				active: false, // 当前项是否处于展开状态
-				activeColor: '#2979ff', // 激活时左边文字和右边对勾图标的颜色
-				inactiveColor: '#606266', // 未激活时左边文字和右边对勾图标的颜色
-			}
-		},
-		computed: {
-			// 监听props是否发生了变化,有些值需要传递给父组件u-dropdown,无法双向绑定
-			propsChange() {
-				return `${this.title}-${this.disabled}`;
-			}
-		},
-		watch: {
-			propsChange(n) {
-				// 当值变化时,通知父组件重新初始化,让父组件执行每个子组件的init()方法
-				// 将所有子组件数据重新整理一遍
-				if (this.parent) this.parent.init();
-			}
-		},
-		created() {
-			// 父组件的实例
-			this.parent = false;
-		},
-		methods: {
-			init() {
-				// 获取父组件u-dropdown
-				let parent = this.$u.$parent.call(this, 'u-dropdown');
-				if (parent) {
-					this.parent = parent;
-					// 将子组件的激活颜色配置为父组件设置的激活和未激活时的颜色
-					this.activeColor = parent.activeColor;
-					this.inactiveColor = parent.inactiveColor;
-					// 将本组件的this,放入到父组件的children数组中,让父组件可以操作本(子)组件的方法和属性
-					// push进去前,显判断是否已经存在了本实例,因为在子组件内部数据变化时,会通过父组件重新初始化子组件
-					let exist = parent.children.find(val => {
-						return this === val;
-					})
-					if (!exist) parent.children.push(this);
-					if (parent.children.length == 1) this.active = true;
-					// 父组件无法监听children的变化,故将子组件的title,传入父组件的menuList数组中
-					parent.menuList.push({
-						title: this.title,
-						disabled: this.disabled
-					});
-				}
-			},
-			// cell被点击
-			cellClick(value) {
-				// 修改通过v-model绑定的值
-				this.$emit('input', value);
-				// 通知父组件(u-dropdown)收起菜单
-				this.parent.close();
-				// 发出事件,抛出当前勾选项的value
-				this.$emit('change', value);
-			}
-		},
-		mounted() {
-			this.init();
-		}
-	}
-</script>
-
-<style scoped lang="scss">
-	@import "../../libs/css/style.components.scss";
-</style>

+ 0 - 298
components/uview-ui/components/u-dropdown/u-dropdown.vue

@@ -1,298 +0,0 @@
-<template>
-	<view class="u-dropdown">
-		<view class="u-dropdown__menu" :style="{
-			height: $u.addUnit(height)
-		}" :class="{
-			'u-border-bottom': borderBottom
-		}">
-			<view class="u-dropdown__menu__item" v-for="(item, index) in menuList" :key="index" @tap.stop="menuClick(index)">
-				<view class="u-flex">
-					<text class="u-dropdown__menu__item__text" :style="{
-						color: item.disabled ? '#c0c4cc' : (index === current || highlightIndex == index) ? activeColor : inactiveColor,
-						fontSize: $u.addUnit(titleSize)
-					}">{{item.title}}</text>
-					<view class="u-dropdown__menu__item__arrow" :class="{
-						'u-dropdown__menu__item__arrow--rotate': index === current
-					}">
-						<u-icon :custom-style="{display: 'flex'}" :name="menuIcon" :size="$u.addUnit(menuIconSize)" :color="index === current || highlightIndex == index ? activeColor : '#c0c4cc'"></u-icon>
-					</view>
-				</view>
-			</view>
-		</view>
-		<view class="u-dropdown__content" :style="[contentStyle, {
-			transition: `opacity ${duration / 1000}s linear`,
-			top: $u.addUnit(height),
-			height: contentHeight + 'px'
-		}]"
-		 @tap="maskClick" @touchmove.stop.prevent>
-			<view @tap.stop.prevent class="u-dropdown__content__popup" :style="[popupStyle]">
-				<slot></slot>
-			</view>
-			<view class="u-dropdown__content__mask"></view>
-		</view>
-	</view>
-</template>
-
-<script>
-	/**
-	 * dropdown 下拉菜单
-	 * @description 该组件一般用于向下展开菜单,同时可切换多个选项卡的场景
-	 * @tutorial http://uviewui.com/components/dropdown.html
-	 * @property {String} active-color 标题和选项卡选中的颜色(默认#2979ff)
-	 * @property {String} inactive-color 标题和选项卡未选中的颜色(默认#606266)
-	 * @property {Boolean} close-on-click-mask 点击遮罩是否关闭菜单(默认true)
-	 * @property {Boolean} close-on-click-self 点击当前激活项标题是否关闭菜单(默认true)
-	 * @property {String | Number} duration 选项卡展开和收起的过渡时间,单位ms(默认300)
-	 * @property {String | Number} height 标题菜单的高度,单位任意(默认80)
-	 * @property {String | Number} border-radius 菜单展开内容下方的圆角值,单位任意(默认0)
-	 * @property {Boolean} border-bottom 标题菜单是否显示下边框(默认false)
-	 * @property {String | Number} title-size 标题的字体大小,单位任意,数值默认为rpx单位(默认28)
-	 * @event {Function} open 下拉菜单被打开时触发
-	 * @event {Function} close 下拉菜单被关闭时触发
-	 * @example <u-dropdown></u-dropdown>
-	 */
-	export default {
-		name: 'u-dropdown',
-		props: {
-			// 菜单标题和选项的激活态颜色
-			activeColor: {
-				type: String,
-				default: '#2979ff'
-			},
-			// 菜单标题和选项的未激活态颜色
-			inactiveColor: {
-				type: String,
-				default: '#606266'
-			},
-			// 点击遮罩是否关闭菜单
-			closeOnClickMask: {
-				type: Boolean,
-				default: true
-			},
-			// 点击当前激活项标题是否关闭菜单
-			closeOnClickSelf: {
-				type: Boolean,
-				default: true
-			},
-			// 过渡时间
-			duration: {
-				type: [Number, String],
-				default: 300
-			},
-			// 标题菜单的高度,单位任意,数值默认为rpx单位
-			height: {
-				type: [Number, String],
-				default: 80
-			},
-			// 是否显示下边框
-			borderBottom: {
-				type: Boolean,
-				default: false
-			},
-			// 标题的字体大小
-			titleSize: {
-				type: [Number, String],
-				default: 28
-			},
-			// 下拉出来的内容部分的圆角值
-			borderRadius: {
-				type: [Number, String],
-				default: 0
-			},
-			// 菜单右侧的icon图标
-			menuIcon: {
-				type: String,
-				default: 'arrow-down'
-			},
-			// 菜单右侧图标的大小
-			menuIconSize: {
-				type: [Number, String],
-				default: 26
-			}
-		},
-		data() {
-			return {
-				showDropdown: true, // 是否打开下来菜单,
-				menuList: [], // 显示的菜单
-				active: false, // 下拉菜单的状态
-				// 当前是第几个菜单处于激活状态,小程序中此处不能写成false或者"",否则后续将current赋值为0,
-				// 无能的TX没有使用===而是使用==判断,导致程序认为前后二者没有变化,从而不会触发视图更新
-				current: 99999,
-				// 外层内容的样式,初始时处于底层,且透明
-				contentStyle: {
-					zIndex: -1,
-					opacity: 0
-				},
-				// 让某个菜单保持高亮的状态
-				highlightIndex: 99999,
-				contentHeight: 0
-			}
-		},
-		computed: {
-			// 下拉出来部分的样式
-			popupStyle() {
-				let style = {};
-				// 进行Y轴位移,展开状态时,恢复原位。收齐状态时,往上位移100%,进行隐藏
-				style.transform = `translateY(${this.active ? 0 : '-100%'})`
-				style['transition-duration'] = this.duration / 1000 + 's';
-				style.borderRadius = `0 0 ${this.$u.addUnit(this.borderRadius)} ${this.$u.addUnit(this.borderRadius)}`;
-				return style;
-			}
-		},
-		created() {
-			// 引用所有子组件(u-dropdown-item)的this,不能在data中声明变量,否则在微信小程序会造成循环引用而报错
-			this.children = [];
-		},
-		mounted() {
-			this.getContentHeight();
-		},
-		methods: {
-			init() {
-				// 当某个子组件内容变化时,触发父组件的init,父组件再让每一个子组件重新初始化一遍
-				// 以保证数据的正确性
-				this.menuList = [];
-				this.children.map(child => {
-					child.init();
-				})
-			},
-			// 点击菜单
-			menuClick(index) {
-				// 判断是否被禁用
-				if (this.menuList[index].disabled) return;
-				// 如果点击时的索引和当前激活项索引相同,意味着点击了激活项,需要收起下拉菜单
-				if (index === this.current && this.closeOnClickSelf) {
-					this.close();
-					// 等动画结束后,再移除下拉菜单中的内容,否则直接移除,也就没有下拉菜单收起的效果了
-					setTimeout(() => {
-						this.children[index].active = false;
-					}, this.duration)
-					return;
-				}
-				this.open(index);
-			},
-			// 打开下拉菜单
-			open(index) {
-				// 重置高亮索引,否则会造成多个菜单同时高亮
-				// this.highlightIndex = 9999;
-				// 展开时,设置下拉内容的样式
-				this.contentStyle = {
-					zIndex: 11,
-				}
-				// 标记展开状态以及当前展开项的索引
-				this.active = true;
-				this.current = index;
-				// 历遍所有的子元素,将索引匹配的项标记为激活状态,因为子元素是通过v-if控制切换的
-				// 之所以不是因display: none,是因为nvue没有display这个属性
-				this.children.map((val, idx) => {
-					val.active = index == idx ? true : false;
-				})
-				this.$emit('open', this.current);
-			},
-			// 设置下拉菜单处于收起状态
-			close() {
-				this.$emit('close', this.current);
-				// 设置为收起状态,同时current归位,设置为空字符串
-				this.active = false;
-				this.current = 99999;
-				// 下拉内容的样式进行调整,不透明度设置为0
-				this.contentStyle = {
-					zIndex: -1,
-					opacity: 0
-				}
-			},
-			// 点击遮罩
-			maskClick() {
-				// 如果不允许点击遮罩,直接返回
-				if (!this.closeOnClickMask) return;
-				this.close();
-			},
-			// 外部手动设置某个菜单高亮
-			highlight(index = undefined) {
-				this.highlightIndex = index !== undefined ? index : 99999;
-			},
-			// 获取下拉菜单内容的高度
-			getContentHeight() {
-				// 这里的原理为,因为dropdown组件是相对定位的,它的下拉出来的内容,必须给定一个高度
-				// 才能让遮罩占满菜单一下,直到屏幕底部的高度
-				// this.$u.sys()为uView封装的获取设备信息的方法
-				let windowHeight = this.$u.sys().windowHeight;
-				this.$uGetRect('.u-dropdown__menu').then(res => {
-					// 这里获取的是dropdown的尺寸,在H5上,uniapp获取尺寸是有bug的(以前提出修复过,后来又出现了此bug,目前hx2.8.11版本)
-					// H5端bug表现为元素尺寸的top值为导航栏底部到到元素的上边沿的距离,但是元素的bottom值确是导航栏顶部到元素底部的距离
-					// 二者是互相矛盾的,本质原因是H5端导航栏非原生,uni的开发者大意造成
-					// 这里取菜单栏的botton值合理的,不能用res.top,否则页面会造成滚动
-					this.contentHeight = windowHeight - res.bottom;
-				})
-			}
-		}
-	}
-</script>
-
-<style scoped lang="scss">
-	@import "../../libs/css/style.components.scss";
-
-	.u-dropdown {
-		flex: 1;
-		width: 100%;
-		position: relative;
-
-		&__menu {
-			@include vue-flex;
-			position: relative;
-			z-index: 11;
-			height: 80rpx;
-
-			&__item {
-				flex: 1;
-				@include vue-flex;
-				justify-content: center;
-				align-items: center;
-
-				&__text {
-					font-size: 28rpx;
-					color: $u-content-color;
-				}
-
-				&__arrow {
-					margin-left: 6rpx;
-					transition: transform .3s;
-					align-items: center;
-					@include vue-flex;
-
-					&--rotate {
-						transform: rotate(180deg);
-					}
-				}
-			}
-		}
-
-		&__content {
-			position: absolute;
-			z-index: 8;
-			width: 100%;
-			left: 0px;
-			bottom: 0;
-			overflow: hidden;
-			
-
-			&__mask {
-				position: absolute;
-				z-index: 9;
-				background: rgba(0, 0, 0, .3);
-				width: 100%;
-				left: 0;
-				top: 0;
-				bottom: 0;
-			}
-
-			&__popup {
-				position: relative;
-				z-index: 10;
-				transition: all 0.3s;
-				transform: translate3D(0, -100%, 0);
-				overflow: hidden;
-			}
-		}
-
-	}
-</style>

+ 0 - 193
components/uview-ui/components/u-empty/u-empty.vue

@@ -1,193 +0,0 @@
-<template>
-	<view class="u-empty" v-if="show" :style="{
-		marginTop: marginTop + 'rpx'
-	}">
-		<u-icon
-			:name="src ? src : 'empty-' + mode"
-			:custom-style="iconStyle"
-			:label="text ? text : icons[mode]"
-			label-pos="bottom"
-			:label-color="color"
-			:label-size="fontSize"
-			:size="iconSize"
-			:color="iconColor"
-			margin-top="14"
-		></u-icon>
-		<view class="u-slot-wrap">
-			<slot name="bottom"></slot>
-		</view>
-	</view>
-</template>
-
-<script>
-	/**
-	 * empty 内容为空
-	 * @description 该组件用于需要加载内容,但是加载的第一页数据就为空,提示一个"没有内容"的场景, 我们精心挑选了十几个场景的图标,方便您使用。
-	 * @tutorial https://www.uviewui.com/components/empty.html
-	 * @property {String} color 文字颜色(默认#c0c4cc)
-	 * @property {String} text 文字提示(默认“无内容”)
-	 * @property {String} src 自定义图标路径,如定义,mode参数会失效
-	 * @property {String Number} font-size 提示文字的大小,单位rpx(默认28)
-	 * @property {String} mode 内置的图标,见官网说明(默认data)
-	 * @property {String Number} img-width 图标的宽度,单位rpx(默认240)
-	 * @property {String} img-height 图标的高度,单位rpx(默认auto)
-	 * @property {String Number} margin-top 组件距离上一个元素之间的距离(默认0)
-	 * @property {Boolean} show 是否显示组件(默认true)
-	 * @event {Function} click 点击组件时触发
-	 * @event {Function} close 点击关闭按钮时触发
-	 * @example <u-empty text="所谓伊人,在水一方" mode="list"></u-empty>
-	 */
-	export default {
-		name: "u-empty",
-		props: {
-			// 图标路径
-			src: {
-				type: String,
-				default: ''
-			},
-			// 提示文字
-			text: {
-				type: String,
-				default: ''
-			},
-			// 文字颜色
-			color: {
-				type: String,
-				default: '#c0c4cc'
-			},
-			// 图标的颜色
-			iconColor: {
-				type: String,
-				default: '#c0c4cc'
-			},
-			// 图标的大小
-			iconSize: {
-				type: [String, Number],
-				default: 120
-			},
-			// 文字大小,单位rpx
-			fontSize: {
-				type: [String, Number],
-				default: 26
-			},
-			// 选择预置的图标类型
-			mode: {
-				type: String,
-				default: 'data'
-			},
-			//  图标宽度,单位rpx
-			imgWidth: {
-				type: [String, Number],
-				default: 120
-			},
-			// 图标高度,单位rpx
-			imgHeight: {
-				type: [String, Number],
-				default: 'auto'
-			},
-			// 是否显示组件
-			show: {
-				type: Boolean,
-				default: true
-			},
-			// 组件距离上一个元素之间的距离
-			marginTop: {
-				type: [String, Number],
-				default: 0
-			},
-			iconStyle: {
-				type: Object,
-				default() {
-					return {}
-				}
-			}
-		},
-		data() {
-			return {
-				icons: {
-					car: '购物车为空',
-					page: '页面不存在',
-					search: '没有搜索结果',
-					address: '没有收货地址',
-					wifi: '没有WiFi',
-					order: '订单为空',
-					coupon: '没有优惠券',
-					favor: '暂无收藏',
-					permission: '无权限',
-					history: '无历史记录',
-					news: '无新闻列表',
-					message: '消息列表为空',
-					list: '列表为空',
-					data: '数据为空'
-				},
-				// icons: [{
-				// 	icon: 'car',
-				// 	text: '购物车为空'
-				// },{
-				// 	icon: 'page',
-				// 	text: '页面不存在'
-				// },{
-				// 	icon: 'search',
-				// 	text: '没有搜索结果'
-				// },{
-				// 	icon: 'address',
-				// 	text: '没有收货地址'
-				// },{
-				// 	icon: 'wifi',
-				// 	text: '没有WiFi'
-				// },{
-				// 	icon: 'order',
-				// 	text: '订单为空'
-				// },{
-				// 	icon: 'coupon',
-				// 	text: '没有优惠券'
-				// },{
-				// 	icon: 'favor',
-				// 	text: '暂无收藏'
-				// },{
-				// 	icon: 'permission',
-				// 	text: '无权限'
-				// },{
-				// 	icon: 'history',
-				// 	text: '无历史记录'
-				// },{
-				// 	icon: 'news',
-				// 	text: '无新闻列表'
-				// },{
-				// 	icon: 'message',
-				// 	text: '消息列表为空'
-				// },{
-				// 	icon: 'list',
-				// 	text: '列表为空'
-				// },{
-				// 	icon: 'data',
-				// 	text: '数据为空'
-				// }],
-
-			}
-		}
-	}
-</script>
-
-<style scoped lang="scss">
-	@import "../../libs/css/style.components.scss";
-
-	.u-empty {
-		@include vue-flex;
-		flex-direction: column;
-		justify-content: center;
-		align-items: center;
-		height: 100%;
-	}
-
-	.u-image {
-		margin-bottom: 20rpx;
-	}
-
-	.u-slot-wrap {
-		@include vue-flex;
-		justify-content: center;
-		align-items: center;
-		margin-top: 20rpx;
-	}
-</style>

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

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

+ 0 - 431
components/uview-ui/components/u-form-item/u-form-item.vue

@@ -1,431 +0,0 @@
-<template>
-	<view class="u-form-item" :class="{'u-border-bottom': elBorderBottom, 'u-form-item__border-bottom--error': validateState === 'error' && showError('border-bottom')}">
-		<view class="u-form-item__body" :style="{
-			flexDirection: elLabelPosition == 'left' ? 'row' : 'column'
-		}">
-			<!-- 微信小程序中,将一个参数设置空字符串,结果会变成字符串"true" -->
-			<view class="u-form-item--left" :style="{
-				width: uLabelWidth,
-				flex: `0 0 ${uLabelWidth}`,
-				marginBottom: elLabelPosition == 'left' ? 0 : '10rpx',
-			}">
-				<!-- 为了块对齐 -->
-				<view class="u-form-item--left__content" v-if="required || leftIcon || label">
-					<!-- nvue不支持伪元素before -->
-					<text v-if="required" class="u-form-item--left__content--required">*</text>
-					<view class="u-form-item--left__content__icon" v-if="leftIcon">
-						<u-icon :name="leftIcon" :custom-style="leftIconStyle"></u-icon>
-					</view>
-					<view class="u-form-item--left__content__label" :style="[elLabelStyle, {
-						'justify-content': elLabelAlign == 'left' ? 'flex-start' : elLabelAlign == 'center' ? 'center' : 'flex-end'
-					}]">
-						{{label}}
-					</view>
-				</view>
-			</view>
-			<view class="u-form-item--right u-flex">
-				<view class="u-form-item--right__content">
-					<view class="u-form-item--right__content__slot ">
-						<slot />
-					</view>
-					<view class="u-form-item--right__content__icon u-flex" v-if="$slots.right || rightIcon">
-						<u-icon :custom-style="rightIconStyle" v-if="rightIcon" :name="rightIcon"></u-icon>
-						<slot name="right" />
-					</view>
-				</view>
-			</view>
-		</view>
-		<view class="u-form-item__message" v-if="validateState === 'error' && showError('message')" :style="{
-			paddingLeft: elLabelPosition == 'left' ? $u.addUnit(elLabelWidth) : '0',
-		}">{{validateMessage}}</view>
-	</view>
-</template>
-
-<script>
-	import Emitter from '../../libs/util/emitter.js';
-	import schema from '../../libs/util/async-validator';
-	// 去除警告信息
-	schema.warning = function() {};
-
-	/**
-	 * form-item 表单item
-	 * @description 此组件一般用于表单场景,可以配置Input输入框,Select弹出框,进行表单验证等。
-	 * @tutorial http://uviewui.com/components/form.html
-	 * @property {String} label 左侧提示文字
-	 * @property {Object} prop 表单域model对象的属性名,在使用 validate、resetFields 方法的情况下,该属性是必填的
-	 * @property {Boolean} border-bottom 是否显示表单域的下划线边框
-	 * @property {String} label-position 表单域提示文字的位置,left-左侧,top-上方
-	 * @property {String Number} label-width 提示文字的宽度,单位rpx(默认90)
-	 * @property {Object} label-style lable的样式,对象形式
-	 * @property {String} label-align lable的对齐方式
-	 * @property {String} right-icon 右侧自定义字体图标(限uView内置图标)或图片地址
-	 * @property {String} left-icon 左侧自定义字体图标(限uView内置图标)或图片地址
-	 * @property {Object} left-icon-style 左侧图标的样式,对象形式
-	 * @property {Object} right-icon-style 右侧图标的样式,对象形式
-	 * @property {Boolean} required 是否显示左边的"*"号,这里仅起展示作用,如需校验必填,请通过rules配置必填规则(默认false)
-	 * @example <u-form-item label="姓名"><u-input v-model="form.name" /></u-form-item>
-	 */
-
-	export default {
-		name: 'u-form-item',
-		mixins: [Emitter],
-		inject: {
-			uForm: {
-				default () {
-					return null
-				}
-			}
-		},
-		props: {
-			// input的label提示语
-			label: {
-				type: String,
-				default: ''
-			},
-			// 绑定的值
-			prop: {
-				type: String,
-				default: ''
-			},
-			// 是否显示表单域的下划线边框
-			borderBottom: {
-				type: [String, Boolean],
-				default: ''
-			},
-			// label的位置,left-左边,top-上边
-			labelPosition: {
-				type: String,
-				default: ''
-			},
-			// label的宽度,单位rpx
-			labelWidth: {
-				type: [String, Number],
-				default: ''
-			},
-			// lable的样式,对象形式
-			labelStyle: {
-				type: Object,
-				default () {
-					return {}
-				}
-			},
-			// lable字体的对齐方式
-			labelAlign: {
-				type: String,
-				default: ''
-			},
-			// 右侧图标
-			rightIcon: {
-				type: String,
-				default: ''
-			},
-			// 左侧图标
-			leftIcon: {
-				type: String,
-				default: ''
-			},
-			// 左侧图标的样式
-			leftIconStyle: {
-				type: Object,
-				default () {
-					return {}
-				}
-			},
-			// 左侧图标的样式
-			rightIconStyle: {
-				type: Object,
-				default () {
-					return {}
-				}
-			},
-			// 是否显示左边的必填星号,只作显示用,具体校验必填的逻辑,请在rules中配置
-			required: {
-				type: Boolean,
-				default: false
-			}
-		},
-		data() {
-			return {
-				initialValue: '', // 存储的默认值
-				// isRequired: false, // 是否必填,由于人性化考虑,必填"*"号通过props的required配置,不再通过rules的规则自动生成
-				validateState: '', // 是否校验成功
-				validateMessage: '', // 校验失败的提示语
-				// 有错误时的提示方式,message-提示信息,border-如果input设置了边框,变成呈红色,
-				errorType: ['message'],
-				fieldValue: '', // 获取当前子组件input的输入的值
-				// 父组件的参数,在computed计算中,无法得知this.parent发生变化,故将父组件的参数值,放到data中
-				parentData: {
-					borderBottom: true,
-					labelWidth: 90,
-					labelPosition: 'left',
-					labelStyle: {},
-					labelAlign: 'left',
-				}
-			};
-		},
-		watch: {
-			validateState(val) {
-				this.broadcastInputError();
-			},
-			// 监听u-form组件的errorType的变化
-			"uForm.errorType"(val) {
-				this.errorType = val;
-				this.broadcastInputError();
-			},
-		},
-		computed: {
-			// 计算后的label宽度,由于需要多个判断,故放到computed中
-			uLabelWidth() {
-				// 如果用户设置label为空字符串(微信小程序空字符串最终会变成字符串的'true'),意味着要将label的位置宽度设置为auto
-				return this.elLabelPosition == 'left' ? (this.label === 'true' || this.label === '' ? 'auto' : this.$u.addUnit(this
-					.elLabelWidth)) : '100%';
-			},
-			showError() {
-				return type => {
-					// 如果errorType数组中含有none,或者toast提示类型
-					if (this.errorType.indexOf('none') >= 0) return false;
-					else if (this.errorType.indexOf(type) >= 0) return true;
-					else return false;
-				}
-			},
-			// label的宽度
-			elLabelWidth() {
-				// label默认宽度为90,优先使用本组件的值,如果没有(如果设置为0,也算是配置了值,依然起效),则用u-form的值
-				return (this.labelWidth != 0 || this.labelWidth != '') ? this.labelWidth : (this.parentData.labelWidth ? this.parentData
-					.labelWidth :
-					90);
-			},
-			// label的样式
-			elLabelStyle() {
-				return Object.keys(this.labelStyle).length ? this.labelStyle : (this.parentData.labelStyle ? this.parentData.labelStyle :
-					{});
-			},
-			// label的位置,左侧或者上方
-			elLabelPosition() {
-				return this.labelPosition ? this.labelPosition : (this.parentData.labelPosition ? this.parentData.labelPosition :
-					'left');
-			},
-			// label的对齐方式
-			elLabelAlign() {
-				return this.labelAlign ? this.labelAlign : (this.parentData.labelAlign ? this.parentData.labelAlign : 'left');
-			},
-			// label的下划线
-			elBorderBottom() {
-				// 子组件的borderBottom默认为空字符串,如果不等于空字符串,意味着子组件设置了值,优先使用子组件的值
-				return this.borderBottom !== '' ? this.borderBottom : this.parentData.borderBottom ? this.parentData.borderBottom :
-					true;
-			}
-		},
-		methods: {
-			broadcastInputError() {
-				// 子组件发出事件,第三个参数为true或者false,true代表有错误
-				this.broadcast('u-input', 'on-form-item-error', this.validateState === 'error' && this.showError('border'));
-			},
-			// 判断是否需要required校验
-			setRules() {
-				let that = this;
-				// 由于人性化考虑,必填"*"号通过props的required配置,不再通过rules的规则自动生成
-				// 从父组件u-form拿到当前u-form-item需要验证 的规则
-				// let rules = this.getRules();
-				// if (rules.length) {
-				// 	this.isRequired = rules.some(rule => {
-				// 		// 如果有必填项,就返回,没有的话,就是undefined
-				// 		return rule.required;
-				// 	});
-				// }
-
-				// blur事件
-				this.$on('on-form-blur', that.onFieldBlur);
-				// change事件
-				this.$on('on-form-change', that.onFieldChange);
-			},
-
-			// 从u-form的rules属性中,取出当前u-form-item的校验规则
-			getRules() {
-				// 父组件的所有规则
-				let rules = this.parent.rules;
-				rules = rules ? rules[this.prop] : [];
-				// 保证返回的是一个数组形式
-				return [].concat(rules || []);
-			},
-
-			// blur事件时进行表单校验
-			onFieldBlur() {
-				this.validation('blur');
-			},
-
-			// change事件进行表单校验
-			onFieldChange() {
-				this.validation('change');
-			},
-
-			// 过滤出符合要求的rule规则
-			getFilteredRule(triggerType = '') {
-				let rules = this.getRules();
-				// 整体验证表单时,triggerType为空字符串,此时返回所有规则进行验证
-				if (!triggerType) return rules;
-				// 历遍判断规则是否有对应的事件,比如blur,change触发等的事件
-				// 使用indexOf判断,是因为某些时候设置的验证规则的trigger属性可能为多个,比如['blur','change']
-				// 某些场景可能的判断规则,可能不存在trigger属性,故先判断是否存在此属性
-				return rules.filter(res => res.trigger && res.trigger.indexOf(triggerType) !== -1);
-			},
-
-			// 校验数据
-			validation(trigger, callback = () => {}) {
-				// 检验之间,先获取需要校验的值
-				this.fieldValue = this.parent.model[this.prop];
-				// blur和change是否有当前方式的校验规则
-				let rules = this.getFilteredRule(trigger);
-				// 判断是否有验证规则,如果没有规则,也调用回调方法,否则父组件u-form会因为
-				// 对count变量的统计错误而无法进入上一层的回调
-				if (!rules || rules.length === 0) {
-					return callback('');
-				}
-				// 设置当前的装填,标识为校验中
-				this.validateState = 'validating';
-				// 调用async-validator的方法
-				let validator = new schema({
-					[this.prop]: rules
-				});
-				validator.validate({
-					[this.prop]: this.fieldValue
-				}, {
-					firstFields: true
-				}, (errors, fields) => {
-					// 记录状态和报错信息
-					this.validateState = !errors ? 'success' : 'error';
-					this.validateMessage = errors ? errors[0].message : '';
-					// 调用回调方法
-					callback(this.validateMessage);
-				});
-			},
-
-			// 清空当前的u-form-item
-			resetField() {
-				this.parent.model[this.prop] = this.initialValue;
-				// 设置为`success`状态,只是为了清空错误标记
-				this.validateState = 'success';
-			}
-		},
-
-		// 组件创建完成时,将当前实例保存到u-form中
-		mounted() {
-			// 支付宝、头条小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环应用
-			this.parent = this.$u.$parent.call(this, 'u-form');
-			if (this.parent) {
-				// 历遍parentData中的属性,将parent中的同名属性赋值给parentData
-				Object.keys(this.parentData).map(key => {
-					this.parentData[key] = this.parent[key];
-				});
-				// 如果没有传入prop,或者uForm为空(如果u-form-input单独使用,就不会有uForm注入),就不进行校验
-				if (this.prop) {
-					// 将本实例添加到父组件中
-					this.parent.fields.push(this);
-					this.errorType = this.parent.errorType;
-					// 设置初始值
-					this.initialValue = this.fieldValue;
-					// 添加表单校验,这里必须要写在$nextTick中,因为u-form的rules是通过ref手动传入的
-					// 不在$nextTick中的话,可能会造成执行此处代码时,父组件还没通过ref把规则给u-form,导致规则为空
-					this.$nextTick(() => {
-						this.setRules();
-					})
-				}
-			}
-		},
-
-		// 组件销毁前,将实例从u-form的缓存中移除
-		beforeDestroy() {
-			// 如果当前没有prop的话表示当前不要进行删除(因为没有注入)
-			if (this.parent && this.prop) {
-				this.parent.fields.map((item, index) => {
-					if (item === this) this.parent.fields.splice(index, 1);
-				})
-			}
-		},
-	};
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-
-	.u-form-item {
-		@include vue-flex;
-		// align-items: flex-start;
-		padding: 20rpx 0;
-		font-size: 28rpx;
-		color: $u-main-color;
-		box-sizing: border-box;
-		line-height: $u-form-item-height;
-		flex-direction: column;
-
-		&__border-bottom--error:after {
-			border-color: $u-type-error;
-		}
-
-		&__body {
-			@include vue-flex;
-		}
-
-		&--left {
-			@include vue-flex;
-			align-items: center;
-
-			&__content {
-				position: relative;
-				@include vue-flex;
-				align-items: center;
-				padding-right: 10rpx;
-				flex: 1;
-
-				&__icon {
-					margin-right: 8rpx;
-				}
-
-				&--required {
-					position: absolute;
-					left: -16rpx;
-					vertical-align: middle;
-					color: $u-type-error;
-					padding-top: 6rpx;
-				}
-
-				&__label {
-					@include vue-flex;
-					align-items: center;
-					flex: 1;
-				}
-			}
-		}
-
-		&--right {
-			flex: 1;
-
-			&__content {
-				@include vue-flex;
-				align-items: center;
-				flex: 1;
-
-				&__slot {
-					flex: 1;
-					/* #ifndef MP */
-					@include vue-flex;
-					align-items: center;
-					/* #endif */
-				}
-
-				&__icon {
-					margin-left: 10rpx;
-					color: $u-light-color;
-					font-size: 30rpx;
-				}
-			}
-		}
-
-		&__message {
-			font-size: 24rpx;
-			line-height: 24rpx;
-			color: $u-type-error;
-			margin-top: 12rpx;
-		}
-	}
-</style>

+ 0 - 134
components/uview-ui/components/u-form/u-form.vue

@@ -1,134 +0,0 @@
-<template>
-	<view class="u-form"><slot /></view>
-</template>
-
-<script>
-	/**
-	 * form 表单
-	 * @description 此组件一般用于表单场景,可以配置Input输入框,Select弹出框,进行表单验证等。
-	 * @tutorial http://uviewui.com/components/form.html
-	 * @property {Object} model 表单数据对象
-	 * @property {Boolean} border-bottom 是否显示表单域的下划线边框
-	 * @property {String} label-position 表单域提示文字的位置,left-左侧,top-上方
-	 * @property {String Number} label-width 提示文字的宽度,单位rpx(默认90)
-	 * @property {Object} label-style lable的样式,对象形式
-	 * @property {String} label-align lable的对齐方式
-	 * @property {Object} rules 通过ref设置,见官网说明
-	 * @property {Array} error-type 错误的提示方式,数组形式,见上方说明(默认['message'])
-	 * @example <u-form :model="form" ref="uForm"></u-form>
-	 */
-
-export default {
-	name: 'u-form',
-	props: {
-		// 当前form的需要验证字段的集合
-		model: {
-			type: Object,
-			default() {
-				return {};
-			}
-		},
-		// 验证规则
-		// rules: {
-		// 	type: [Object, Function, Array],
-		// 	default() {
-		// 		return {};
-		// 	}
-		// },
-		// 有错误时的提示方式,message-提示信息,border-如果input设置了边框,变成呈红色,
-		// border-bottom-下边框呈现红色,none-无提示
-		errorType: {
-			type: Array,
-			default() {
-				return ['message', 'toast']
-			}
-		},
-		// 是否显示表单域的下划线边框
-		borderBottom: {
-			type: Boolean,
-			default: true
-		},
-		// label的位置,left-左边,top-上边
-		labelPosition: {
-			type: String,
-			default: 'left'
-		},
-		// label的宽度,单位rpx
-		labelWidth: {
-			type: [String, Number],
-			default: 90
-		},
-		// lable字体的对齐方式
-		labelAlign: {
-			type: String,
-			default: 'left'
-		},
-		// lable的样式,对象形式
-		labelStyle: {
-			type: Object,
-			default() {
-				return {}
-			}
-		},
-	},
-	provide() {
-		return {
-			uForm: this
-		};
-	},
-	data() {
-		return {
-			rules: {}
-		};
-	},
-	created() {
-		// 存储当前form下的所有u-form-item的实例
-		// 不能定义在data中,否则微信小程序会造成循环引用而报错
-		this.fields = [];
-	},
-	methods: {
-		setRules(rules) {
-			this.rules = rules;
-		},
-		// 清空所有u-form-item组件的内容,本质上是调用了u-form-item组件中的resetField()方法
-		resetFields() {
-			this.fields.map(field => {
-				field.resetField();
-			});
-		},
-		// 校验全部数据
-		validate(callback) {
-			return new Promise(resolve => {
-				// 对所有的u-form-item进行校验
-				let valid = true; // 默认通过
-				let count = 0; // 用于标记是否检查完毕
-				let errorArr = []; // 存放错误信息
-				this.fields.map(field => {
-					// 调用每一个u-form-item实例的validation的校验方法
-					field.validation('', error => {
-						// 如果任意一个u-form-item校验不通过,就意味着整个表单不通过
-						if (error) {
-							valid = false;
-							errorArr.push(error);
-						}
-						// 当历遍了所有的u-form-item时,调用promise的then方法
-						if (++count === this.fields.length) {
-							resolve(valid); // 进入promise的then方法
-							// 判断是否设置了toast的提示方式,只提示最前面的表单域的第一个错误信息
-							if(this.errorType.indexOf('none') === -1 && this.errorType.indexOf('toast') >= 0 && errorArr.length) {
-								this.$u.toast(errorArr[0]);
-							}
-							// 调用回调方法
-							if (typeof callback == 'function') callback(valid);
-						}
-					});
-				});
-			});
-		}
-	}
-};
-</script>
-
-<style scoped lang="scss">
-@import "../../libs/css/style.components.scss";
-</style>

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

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

+ 0 - 54
components/uview-ui/components/u-gap/u-gap.vue

@@ -1,54 +0,0 @@
-<template>
-	<view class="u-gap" :style="[gapStyle]"></view>
-</template>
-
-<script>
-/**
- * gap 间隔槽
- * @description 该组件一般用于内容块之间的用一个灰色块隔开的场景,方便用户风格统一,减少工作量
- * @tutorial https://www.uviewui.com/components/gap.html
- * @property {String} bg-color 背景颜色(默认#f3f4f6)
- * @property {String Number} height 分割槽高度,单位rpx(默认30)
- * @property {String Number} margin-top 与前一个组件的距离,单位rpx(默认0)
- * @property {String Number} margin-bottom 与后一个组件的距离,单位rpx(0)
- * @example <u-gap height="80" bg-color="#bbb"></u-gap>
- */
-export default {
-	name: "u-gap",
-	props: {
-		bgColor: {
-			type: String,
-			default: 'transparent ' // 背景透明
-		},
-		// 高度
-		height: {
-			type: [String, Number],
-			default: 30
-		},
-		// 与上一个组件的距离
-		marginTop: {
-			type: [String, Number],
-			default: 0
-		},
-		// 与下一个组件的距离
-		marginBottom: {
-			type: [String, Number],
-			default: 0
-		},
-	},
-	computed: {
-		gapStyle() {
-			return {
-				backgroundColor: this.bgColor,
-				height: this.height + 'rpx',
-				marginTop: this.marginTop + 'rpx',
-				marginBottom: this.marginBottom + 'rpx'
-			};
-		}
-	}
-};
-</script>
-
-<style lang="scss" scoped>
-	@import "../../libs/css/style.components.scss";
-</style>

+ 0 - 126
components/uview-ui/components/u-grid-item/u-grid-item.vue

@@ -1,126 +0,0 @@
-<template>
-	<view class="u-grid-item" :hover-class="parentData.hoverClass"
-	 :hover-stay-time="200" @tap="click" :style="{
-			background: bgColor,
-			width: width,
-		}">
-		<view class="u-grid-item-box" :style="[customStyle]" :class="[parentData.border ? 'u-border-right u-border-bottom' : '']">
-			<slot />
-		</view>
-	</view>
-</template>
-
-<script>
-	/**
-	 * gridItem 提示
-	 * @description 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。搭配u-grid使用
-	 * @tutorial https://www.uviewui.com/components/grid.html
-	 * @property {String} bg-color 宫格的背景颜色(默认#ffffff)
-	 * @property {String Number} index 点击宫格时,返回的值
-	 * @property {Object} custom-style 自定义样式,对象形式
-	 * @event {Function} click 点击宫格触发
-	 * @example <u-grid-item></u-grid-item>
-	 */
-	export default {
-		name: "u-grid-item",
-		props: {
-			// 背景颜色
-			bgColor: {
-				type: String,
-				default: '#ffffff'
-			},
-			// 点击时返回的index
-			index: {
-				type: [Number, String],
-				default: ''
-			},
-			// 自定义样式,对象形式
-			customStyle: {
-				type: Object,
-				default() {
-					return {
-						padding: '30rpx 0'
-					}
-				}
-			}
-		},
-		data() {
-			return {
-				parentData: {
-					hoverClass: '', // 按下去的时候,是否显示背景灰色
-					col: 3, // 父组件划分的宫格数
-					border: true, // 是否显示边框,根据父组件决定
-				}
-			};
-		},
-		created() {
-			// 父组件的实例
-			this.updateParentData();
-			// this.parent在updateParentData()中定义
-			this.parent.children.push(this);
-		},
-		computed: {
-			// 每个grid-item的宽度
-			width() {
-				return 100 / Number(this.parentData.col) + '%';
-			},
-		},
-		methods: {
-			// 获取父组件的参数
-			updateParentData() {
-				// 此方法写在mixin中
-				this.getParentData('u-grid');
-			},
-			click() {
-				this.$emit('click', this.index);
-				this.parent && this.parent.click(this.index);
-			}
-		}
-	};
-</script>
-
-<style scoped lang="scss">
-	@import "../../libs/css/style.components.scss";
-	
-	.u-grid-item {
-		box-sizing: border-box;
-		background: #fff;
-		@include vue-flex;
-		align-items: center;
-		justify-content: center;
-		position: relative;
-		flex-direction: column;
-		
-		/* #ifdef MP */
-		position: relative;
-		float: left;
-		/* #endif */
-	}
-
-	.u-grid-item-hover {
-		background: #f7f7f7 !important;
-	}
-
-	.u-grid-marker-box {
-		position: absolute;
-		/* #ifndef APP-NVUE */
-		display: inline-flex;		
-		/* #endif */
-		line-height: 0;
-	}
-
-	.u-grid-marker-wrap {
-		position: absolute;
-	}
-
-	.u-grid-item-box {
-		padding: 30rpx 0;
-		@include vue-flex;
-		align-items: center;
-		justify-content: center;
-		flex-direction: column;
-		flex: 1;
-		width: 100%;
-		height: 100%;
-	}
-</style>

+ 0 - 0
components/uview-ui/components/u-grid/u-grid.vue


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