Commit 9709f200c2145593a497ec0b4efa71131368847a

Authored by sfmind
1 parent 9ae44336

uni-app引入使用uView

Showing 386 changed files with 38777 additions and 0 deletions

Too many changes.

To preserve performance only 100 of 386 files are displayed.

yudao-ui-app/App.vue 0 → 100644
  1 +<script>
  2 + export default {
  3 + onLaunch: function() {
  4 + console.log('App Launch')
  5 + },
  6 + onShow: function() {
  7 + console.log('App Show')
  8 + },
  9 + onHide: function() {
  10 + console.log('App Hide')
  11 + }
  12 + }
  13 +</script>
  14 +
  15 +<style lang="scss">
  16 + /* 引入uView基础样式 */
  17 + @import "@/uni_modules/uview-ui/index.scss";
  18 +
  19 + /*每个页面公共css */
  20 + .container {
  21 + background-color: $uni-bg-color;
  22 + box-sizing: border-box;
  23 + height: 100%;
  24 + }
  25 +</style>
... ...
yudao-ui-app/index.html 0 → 100644
  1 +<!DOCTYPE html>
  2 +<html lang="en">
  3 + <head>
  4 + <meta charset="UTF-8" />
  5 + <script>
  6 + var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
  7 + CSS.supports('top: constant(a)'))
  8 + document.write(
  9 + '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
  10 + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
  11 + </script>
  12 + <title></title>
  13 + <!--preload-links-->
  14 + <!--app-context-->
  15 + </head>
  16 + <body>
  17 + <div id="app"><!--app-html--></div>
  18 + <script type="module" src="/main.js"></script>
  19 + </body>
  20 +</html>
... ...
yudao-ui-app/main.js 0 → 100644
  1 +import App from './App'
  2 +
  3 +// #ifndef VUE3
  4 +import Vue from 'vue'
  5 +Vue.config.productionTip = false
  6 +
  7 +//引入并使用uView的JS库
  8 +import uView from '@/uni_modules/uview-ui'
  9 +Vue.use(uView)
  10 +
  11 +App.mpType = 'app'
  12 +const app = new Vue({
  13 + ...App
  14 +})
  15 +app.$mount()
  16 +// #endif
  17 +
  18 +// #ifdef VUE3
  19 +import { createSSRApp } from 'vue'
  20 +export function createApp() {
  21 + const app = createSSRApp(App)
  22 + return {
  23 + app
  24 + }
  25 +}
  26 +// #endif
0 27 \ No newline at end of file
... ...
yudao-ui-app/manifest.json 0 → 100644
  1 +{
  2 + "name" : "yudao-ui-app",
  3 + "appid" : "__UNI__CA099E3",
  4 + "description" : "yudao-ui-app for ruoyi-vue-pro",
  5 + "versionName" : "1.0.0",
  6 + "versionCode" : "100",
  7 + "transformPx" : false,
  8 + /* 5+App特有相关 */
  9 + "app-plus" : {
  10 + "usingComponents" : true,
  11 + "nvueStyleCompiler" : "uni-app",
  12 + "compilerVersion" : 3,
  13 + "splashscreen" : {
  14 + "alwaysShowBeforeRender" : true,
  15 + "waiting" : true,
  16 + "autoclose" : true,
  17 + "delay" : 0
  18 + },
  19 + /* 模块配置 */
  20 + "modules" : {},
  21 + /* 应用发布信息 */
  22 + "distribute" : {
  23 + /* android打包配置 */
  24 + "android" : {
  25 + "permissions" : [
  26 + "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
  27 + "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
  28 + "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
  29 + "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
  30 + "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
  31 + "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
  32 + "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
  33 + "<uses-permission android:name=\"android.permission.CAMERA\"/>",
  34 + "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
  35 + "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
  36 + "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
  37 + "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
  38 + "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
  39 + "<uses-feature android:name=\"android.hardware.camera\"/>",
  40 + "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
  41 + ]
  42 + },
  43 + /* ios打包配置 */
  44 + "ios" : {},
  45 + /* SDK配置 */
  46 + "sdkConfigs" : {}
  47 + }
  48 + },
  49 + /* 快应用特有相关 */
  50 + "quickapp" : {},
  51 + /* 小程序特有相关 */
  52 + "mp-weixin" : {
  53 + "appid" : "",
  54 + "setting" : {
  55 + "urlCheck" : false
  56 + },
  57 + "usingComponents" : true
  58 + },
  59 + "mp-alipay" : {
  60 + "usingComponents" : true
  61 + },
  62 + "mp-baidu" : {
  63 + "usingComponents" : true
  64 + },
  65 + "mp-toutiao" : {
  66 + "usingComponents" : true
  67 + },
  68 + "uniStatistics" : {
  69 + "enable" : false
  70 + },
  71 + "vueVersion" : "2"
  72 +}
... ...
yudao-ui-app/pages.json 0 → 100644
  1 +{
  2 + "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
  3 + {
  4 + "path": "pages/index/index",
  5 + "style": {
  6 + "navigationBarTitleText": "首页"
  7 + }
  8 + },
  9 + {
  10 + "path": "pages/category/category",
  11 + "style": {
  12 + "navigationBarTitleText": "分类"
  13 + }
  14 + },
  15 + {
  16 + "path": "pages/cart/cart",
  17 + "style": {
  18 + "navigationBarTitleText": "购物车"
  19 + }
  20 + },
  21 + {
  22 + "path": "pages/user/user",
  23 + "style": {
  24 + "navigationBarTitleText": "我的"
  25 + }
  26 + }
  27 + ],
  28 + "tabBar": {
  29 + "selectedColor": "#333333",
  30 + "color": "#bfbfbf",
  31 + "list": [
  32 + {
  33 + "pagePath": "pages/index/index",
  34 + "text": "首页",
  35 + "iconPath": "/static/images/tabbar/index.png",
  36 + "selectedIconPath": "/static/images/tabbar/index-active.png"
  37 + },
  38 + {
  39 + "pagePath": "pages/category/category",
  40 + "text": "分类",
  41 + "iconPath": "/static/images/tabbar/category.png",
  42 + "selectedIconPath": "/static/images/tabbar/category-active.png"
  43 + },
  44 + {
  45 + "pagePath": "pages/cart/cart",
  46 + "text": "购物车",
  47 + "iconPath": "/static/images/tabbar/cart.png",
  48 + "selectedIconPath": "/static/images/tabbar/cart-active.png"
  49 + },
  50 + {
  51 + "pagePath": "pages/user/user.png",
  52 + "text": "我的",
  53 + "iconPath": "/static/images/tabbar/user.png",
  54 + "selectedIconPath": "/static/images/tabbar/user-active.png"
  55 + }
  56 + ]
  57 + },
  58 + "globalStyle": {
  59 + "navigationBarTextStyle": "black",
  60 + "navigationBarTitleText": "yudao-ui-app",
  61 + "navigationBarBackgroundColor": "#F8F8F8",
  62 + "backgroundColor": "#FFFFFF"
  63 + }
  64 +}
... ...
yudao-ui-app/pages/cart/cart.nvue 0 → 100644
  1 +<template>
  2 + <view class="container">
  3 +
  4 + </view>
  5 +</template>
  6 +
  7 +<script>
  8 + export default {
  9 + data() {
  10 + return {
  11 + title: ''
  12 + }
  13 + },
  14 + onLoad() {
  15 +
  16 + },
  17 + methods: {
  18 +
  19 + }
  20 + }
  21 +</script>
  22 +
  23 +<style lang="scss" scoped>
  24 +</style>
... ...
yudao-ui-app/pages/category/category.nvue 0 → 100644
  1 +<template>
  2 + <view class="container">
  3 +
  4 + </view>
  5 +</template>
  6 +
  7 +<script>
  8 + export default {
  9 + data() {
  10 + return {
  11 + title: ''
  12 + }
  13 + },
  14 + onLoad() {
  15 +
  16 + },
  17 + methods: {
  18 +
  19 + }
  20 + }
  21 +</script>
  22 +
  23 +<style lang="scss" scoped>
  24 +</style>
... ...
yudao-ui-app/pages/index/index.nvue 0 → 100644
  1 +<template>
  2 + <view class="container">
  3 +
  4 + </view>
  5 +</template>
  6 +
  7 +<script>
  8 + export default {
  9 + data() {
  10 + return {
  11 + title: ''
  12 + }
  13 + },
  14 + onLoad() {
  15 +
  16 + },
  17 + methods: {
  18 +
  19 + }
  20 + }
  21 +</script>
  22 +
  23 +<style lang="scss" scoped>
  24 +
  25 +</style>
... ...
yudao-ui-app/pages/user/user.nvue 0 → 100644
  1 +<template>
  2 + <view class="container">
  3 +
  4 + </view>
  5 +</template>
  6 +
  7 +<script>
  8 + export default {
  9 + data() {
  10 + return {
  11 + title: ''
  12 + }
  13 + },
  14 + onLoad() {
  15 +
  16 + },
  17 + methods: {
  18 +
  19 + }
  20 + }
  21 +</script>
  22 +
  23 +<style lang="scss" scoped>
  24 +
  25 +</style>
... ...
yudao-ui-app/static/images/tabbar/cart-active.png 0 → 100644

6.16 KB

yudao-ui-app/static/images/tabbar/cart.png 0 → 100644

6.02 KB

yudao-ui-app/static/images/tabbar/category-active.png 0 → 100644

7.98 KB

yudao-ui-app/static/images/tabbar/category.png 0 → 100644

7.71 KB

yudao-ui-app/static/images/tabbar/index-active.png 0 → 100644

6.73 KB

yudao-ui-app/static/images/tabbar/index.png 0 → 100644

6.61 KB

yudao-ui-app/static/images/tabbar/user-active.png 0 → 100644

8.1 KB

yudao-ui-app/static/images/tabbar/user.png 0 → 100644

7.88 KB

yudao-ui-app/uni.scss 0 → 100644
  1 +/**
  2 + * 这里是uni-app内置的常用样式变量
  3 + *
  4 + * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
  5 + * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
  6 + *
  7 + */
  8 +
  9 +/**
  10 + * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
  11 + *
  12 + * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
  13 + */
  14 +
  15 +/* 引入uView主题样式 */
  16 +@import '@/uni_modules/uview-ui/theme.scss';
  17 +
  18 +/* 颜色变量 */
  19 +
  20 +/* 行为相关颜色 */
  21 +$uni-color-primary: #007aff;
  22 +$uni-color-success: #4cd964;
  23 +$uni-color-warning: #f0ad4e;
  24 +$uni-color-error: #dd524d;
  25 +
  26 +/* 文字基本颜色 */
  27 +$uni-text-color:#333;//基本色
  28 +$uni-text-color-inverse:#fff;//反色
  29 +$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
  30 +$uni-text-color-placeholder: #808080;
  31 +$uni-text-color-disable:#c0c0c0;
  32 +
  33 +/* 背景颜色 */
  34 +$uni-bg-color:#ffffff;
  35 +$uni-bg-color-grey:#f8f8f8;
  36 +$uni-bg-color-hover:#f1f1f1;//点击状态颜色
  37 +$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
  38 +
  39 +/* 边框颜色 */
  40 +$uni-border-color:#c8c7cc;
  41 +
  42 +/* 尺寸变量 */
  43 +
  44 +/* 文字尺寸 */
  45 +$uni-font-size-sm:12px;
  46 +$uni-font-size-base:14px;
  47 +$uni-font-size-lg:16;
  48 +
  49 +/* 图片尺寸 */
  50 +$uni-img-size-sm:20px;
  51 +$uni-img-size-base:26px;
  52 +$uni-img-size-lg:40px;
  53 +
  54 +/* Border Radius */
  55 +$uni-border-radius-sm: 2px;
  56 +$uni-border-radius-base: 3px;
  57 +$uni-border-radius-lg: 6px;
  58 +$uni-border-radius-circle: 50%;
  59 +
  60 +/* 水平间距 */
  61 +$uni-spacing-row-sm: 5px;
  62 +$uni-spacing-row-base: 10px;
  63 +$uni-spacing-row-lg: 15px;
  64 +
  65 +/* 垂直间距 */
  66 +$uni-spacing-col-sm: 4px;
  67 +$uni-spacing-col-base: 8px;
  68 +$uni-spacing-col-lg: 12px;
  69 +
  70 +/* 透明度 */
  71 +$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
  72 +
  73 +/* 文章场景相关 */
  74 +$uni-color-title: #2C405A; // 文章标题颜色
  75 +$uni-font-size-title:20px;
  76 +$uni-color-subtitle: #555555; // 二级标题颜色
  77 +$uni-font-size-subtitle:26px;
  78 +$uni-color-paragraph: #3F536E; // 文章段落颜色
  79 +$uni-font-size-paragraph:15px;
... ...
yudao-ui-app/uni_modules/uview-ui/LICENSE 0 → 100644
  1 +MIT License
  2 +
  3 +Copyright (c) 2020 www.uviewui.com
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy
  6 +of this software and associated documentation files (the "Software"), to deal
  7 +in the Software without restriction, including without limitation the rights
  8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 +copies of the Software, and to permit persons to whom the Software is
  10 +furnished to do so, subject to the following conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be included in all
  13 +copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 +SOFTWARE.
0 22 \ No newline at end of file
... ...
yudao-ui-app/uni_modules/uview-ui/README.md 0 → 100644
  1 +<p align="center">
  2 + <img alt="logo" src="https://uviewui.com/common/logo.png" width="120" height="120" style="margin-bottom: 10px;">
  3 +</p>
  4 +<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">uView</h3>
  5 +<h3 align="center">多平台快速开发的UI框架</h3>
  6 +
  7 +## 说明
  8 +
  9 +uView UI,是[uni-app](https://uniapp.dcloud.io/)生态优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
  10 +
  11 +## 特性
  12 +
  13 +- 兼容安卓,iOS,微信小程序,H5,QQ小程序,百度小程序,支付宝小程序,头条小程序
  14 +- 60+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用
  15 +- 众多贴心的JS利器,让您飞镖在手,召之即来,百步穿杨
  16 +- 众多的常用页面和布局,让您专注逻辑,事半功倍
  17 +- 详尽的文档支持,现代化的演示效果
  18 +- 按需引入,精简打包体积
  19 +
  20 +
  21 +## 安装
  22 +
  23 +```bash
  24 +# npm方式安装,插件市场导入无需执行此命令
  25 +npm i uview-ui
  26 +```
  27 +
  28 +## 快速上手
  29 +
  30 +1. `main.js`引入uView库
  31 +```js
  32 +// main.js
  33 +import uView from 'uview-ui';
  34 +Vue.use(uView);
  35 +```
  36 +
  37 +2. `App.vue`引入基础样式(注意style标签需声明scss属性支持)
  38 +```css
  39 +/* App.vue */
  40 +<style lang="scss">
  41 +@import "uview-ui/index.scss";
  42 +</style>
  43 +```
  44 +
  45 +3. `uni.scss`引入全局scss变量文件
  46 +```css
  47 +/* uni.scss */
  48 +@import "uview-ui/theme.scss";
  49 +```
  50 +
  51 +4. `pages.json`配置easycom规则(按需引入)
  52 +
  53 +```js
  54 +// pages.json
  55 +{
  56 + "easycom": {
  57 + // npm安装的方式不需要前面的"@/",下载安装的方式需要"@/"
  58 + // npm安装方式
  59 + "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
  60 + // 下载安装方式
  61 + // "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
  62 + },
  63 + // 此为本身已有的内容
  64 + "pages": [
  65 + // ......
  66 + ]
  67 +}
  68 +```
  69 +
  70 +请通过[快速上手](https://www.uviewui.com/components/quickstart.html)了解更详细的内容
  71 +
  72 +## 使用方法
  73 +配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
  74 +
  75 +```html
  76 +<template>
  77 + <u-button text="按钮"></u-button>
  78 +</template>
  79 +```
  80 +
  81 +请通过[快速上手](https://www.uviewui.com/components/quickstart.html)了解更详细的内容
  82 +
  83 +## 链接
  84 +
  85 +- [官方文档](https://www.uviewui.com/)
  86 +- [更新日志](https://www.www.uviewui.com/components/changelog.html)
  87 +- [升级指南](https://www.uviewui.com/components/changelog.html)
  88 +- [关于我们](https://www.uviewui.com/cooperation/about.html)
  89 +
  90 +## 预览
  91 +
  92 +您可以通过**微信**扫码,查看最佳的演示效果。
  93 +<br>
  94 +<br>
  95 +<img src="https://uviewui.com/common/weixin_mini_qrcode.png" width="220" height="220" >
  96 +
  97 +## 捐赠uView的研发
  98 +
  99 +uView文档和源码全部开源免费,如果您认为uView帮到了您的开发工作,您可以捐赠uView的研发工作,捐赠无门槛,哪怕是一杯可乐也好(相信这比打赏主播更有意义)。
  100 +
  101 +<img src="https://uviewui.com/common/alipay.png" width="220" ><img style="margin-left: 100px;" src="https://uviewui.com/common/wechat.png" width="220" >
  102 +
  103 +## 版权信息
  104 +uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。
... ...
yudao-ui-app/uni_modules/uview-ui/changelog.md 0 → 100644
  1 +## 2.0.30(2022-04-04)
  2 +# uView2.0重磅发布,利剑出鞘,一统江湖
  3 +
  4 +1. `u-rate`增加`readonly`属性
  5 +2. `tabs`滑块支持设置背景图片
  6 +3. 修复`u-subsection` `mode`为`subsection`时,滑块样式不正确的问题
  7 +4. `u-code-input`添加光标效果动画
  8 +5. 修复`popup`的`open`事件不触发
  9 +6. 修复`u-flex-column`无效的问题
  10 +7. 修复`u-datetime-picker`索引在特定场合异常问题
  11 +8. 修复`u-datetime-picker`最小时间字符串模板错误问题
  12 +9. `u-swiper`添加`m3u8`验证
  13 +10. `u-swiper`修改判断image和video逻辑
  14 +11. 修复`swiper`无法使用本地图片问题,增加`type`参数
  15 +12. 修复`u-row-notice`格式错误问题
  16 +13. 修复`u-switch`组件当`unit`为`rpx`时,`nodeStyle`消失的问题
  17 +14. 修复`datetime-picker`组件`showToolbar`与`visibleItemCount`属性无效的问题
  18 +15. 修复`upload`组件条件编译位置判断错误,导致`previewImage`属性设置为`false`时,整个组件都会被隐藏的问题
  19 +16. 修复`u-checkbox-group`设置`shape`属性无效的问题
  20 +17. 修复`u-upload`的`capture`传入字符串的时候不生效的问题
  21 +18. 修复`u-action-sheet`组件,关闭事件逻辑错误的问题
  22 +19. 修复`u-list`触顶事件的触发错误的问题
  23 +20. 修复`u-text`只有手机号可拨打的问题
  24 +21. 修复`u-textarea`不能换行的问题
  25 +22. 其他修复
  26 +## 2.0.29(2022-03-13)
  27 +# uView2.0重磅发布,利剑出鞘,一统江湖
  28 +
  29 +1. 修复`u--text`组件设置`decoration`属性未生效的问题
  30 +2. 修复`u-datetime-picker`使用`formatter`后返回值不正确
  31 +3. 修复`u-datetime-picker` `intercept` 可能为undefined
  32 +4. 修复已设置单位 uni..config.unit = 'rpx'时,线型指示器 `transform` 的位置翻倍,导致指示器超出宽度
  33 +5. 修复mixin中bem方法生成的类名在支付宝和字节小程序中失效
  34 +6. 修复默认值传值为空的时候,打开`u-datetime-picker`报错,不能选中第一列时间的bug
  35 +7. 修复`u-datetime-picker`使用`formatter`后返回值不正确
  36 +8. 修复`u-image`组件`loading`无效果的问题
  37 +9. 修复`config.unit`属性设为`rpx`时,导航栏占用高度不足导致塌陷的问题
  38 +10. 修复`u-datetime-picker`组件`itemHeight`无效问题
  39 +11. 其他修复
  40 +## 2.0.28(2022-02-22)
  41 +# uView2.0重磅发布,利剑出鞘,一统江湖
  42 +
  43 +1. search组件新增searchIconSize属性
  44 +2. 兼容Safari/Webkit中传入时间格式如2022-02-17 12:00:56
  45 +3. 修复text value.js 判断日期出format错误问题
  46 +4. priceFormat格式化金额出现精度错误
  47 +5. priceFormat在部分情况下出现精度损失问题
  48 +6. 优化表单rules提示
  49 +7. 修复avatar组件src为空时,展示状态不对
  50 +8. 其他修复
  51 +## 2.0.27(2022-01-28)
  52 +# uView2.0重磅发布,利剑出鞘,一统江湖
  53 +
  54 +1.样式修复
  55 +## 2.0.26(2022-01-28)
  56 +# uView2.0重磅发布,利剑出鞘,一统江湖
  57 +
  58 +1.样式修复
  59 +## 2.0.25(2022-01-27)
  60 +# uView2.0重磅发布,利剑出鞘,一统江湖
  61 +
  62 +1. 修复text组件mode=price时,可能会导致精度错误的问题
  63 +2. 添加$u.setConfig()方法,可设置uView内置的config, props, zIndex, color属性,详见:[修改uView内置配置方案](https://uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
  64 +3. 优化form组件在errorType=toast时,如果输入错误页面会有抖动的问题
  65 +4. 修复$u.addUnit()对配置默认单位可能无效的问题
  66 +## 2.0.24(2022-01-25)
  67 +# uView2.0重磅发布,利剑出鞘,一统江湖
  68 +
  69 +1. 修复swiper在current指定非0时缩放有误
  70 +2. 修复u-icon添加stop属性的时候报错
  71 +3. 优化遗留的通过正则判断rpx单位的问题
  72 +4. 优化Layout布局 vue使用gutter时,会超出固定区域
  73 +5. 优化search组件高度单位问题(rpx -> px)
  74 +6. 修复u-image slot 加载和错误的图片失去了高度
  75 +7. 修复u-index-list中footer插槽与header插槽存在性判断错误
  76 +8. 修复部分机型下u-popup关闭时会闪烁
  77 +9. 修复u-image在nvue-app下失去宽高
  78 +10. 修复u-popup运行报错
  79 +11. 修复u-tooltip报错
  80 +12. 修复box-sizing在app下的警告
  81 +13. 修复u-navbar在小程序中报运行时错误
  82 +14. 其他修复
  83 +## 2.0.23(2022-01-24)
  84 +# uView2.0重磅发布,利剑出鞘,一统江湖
  85 +
  86 +1. 修复image组件在hx3.3.9的nvue下可能会显示异常的问题
  87 +2. 修复col组件gutter参数带rpx单位处理不正确的问题
  88 +3. 修复text组件单行时无法显示省略号的问题
  89 +4. navbar添加titleStyle参数
  90 +5. 升级到hx3.3.9可消除nvue下控制台样式警告的问题
  91 +## 2.0.22(2022-01-19)
  92 +# uView2.0重磅发布,利剑出鞘,一统江湖
  93 +
  94 +1. $u.page()方法优化,避免在特殊场景可能报错的问题
  95 +2. picker组件添加immediateChange参数
  96 +3. 新增$u.pages()方法
  97 +## 2.0.21(2022-01-19)
  98 +# uView2.0重磅发布,利剑出鞘,一统江湖
  99 +
  100 +1. 优化:form组件在用户设置rules的时候提示用户model必传
  101 +2. 优化遗留的通过正则判断rpx单位的问题
  102 +3. 修复微信小程序环境中tabbar组件开启safeAreaInsetBottom属性后,placeholder高度填充不正确
  103 +4. 修复swiper在current指定非0时缩放有误
  104 +5. 修复u-icon添加stop属性的时候报错
  105 +6. 修复upload组件在accept=all的时候没有作用
  106 +7. 修复在text组件mode为phone时call属性无效的问题
  107 +8. 处理u-form clearValidate方法
  108 +9. 其他修复
  109 +## 2.0.20(2022-01-14)
  110 +# uView2.0重磅发布,利剑出鞘,一统江湖
  111 +
  112 +1. 修复calendar默认会选择一个日期,如果直接点确定的话,无法取到值的问题
  113 +2. 修复Slider缺少disabled props 还有注释
  114 +3. 修复u-notice-bar点击事件无法拿到index索引值的问题
  115 +4. 修复u-collapse-item在vue文件下,app端自定义插槽不生效的问题
  116 +5. 优化头像为空时显示默认头像
  117 +6. 修复图片地址赋值后判断加载状态为完成问题
  118 +7. 修复日历滚动到默认日期月份区域
  119 +8. search组件暴露点击左边icon事件
  120 +9. 修复u-form clearValidate方法不生效
  121 +10. upload h5端增加返回文件参数(文件的name参数)
  122 +11. 处理upload选择文件后url为blob类型无法预览的问题
  123 +12. u-code-input 修复输入框没有往左移出一半屏幕
  124 +13. 修复Upload上传 disabled为true时,控制台报hoverClass类型错误
  125 +14. 临时处理ios app下grid点击坍塌问题
  126 +15. 其他修复
  127 +## 2.0.19(2021-12-29)
  128 +# uView2.0重磅发布,利剑出鞘,一统江湖
  129 +
  130 +1. 优化微信小程序包体积可在微信中预览,请升级HbuilderX3.3.4,同时在“运行->运行到小程序模拟器”中勾选“运行时是否压缩代码”
  131 +2. 优化微信小程序setData性能,处理某些方法如$u.route()无法在模板中使用的问题
  132 +3. navbar添加autoBack参数
  133 +4. 允许avatar组件的事件冒泡
  134 +5. 修复cell组件报错问题
  135 +6. 其他修复
  136 +## 2.0.18(2021-12-28)
  137 +# uView2.0重磅发布,利剑出鞘,一统江湖
  138 +
  139 +1. 修复app端编译报错问题
  140 +2. 重新处理微信小程序端setData过大的性能问题
  141 +3. 修复边框问题
  142 +4. 修复最大最小月份不大于0则没有数据出现的问题
  143 +5. 修复SwipeAction微信小程序端无法上下滑动问题
  144 +6. 修复input的placeholder在小程序端默认显示为true问题
  145 +7. 修复divider组件click事件无效问题
  146 +8. 修复u-code-input maxlength 属性值为 String 类型时显示异常
  147 +9. 修复当 grid只有 1到2时 在小程序端algin设置无效的问题
  148 +10. 处理form-item的label为top时,取消错误提示的左边距
  149 +11. 其他修复
  150 +## 2.0.17(2021-12-26)
  151 +## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
  152 +
  153 +# uView2.0重磅发布,利剑出鞘,一统江湖
  154 +
  155 +1. 解决HBuilderX3.3.3.20211225版本导致的样式问题
  156 +2. calendar日历添加monthNum参数
  157 +3. navbar添加center slot
  158 +## 2.0.16(2021-12-25)
  159 +## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
  160 +
  161 +# uView2.0重磅发布,利剑出鞘,一统江湖
  162 +
  163 +1. 解决微信小程序setData性能问题
  164 +2. 修复count-down组件change事件不触发问题
  165 +## 2.0.15(2021-12-21)
  166 +## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
  167 +
  168 +# uView2.0重磅发布,利剑出鞘,一统江湖
  169 +
  170 +1. 修复Cell单元格titleWidth无效
  171 +2. 修复cheakbox组件ischecked不更新
  172 +3. 修复keyboard是否显示"."按键默认值问题
  173 +4. 修复number-keyboard是否显示键盘的"."符号问题
  174 +5. 修复Input输入框 readonly无效
  175 +6. 修复u-avatar 导致打包app、H5时候报错问题
  176 +7. 修复Upload上传deletable无效
  177 +8. 修复upload当设置maxSize时无效的问题
  178 +9. 修复tabs lineWidth传入带单位的字符串的时候偏移量计算错误问题
  179 +10. 修复rate组件在有padding的view内,显示的星星位置和可触摸区域不匹配,无法正常选中星星
  180 +## 2.0.13(2021-12-14)
  181 +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
  182 +
  183 +# uView2.0重磅发布,利剑出鞘,一统江湖
  184 +
  185 +1. 修复配置默认单位为rpx可能会导致自定义导航栏高度异常的问题
  186 +## 2.0.12(2021-12-14)
  187 +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
  188 +
  189 +# uView2.0重磅发布,利剑出鞘,一统江湖
  190 +
  191 +1. 修复tabs组件在vue环境下划线消失的问题
  192 +2. 修复upload组件在安卓小程序无法选择视频的问题
  193 +3. 添加uni.$u.config.unit配置,用于配置参数默认单位,详见:[默认单位配置](https://www.uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
  194 +4. 修复textarea组件在没绑定v-model时,字符统计不生效问题
  195 +5. 修复nvue下控制是否出现滚动条失效问题
  196 +## 2.0.11(2021-12-13)
  197 +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
  198 +
  199 +# uView2.0重磅发布,利剑出鞘,一统江湖
  200 +
  201 +1. text组件align参数无效的问题
  202 +2. subsection组件添加keyName参数
  203 +3. upload组件无法判断[Object file]类型的问题
  204 +4. 处理notify层级过低问题
  205 +5. codeInput组件添加disabledDot参数
  206 +6. 处理actionSheet组件round参数无效的问题
  207 +7. calendar组件添加round参数用于控制圆角值
  208 +8. 处理swipeAction组件在vue环境下默认被打开的问题
  209 +9. button组件的throttleTime节流参数无效的问题
  210 +10. 解决u-notify手动关闭方法close()无效的问题
  211 +11. input组件readonly不生效问题
  212 +12. tag组件type参数为info不生效问题
  213 +## 2.0.10(2021-12-08)
  214 +## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
  215 +
  216 +# uView2.0重磅发布,利剑出鞘,一统江湖
  217 +
  218 +1. 修复button sendMessagePath属性不生效
  219 +2. 修复DatetimePicker选择器title无效
  220 +3. 修复u-toast设置loading=true不生效
  221 +4. 修复u-text金额模式传0报错
  222 +5. 修复u-toast组件的icon属性配置不生效
  223 +6. button的icon在特殊场景下的颜色优化
  224 +7. IndexList优化,增加#
  225 +## 2.0.9(2021-12-01)
  226 +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
  227 +
  228 +# uView2.0重磅发布,利剑出鞘,一统江湖
  229 +
  230 +1. 优化swiper的height支持100%值(仅vue有效),修复嵌入视频时click事件无法触发的问题
  231 +2. 优化tabs组件对list值为空的判断,或者动态变化list时重新计算相关尺寸的问题
  232 +3. 优化datetime-picker组件逻辑,让其后续打开的默认值为上一次的选中值,需要通过v-model绑定值才有效
  233 +4. 修复upload内嵌在其他组件中,选择图片可能不会换行的问题
  234 +## 2.0.8(2021-12-01)
  235 +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
  236 +
  237 +# uView2.0重磅发布,利剑出鞘,一统江湖
  238 +
  239 +1. 修复toast的position参数无效问题
  240 +2. 处理input在ios nvue上无法获得焦点的问题
  241 +3. avatar-group组件添加extraValue参数,让剩余展示数量可手动控制
  242 +4. tabs组件添加keyName参数用于配置从对象中读取的键名
  243 +5. 处理text组件名字脱敏默认配置无效的问题
  244 +6. 处理picker组件item文本太长换行问题
  245 +## 2.0.7(2021-11-30)
  246 +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
  247 +
  248 +# uView2.0重磅发布,利剑出鞘,一统江湖
  249 +
  250 +1. 修复radio和checkbox动态改变v-model无效的问题。
  251 +2. 优化form规则validator在微信小程序用法
  252 +3. 修复backtop组件mode参数在微信小程序无效的问题
  253 +4. 处理Album的previewFullImage属性无效的问题
  254 +5. 处理u-datetime-picker组件mode='time'在选择改变时间时,控制台报错的问题
  255 +## 2.0.6(2021-11-27)
  256 +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
  257 +
  258 +# uView2.0重磅发布,利剑出鞘,一统江湖
  259 +
  260 +1. 处理tag组件在vue下边框无效的问题。
  261 +2. 处理popup组件圆角参数可能无效的问题。
  262 +3. 处理tabs组件lineColor参数可能无效的问题。
  263 +4. propgress组件在值很小时,显示异常的问题。
  264 +## 2.0.5(2021-11-25)
  265 +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
  266 +
  267 +# uView2.0重磅发布,利剑出鞘,一统江湖
  268 +
  269 +1. calendar在vue下显示异常问题。
  270 +2. form组件labelPosition和errorType参数无效的问题
  271 +3. input组件inputAlign无效的问题
  272 +4. 其他一些修复
  273 +## 2.0.4(2021-11-23)
  274 +## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
  275 +
  276 +# uView2.0重磅发布,利剑出鞘,一统江湖
  277 +
  278 +0. input组件缺失@confirm事件,以及subfix和prefix无效问题
  279 +1. component.scss文件样式在vue下干扰全局布局问题
  280 +2. 修复subsection在vue环境下表现异常的问题
  281 +3. tag组件的bgColor等参数无效的问题
  282 +4. upload组件不换行的问题
  283 +5. 其他的一些修复处理
  284 +## 2.0.3(2021-11-16)
  285 +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
  286 +
  287 +# uView2.0重磅发布,利剑出鞘,一统江湖
  288 +
  289 +1. uView2.0已实现全面兼容nvue
  290 +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
  291 +3. 目前uView2.0为公测阶段,相关细节可能会有变动
  292 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
  293 +5. 处理modal的confirm回调事件拼写错误问题
  294 +6. 处理input组件@input事件参数错误问题
  295 +7. 其他一些修复
  296 +## 2.0.2(2021-11-16)
  297 +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
  298 +
  299 +# uView2.0重磅发布,利剑出鞘,一统江湖
  300 +
  301 +1. uView2.0已实现全面兼容nvue
  302 +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
  303 +3. 目前uView2.0为公测阶段,相关细节可能会有变动
  304 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
  305 +5. 修复input组件formatter参数缺失问题
  306 +6. 优化loading-icon组件的scss写法问题,防止不兼容新版本scss
  307 +## 2.0.0(2020-11-15)
  308 +## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
  309 +
  310 +# uView2.0重磅发布,利剑出鞘,一统江湖
  311 +
  312 +1. uView2.0已实现全面兼容nvue
  313 +2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
  314 +3. 目前uView2.0为公测阶段,相关细节可能会有变动
  315 +4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
  316 +5. 修复input组件formatter参数缺失问题
  317 +
  318 +
... ...
yudao-ui-app/uni_modules/uview-ui/components/u--form/u--form.vue 0 → 100644
  1 +<template>
  2 + <uvForm
  3 + ref="uForm"
  4 + :model="model"
  5 + :rules="rules"
  6 + :errorType="errorType"
  7 + :borderBottom="borderBottom"
  8 + :labelPosition="labelPosition"
  9 + :labelWidth="labelWidth"
  10 + :labelAlign="labelAlign"
  11 + :labelStyle="labelStyle"
  12 + :customStyle="customStyle"
  13 + >
  14 + <slot />
  15 + </uvForm>
  16 +</template>
  17 +
  18 +<script>
  19 + /**
  20 + * 此组件存在的理由是,在nvue下,u-form被uni-app官方占用了,u-form在nvue中相当于form组件
  21 + * 所以在nvue下,取名为u--form,内部其实还是u-form.vue,只不过做一层中转
  22 + */
  23 + import uvForm from '../u-form/u-form.vue';
  24 + import props from '../u-form/props.js'
  25 + export default {
  26 + // #ifdef MP-WEIXIN
  27 + name: 'u-form',
  28 + // #endif
  29 + // #ifndef MP-WEIXIN
  30 + name: 'u--form',
  31 + // #endif
  32 + mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
  33 + components: {
  34 + uvForm
  35 + },
  36 + created() {
  37 + this.children = []
  38 + },
  39 + methods: {
  40 + // 手动设置校验的规则,如果规则中有函数的话,微信小程序中会过滤掉,所以只能手动调用设置规则
  41 + setRules(rules) {
  42 + this.$refs.uForm.setRules(rules)
  43 + },
  44 + validate() {
  45 + /**
  46 + * 在微信小程序中,通过this.$parent拿到的父组件是u--form,而不是其内嵌的u-form
  47 + * 导致在u-form组件中,拿不到对应的children数组,从而校验无效,所以这里每次调用u-form组件中的
  48 + * 对应方法的时候,在小程序中都先将u--form的children赋值给u-form中的children
  49 + */
  50 + // #ifdef MP-WEIXIN
  51 + this.setMpData()
  52 + // #endif
  53 + return this.$refs.uForm.validate()
  54 + },
  55 + validateField(value, callback) {
  56 + // #ifdef MP-WEIXIN
  57 + this.setMpData()
  58 + // #endif
  59 + return this.$refs.uForm.validateField(value, callback)
  60 + },
  61 + resetFields() {
  62 + // #ifdef MP-WEIXIN
  63 + this.setMpData()
  64 + // #endif
  65 + return this.$refs.uForm.resetFields()
  66 + },
  67 + clearValidate(props) {
  68 + // #ifdef MP-WEIXIN
  69 + this.setMpData()
  70 + // #endif
  71 + return this.$refs.uForm.clearValidate(props)
  72 + },
  73 + setMpData() {
  74 + this.$refs.uForm.children = this.children
  75 + }
  76 + },
  77 + }
  78 +</script>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u--image/u--image.vue 0 → 100644
  1 +<template>
  2 + <uvImage
  3 + :src="src"
  4 + :mode="mode"
  5 + :width="width"
  6 + :height="height"
  7 + :shape="shape"
  8 + :radius="radius"
  9 + :lazyLoad="lazyLoad"
  10 + :showMenuByLongpress="showMenuByLongpress"
  11 + :loadingIcon="loadingIcon"
  12 + :errorIcon="errorIcon"
  13 + :showLoading="showLoading"
  14 + :showError="showError"
  15 + :fade="fade"
  16 + :webp="webp"
  17 + :duration="duration"
  18 + :bgColor="bgColor"
  19 + :customStyle="customStyle"
  20 + @click="$emit('click')"
  21 + @error="$emit('error')"
  22 + @load="$emit('load')"
  23 + >
  24 + <template v-slot:loading>
  25 + <slot name="loading"></slot>
  26 + </template>
  27 + <template v-slot:error>
  28 + <slot name="error"></slot>
  29 + </template>
  30 + </uvImage>
  31 +</template>
  32 +
  33 +<script>
  34 + /**
  35 + * 此组件存在的理由是,在nvue下,u-image被uni-app官方占用了,u-image在nvue中相当于image组件
  36 + * 所以在nvue下,取名为u--image,内部其实还是u-iamge.vue,只不过做一层中转
  37 + */
  38 + import uvImage from '../u-image/u-image.vue';
  39 + import props from '../u-image/props.js';
  40 + export default {
  41 + name: 'u--image',
  42 + mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
  43 + components: {
  44 + uvImage
  45 + },
  46 + }
  47 +</script>
0 48 \ No newline at end of file
... ...
yudao-ui-app/uni_modules/uview-ui/components/u--input/u--input.vue 0 → 100644
  1 +<template>
  2 + <uvInput
  3 + :value="value"
  4 + :type="type"
  5 + :fixed="fixed"
  6 + :disabled="disabled"
  7 + :disabledColor="disabledColor"
  8 + :clearable="clearable"
  9 + :password="password"
  10 + :maxlength="maxlength"
  11 + :placeholder="placeholder"
  12 + :placeholderClass="placeholderClass"
  13 + :placeholderStyle="placeholderStyle"
  14 + :showWordLimit="showWordLimit"
  15 + :confirmType="confirmType"
  16 + :confirmHold="confirmHold"
  17 + :holdKeyboard="holdKeyboard"
  18 + :focus="focus"
  19 + :autoBlur="autoBlur"
  20 + :disableDefaultPadding="disableDefaultPadding"
  21 + :cursor="cursor"
  22 + :cursorSpacing="cursorSpacing"
  23 + :selectionStart="selectionStart"
  24 + :selectionEnd="selectionEnd"
  25 + :adjustPosition="adjustPosition"
  26 + :inputAlign="inputAlign"
  27 + :fontSize="fontSize"
  28 + :color="color"
  29 + :prefixIcon="prefixIcon"
  30 + :suffixIcon="suffixIcon"
  31 + :suffixIconStyle="suffixIconStyle"
  32 + :prefixIconStyle="prefixIconStyle"
  33 + :border="border"
  34 + :readonly="readonly"
  35 + :shape="shape"
  36 + :customStyle="customStyle"
  37 + :formatter="formatter"
  38 + @focus="$emit('focus')"
  39 + @blur="$emit('blur')"
  40 + @keyboardheightchange="$emit('keyboardheightchange')"
  41 + @change="e => $emit('change', e)"
  42 + @input="e => $emit('input', e)"
  43 + @confirm="e => $emit('confirm', e)"
  44 + @clear="$emit('clear')"
  45 + @click="$emit('click')"
  46 + >
  47 + <!-- #ifdef MP -->
  48 + <slot name="prefix"></slot>
  49 + <slot name="suffix"></slot>
  50 + <!-- #endif -->
  51 + <!-- #ifndef MP -->
  52 + <slot name="prefix" slot="prefix"></slot>
  53 + <slot name="suffix" slot="suffix"></slot>
  54 + <!-- #endif -->
  55 + </uvInput>
  56 +</template>
  57 +
  58 +<script>
  59 + /**
  60 + * 此组件存在的理由是,在nvue下,u-input被uni-app官方占用了,u-input在nvue中相当于input组件
  61 + * 所以在nvue下,取名为u--input,内部其实还是u-input.vue,只不过做一层中转
  62 + */
  63 + import uvInput from '../u-input/u-input.vue';
  64 + import props from '../u-input/props.js'
  65 + export default {
  66 + name: 'u--input',
  67 + mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
  68 + components: {
  69 + uvInput
  70 + },
  71 + }
  72 +</script>
0 73 \ No newline at end of file
... ...
yudao-ui-app/uni_modules/uview-ui/components/u--text/u--text.vue 0 → 100644
  1 +<template>
  2 + <uvText
  3 + :type="type"
  4 + :show="show"
  5 + :text="text"
  6 + :prefixIcon="prefixIcon"
  7 + :suffixIcon="suffixIcon"
  8 + :mode="mode"
  9 + :href="href"
  10 + :format="format"
  11 + :call="call"
  12 + :openType="openType"
  13 + :bold="bold"
  14 + :block="block"
  15 + :lines="lines"
  16 + :color="color"
  17 + :decoration="decoration"
  18 + :size="size"
  19 + :iconStyle="iconStyle"
  20 + :margin="margin"
  21 + :lineHeight="lineHeight"
  22 + :align="align"
  23 + :wordWrap="wordWrap"
  24 + :customStyle="customStyle"
  25 + @click="$emit('click')"
  26 + ></uvText>
  27 +</template>
  28 +
  29 +<script>
  30 +/**
  31 + * 此组件存在的理由是,在nvue下,u-text被uni-app官方占用了,u-text在nvue中相当于input组件
  32 + * 所以在nvue下,取名为u--input,内部其实还是u-text.vue,只不过做一层中转
  33 + * 不使用v-bind="$attrs",而是分开独立写传参,是因为微信小程序不支持此写法
  34 + */
  35 +import uvText from "../u-text/u-text.vue";
  36 +import props from "../u-text/props.js";
  37 +export default {
  38 + name: "u--text",
  39 + mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
  40 + components: {
  41 + uvText,
  42 + },
  43 +};
  44 +</script>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u--textarea/u--textarea.vue 0 → 100644
  1 +<template>
  2 + <uvTextarea
  3 + :value="value"
  4 + :placeholder="placeholder"
  5 + :height="height"
  6 + :confirmType="confirmType"
  7 + :disabled="disabled"
  8 + :count="count"
  9 + :focus="focus"
  10 + :autoHeight="autoHeight"
  11 + :fixed="fixed"
  12 + :cursorSpacing="cursorSpacing"
  13 + :cursor="cursor"
  14 + :showConfirmBar="showConfirmBar"
  15 + :selectionStart="selectionStart"
  16 + :selectionEnd="selectionEnd"
  17 + :adjustPosition="adjustPosition"
  18 + :disableDefaultPadding="disableDefaultPadding"
  19 + :holdKeyboard="holdKeyboard"
  20 + :maxlength="maxlength"
  21 + :border="border"
  22 + :customStyle="customStyle"
  23 + :formatter="formatter"
  24 + @focus="e => $emit('focus')"
  25 + @blur="e => $emit('blur')"
  26 + @linechange="e => $emit('linechange', e)"
  27 + @confirm="e => $emit('confirm')"
  28 + @input="e => $emit('input', e)"
  29 + @keyboardheightchange="e => $emit('keyboardheightchange')"
  30 + ></uvTextarea>
  31 +</template>
  32 +
  33 +<script>
  34 + /**
  35 + * 此组件存在的理由是,在nvue下,u--textarea被uni-app官方占用了,u-textarea在nvue中相当于textarea组件
  36 + * 所以在nvue下,取名为u--textarea,内部其实还是u-textarea.vue,只不过做一层中转
  37 + */
  38 + import uvTextarea from '../u-textarea/u-textarea.vue';
  39 + import props from '../u-textarea/props.js'
  40 + export default {
  41 + name: 'u--textarea',
  42 + mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
  43 + components: {
  44 + uvTextarea
  45 + },
  46 + }
  47 +</script>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-action-sheet/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 操作菜单是否展示 (默认false)
  4 + show: {
  5 + type: Boolean,
  6 + default: uni.$u.props.actionSheet.show
  7 + },
  8 + // 标题
  9 + title: {
  10 + type: String,
  11 + default: uni.$u.props.actionSheet.title
  12 + },
  13 + // 选项上方的描述信息
  14 + description: {
  15 + type: String,
  16 + default: uni.$u.props.actionSheet.description
  17 + },
  18 + // 数据
  19 + actions: {
  20 + type: Array,
  21 + default: uni.$u.props.actionSheet.actions
  22 + },
  23 + // 取消按钮的文字,不为空时显示按钮
  24 + cancelText: {
  25 + type: String,
  26 + default: uni.$u.props.actionSheet.cancelText
  27 + },
  28 + // 点击某个菜单项时是否关闭弹窗
  29 + closeOnClickAction: {
  30 + type: Boolean,
  31 + default: uni.$u.props.actionSheet.closeOnClickAction
  32 + },
  33 + // 处理底部安全区(默认true)
  34 + safeAreaInsetBottom: {
  35 + type: Boolean,
  36 + default: uni.$u.props.actionSheet.safeAreaInsetBottom
  37 + },
  38 + // 小程序的打开方式
  39 + openType: {
  40 + type: String,
  41 + default: uni.$u.props.actionSheet.openType
  42 + },
  43 + // 点击遮罩是否允许关闭 (默认true)
  44 + closeOnClickOverlay: {
  45 + type: Boolean,
  46 + default: uni.$u.props.actionSheet.closeOnClickOverlay
  47 + },
  48 + // 圆角值
  49 + round: {
  50 + type: [Boolean, String, Number],
  51 + default: uni.$u.props.actionSheet.round
  52 + }
  53 + }
  54 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue 0 → 100644
  1 +
  2 +<template>
  3 + <u-popup
  4 + :show="show"
  5 + mode="bottom"
  6 + @close="closeHandler"
  7 + :safeAreaInsetBottom="safeAreaInsetBottom"
  8 + :round="round"
  9 + >
  10 + <view class="u-action-sheet">
  11 + <view
  12 + class="u-action-sheet__header"
  13 + v-if="title"
  14 + >
  15 + <text class="u-action-sheet__header__title u-line-1">{{title}}</text>
  16 + <view
  17 + class="u-action-sheet__header__icon-wrap"
  18 + @tap.stop="close"
  19 + >
  20 + <u-icon
  21 + name="close"
  22 + size="17"
  23 + color="#c8c9cc"
  24 + bold
  25 + ></u-icon>
  26 + </view>
  27 + </view>
  28 + <text
  29 + class="u-action-sheet__description"
  30 + :style="[{
  31 + marginTop: `${title && description ? 0 : '18px'}`
  32 + }]"
  33 + v-if="description"
  34 + >{{description}}</text>
  35 + <slot>
  36 + <u-line v-if="description"></u-line>
  37 + <view class="u-action-sheet__item-wrap">
  38 + <template v-for="(item, index) in actions">
  39 + <!-- #ifdef MP -->
  40 + <button
  41 + :key="index"
  42 + class="u-reset-button"
  43 + :openType="item.openType"
  44 + @getuserinfo="onGetUserInfo"
  45 + @contact="onContact"
  46 + @getphonenumber="onGetPhoneNumber"
  47 + @error="onError"
  48 + @launchapp="onLaunchApp"
  49 + @opensetting="onOpenSetting"
  50 + :lang="lang"
  51 + :session-from="sessionFrom"
  52 + :send-message-title="sendMessageTitle"
  53 + :send-message-path="sendMessagePath"
  54 + :send-message-img="sendMessageImg"
  55 + :show-message-card="showMessageCard"
  56 + :app-parameter="appParameter"
  57 + @tap="selectHandler(index)"
  58 + :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
  59 + >
  60 + <!-- #endif -->
  61 + <view
  62 + class="u-action-sheet__item-wrap__item"
  63 + @tap.stop="selectHandler(index)"
  64 + :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
  65 + :hover-stay-time="150"
  66 + >
  67 + <template v-if="!item.loading">
  68 + <text
  69 + class="u-action-sheet__item-wrap__item__name"
  70 + :style="[itemStyle(index)]"
  71 + >{{ item.name }}</text>
  72 + <text
  73 + v-if="item.subname"
  74 + class="u-action-sheet__item-wrap__item__subname"
  75 + >{{ item.subname }}</text>
  76 + </template>
  77 + <u-loading-icon
  78 + v-else
  79 + custom-class="van-action-sheet__loading"
  80 + size="18"
  81 + mode="circle"
  82 + />
  83 + </view>
  84 + <!-- #ifdef MP -->
  85 + </button>
  86 + <!-- #endif -->
  87 + <u-line v-if="index !== actions.length - 1"></u-line>
  88 + </template>
  89 + </view>
  90 + </slot>
  91 + <u-gap
  92 + bgColor="#eaeaec"
  93 + height="6"
  94 + v-if="cancelText"
  95 + ></u-gap>
  96 + <view hover-class="u-action-sheet--hover">
  97 + <text
  98 + @touchmove.stop.prevent
  99 + :hover-stay-time="150"
  100 + v-if="cancelText"
  101 + class="u-action-sheet__cancel-text"
  102 + @tap="cancel"
  103 + >{{cancelText}}</text>
  104 + </view>
  105 + </view>
  106 + </u-popup>
  107 +</template>
  108 +
  109 +<script>
  110 + import openType from '../../libs/mixin/openType'
  111 + import button from '../../libs/mixin/button'
  112 + import props from './props.js';
  113 + /**
  114 + * ActionSheet 操作菜单
  115 + * @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
  116 + * @tutorial https://www.uviewui.com/components/actionSheet.html
  117 + *
  118 + * @property {Boolean} show 操作菜单是否展示 (默认 false )
  119 + * @property {String} title 操作菜单标题
  120 + * @property {String} description 选项上方的描述信息
  121 + * @property {Array<Object>} actions 按钮的文字数组,见官方文档示例
  122 + * @property {String} cancelText 取消按钮的提示文字,不为空时显示按钮
  123 + * @property {Boolean} closeOnClickAction 点击某个菜单项时是否关闭弹窗 (默认 true )
  124 + * @property {Boolean} safeAreaInsetBottom 处理底部安全区 (默认 true )
  125 + * @property {String} openType 小程序的打开方式 (contact | launchApp | getUserInfo | openSetting |getPhoneNumber |error )
  126 + * @property {Boolean} closeOnClickOverlay 点击遮罩是否允许关闭 (默认 true )
  127 + * @property {Number|String} round 圆角值,默认无圆角 (默认 0 )
  128 + * @property {String} lang 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文
  129 + * @property {String} sessionFrom 会话来源,openType="contact"时有效
  130 + * @property {String} sendMessageTitle 会话内消息卡片标题,openType="contact"时有效
  131 + * @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径,openType="contact"时有效
  132 + * @property {String} sendMessageImg 会话内消息卡片图片,openType="contact"时有效
  133 + * @property {Boolean} showMessageCard 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效 (默认 false )
  134 + * @property {String} appParameter 打开 APP 时,向 APP 传递的参数,openType=launchApp 时有效
  135 + *
  136 + * @event {Function} select 点击ActionSheet列表项时触发
  137 + * @event {Function} close 点击取消按钮时触发
  138 + * @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与 wx.getUserInfo 返回的一致,openType="getUserInfo"时有效
  139 + * @event {Function} contact 客服消息回调,openType="contact"时有效
  140 + * @event {Function} getphonenumber 获取用户手机号回调,openType="getPhoneNumber"时有效
  141 + * @event {Function} error 当使用开放能力时,发生错误的回调,openType="error"时有效
  142 + * @event {Function} launchapp 打开 APP 成功的回调,openType="launchApp"时有效
  143 + * @event {Function} opensetting 在打开授权设置页后回调,openType="openSetting"时有效
  144 + * @example <u-action-sheet :actions="list" :title="title" :show="show"></u-action-sheet>
  145 + */
  146 + export default {
  147 + name: "u-action-sheet",
  148 + // 一些props参数和methods方法,通过mixin混入,因为其他文件也会用到
  149 + mixins: [openType, button, uni.$u.mixin, props],
  150 + data() {
  151 + return {
  152 +
  153 + }
  154 + },
  155 + computed: {
  156 + // 操作项目的样式
  157 + itemStyle() {
  158 + return (index) => {
  159 + let style = {};
  160 + if (this.actions[index].color) style.color = this.actions[index].color
  161 + if (this.actions[index].fontSize) style.fontSize = uni.$u.addUnit(this.actions[index].fontSize)
  162 + // 选项被禁用的样式
  163 + if (this.actions[index].disabled) style.color = '#c0c4cc'
  164 + return style;
  165 + }
  166 + },
  167 + },
  168 + methods: {
  169 + closeHandler() {
  170 + // 允许点击遮罩关闭时,才发出close事件
  171 + if(this.closeOnClickOverlay) {
  172 + this.$emit('close')
  173 + }
  174 + },
  175 + // 点击取消按钮
  176 + cancel() {
  177 + this.$emit('close')
  178 + },
  179 + selectHandler(index) {
  180 + const item = this.actions[index]
  181 + if (item && !item.disabled && !item.loading) {
  182 + this.$emit('select', item)
  183 + if (this.closeOnClickAction) {
  184 + this.$emit('close')
  185 + }
  186 + }
  187 + },
  188 + }
  189 + }
  190 +</script>
  191 +
  192 +<style lang="scss" scoped>
  193 + @import "../../libs/css/components.scss";
  194 + $u-action-sheet-reset-button-width:100% !default;
  195 + $u-action-sheet-title-font-size: 16px !default;
  196 + $u-action-sheet-title-padding: 12px 30px !default;
  197 + $u-action-sheet-title-color: $u-main-color !default;
  198 + $u-action-sheet-header-icon-wrap-right:15px !default;
  199 + $u-action-sheet-header-icon-wrap-top:15px !default;
  200 + $u-action-sheet-description-font-size:13px !default;
  201 + $u-action-sheet-description-color:14px !default;
  202 + $u-action-sheet-description-margin: 18px 15px !default;
  203 + $u-action-sheet-item-wrap-item-padding:15px !default;
  204 + $u-action-sheet-item-wrap-name-font-size:16px !default;
  205 + $u-action-sheet-item-wrap-subname-font-size:13px !default;
  206 + $u-action-sheet-item-wrap-subname-color: #c0c4cc !default;
  207 + $u-action-sheet-item-wrap-subname-margin-top:10px !default;
  208 + $u-action-sheet-cancel-text-font-size:16px !default;
  209 + $u-action-sheet-cancel-text-color:$u-content-color !default;
  210 + $u-action-sheet-cancel-text-font-size:15px !default;
  211 + $u-action-sheet-cancel-text-hover-background-color:rgb(242, 243, 245) !default;
  212 +
  213 + .u-reset-button {
  214 + width: $u-action-sheet-reset-button-width;
  215 + }
  216 +
  217 + .u-action-sheet {
  218 + text-align: center;
  219 + &__header {
  220 + position: relative;
  221 + padding: $u-action-sheet-title-padding;
  222 + &__title {
  223 + font-size: $u-action-sheet-title-font-size;
  224 + color: $u-action-sheet-title-color;
  225 + font-weight: bold;
  226 + text-align: center;
  227 + }
  228 +
  229 + &__icon-wrap {
  230 + position: absolute;
  231 + right: $u-action-sheet-header-icon-wrap-right;
  232 + top: $u-action-sheet-header-icon-wrap-top;
  233 + }
  234 + }
  235 +
  236 + &__description {
  237 + font-size: $u-action-sheet-description-font-size;
  238 + color: $u-tips-color;
  239 + margin: $u-action-sheet-description-margin;
  240 + text-align: center;
  241 + }
  242 +
  243 + &__item-wrap {
  244 +
  245 + &__item {
  246 + padding: $u-action-sheet-item-wrap-item-padding;
  247 + @include flex;
  248 + align-items: center;
  249 + justify-content: center;
  250 + flex-direction: column;
  251 +
  252 + &__name {
  253 + font-size: $u-action-sheet-item-wrap-name-font-size;
  254 + color: $u-main-color;
  255 + text-align: center;
  256 + }
  257 +
  258 + &__subname {
  259 + font-size: $u-action-sheet-item-wrap-subname-font-size;
  260 + color: $u-action-sheet-item-wrap-subname-color;
  261 + margin-top: $u-action-sheet-item-wrap-subname-margin-top;
  262 + text-align: center;
  263 + }
  264 + }
  265 + }
  266 +
  267 + &__cancel-text {
  268 + font-size: $u-action-sheet-cancel-text-font-size;
  269 + color: $u-action-sheet-cancel-text-color;
  270 + text-align: center;
  271 + padding: $u-action-sheet-cancel-text-font-size;
  272 + }
  273 +
  274 + &--hover {
  275 + background-color: $u-action-sheet-cancel-text-hover-background-color;
  276 + }
  277 + }
  278 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-album/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 图片地址,Array<String>|Array<Object>形式
  4 + urls: {
  5 + type: Array,
  6 + default: uni.$u.props.album.urls
  7 + },
  8 + // 指定从数组的对象元素中读取哪个属性作为图片地址
  9 + keyName: {
  10 + type: String,
  11 + default: uni.$u.props.album.keyName
  12 + },
  13 + // 单图时,图片长边的长度
  14 + singleSize: {
  15 + type: [String, Number],
  16 + default: uni.$u.props.album.singleSize
  17 + },
  18 + // 多图时,图片边长
  19 + multipleSize: {
  20 + type: [String, Number],
  21 + default: uni.$u.props.album.multipleSize
  22 + },
  23 + // 多图时,图片水平和垂直之间的间隔
  24 + space: {
  25 + type: [String, Number],
  26 + default: uni.$u.props.album.space
  27 + },
  28 + // 单图时,图片缩放裁剪的模式
  29 + singleMode: {
  30 + type: String,
  31 + default: uni.$u.props.album.singleMode
  32 + },
  33 + // 多图时,图片缩放裁剪的模式
  34 + multipleMode: {
  35 + type: String,
  36 + default: uni.$u.props.album.multipleMode
  37 + },
  38 + // 最多展示的图片数量,超出时最后一个位置将会显示剩余图片数量
  39 + maxCount: {
  40 + type: [String, Number],
  41 + default: uni.$u.props.album.maxCount
  42 + },
  43 + // 是否可以预览图片
  44 + previewFullImage: {
  45 + type: Boolean,
  46 + default: uni.$u.props.album.previewFullImage
  47 + },
  48 + // 每行展示图片数量,如设置,singleSize和multipleSize将会无效
  49 + rowCount: {
  50 + type: [String, Number],
  51 + default: uni.$u.props.album.rowCount
  52 + },
  53 + // 超出maxCount时是否显示查看更多的提示
  54 + showMore: {
  55 + type: Boolean,
  56 + default: uni.$u.props.album.showMore
  57 + }
  58 + }
  59 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-album/u-album.vue 0 → 100644
  1 +<template>
  2 + <view class="u-album">
  3 + <view
  4 + class="u-album__row"
  5 + ref="u-album__row"
  6 + v-for="(arr, index) in showUrls"
  7 + :forComputedUse="albumWidth"
  8 + :key="index"
  9 + >
  10 + <view
  11 + class="u-album__row__wrapper"
  12 + v-for="(item, index1) in arr"
  13 + :key="index1"
  14 + :style="[imageStyle(index + 1, index1 + 1)]"
  15 + @tap="previewFullImage ? onPreviewTap(getSrc(item)) : ''"
  16 + >
  17 + <image
  18 + :src="getSrc(item)"
  19 + :mode="
  20 + urls.length === 1
  21 + ? imageHeight > 0
  22 + ? singleMode
  23 + : 'widthFix'
  24 + : multipleMode
  25 + "
  26 + :style="[
  27 + {
  28 + width: imageWidth,
  29 + height: imageHeight
  30 + }
  31 + ]"
  32 + ></image>
  33 + <view
  34 + v-if="
  35 + showMore &&
  36 + urls.length > rowCount * showUrls.length &&
  37 + index === showUrls.length - 1 &&
  38 + index1 === showUrls[showUrls.length - 1].length - 1
  39 + "
  40 + class="u-album__row__wrapper__text"
  41 + >
  42 + <u--text
  43 + :text="`+${urls.length - maxCount}`"
  44 + color="#fff"
  45 + :size="multipleSize * 0.3"
  46 + align="center"
  47 + customStyle="justify-content: center"
  48 + ></u--text>
  49 + </view>
  50 + </view>
  51 + </view>
  52 + </view>
  53 +</template>
  54 +
  55 +<script>
  56 +import props from './props.js'
  57 +// #ifdef APP-NVUE
  58 +// 由于weex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度
  59 +const dom = uni.requireNativePlugin('dom')
  60 +// #endif
  61 +
  62 +/**
  63 + * Album 相册
  64 + * @description 本组件提供一个类似相册的功能,让开发者开发起来更加得心应手。减少重复的模板代码
  65 + * @tutorial https://www.uviewui.com/components/album.html
  66 + *
  67 + * @property {Array} urls 图片地址列表 Array<String>|Array<Object>形式
  68 + * @property {String} keyName 指定从数组的对象元素中读取哪个属性作为图片地址
  69 + * @property {String | Number} singleSize 单图时,图片长边的长度 (默认 180 )
  70 + * @property {String | Number} multipleSize 多图时,图片边长 (默认 70 )
  71 + * @property {String | Number} space 多图时,图片水平和垂直之间的间隔 (默认 6 )
  72 + * @property {String} singleMode 单图时,图片缩放裁剪的模式 (默认 'scaleToFill' )
  73 + * @property {String} multipleMode 多图时,图片缩放裁剪的模式 (默认 'aspectFill' )
  74 + * @property {String | Number} maxCount 取消按钮的提示文字 (默认 9 )
  75 + * @property {Boolean} previewFullImage 是否可以预览图片 (默认 true )
  76 + * @property {String | Number} rowCount 每行展示图片数量,如设置,singleSize和multipleSize将会无效 (默认 3 )
  77 + * @property {Boolean} showMore 超出maxCount时是否显示查看更多的提示 (默认 true )
  78 + *
  79 + * @event {Function} albumWidth 某些特殊的情况下,需要让文字与相册的宽度相等,这里事件的形式对外发送 (回调参数 width )
  80 + * @example <u-album :urls="urls2" @albumWidth="width => albumWidth = width" multipleSize="68" ></u-album>
  81 + */
  82 +export default {
  83 + name: 'u-album',
  84 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  85 + data() {
  86 + return {
  87 + // 单图的宽度
  88 + singleWidth: 0,
  89 + // 单图的高度
  90 + singleHeight: 0,
  91 + // 单图时,如果无法获取图片的尺寸信息,让图片宽度默认为容器的一定百分比
  92 + singlePercent: 0.6
  93 + }
  94 + },
  95 + watch: {
  96 + urls: {
  97 + immediate: true,
  98 + handler(newVal) {
  99 + if (newVal.length === 1) {
  100 + this.getImageRect()
  101 + }
  102 + }
  103 + }
  104 + },
  105 + computed: {
  106 + imageStyle() {
  107 + return (index1, index2) => {
  108 + const { space, rowCount, multipleSize, urls } = this,
  109 + { addUnit, addStyle } = uni.$u,
  110 + rowLen = this.showUrls.length,
  111 + allLen = this.urls.length
  112 + const style = {
  113 + marginRight: addUnit(space),
  114 + marginBottom: addUnit(space)
  115 + }
  116 + // 如果为最后一行,则每个图片都无需下边框
  117 + if (index1 === rowLen) style.marginBottom = 0
  118 + // 每行的最右边一张和总长度的最后一张无需右边框
  119 + if (
  120 + index2 === rowCount ||
  121 + (index1 === rowLen &&
  122 + index2 === this.showUrls[index1 - 1].length)
  123 + )
  124 + style.marginRight = 0
  125 + return style
  126 + }
  127 + },
  128 + // 将数组划分为二维数组
  129 + showUrls() {
  130 + const arr = []
  131 + this.urls.map((item, index) => {
  132 + // 限制最大展示数量
  133 + if (index + 1 <= this.maxCount) {
  134 + // 计算该元素为第几个素组内
  135 + const itemIndex = Math.floor(index / this.rowCount)
  136 + // 判断对应的索引是否存在
  137 + if (!arr[itemIndex]) {
  138 + arr[itemIndex] = []
  139 + }
  140 + arr[itemIndex].push(item)
  141 + }
  142 + })
  143 + return arr
  144 + },
  145 + imageWidth() {
  146 + return uni.$u.addUnit(
  147 + this.urls.length === 1 ? this.singleWidth : this.multipleSize
  148 + )
  149 + },
  150 + imageHeight() {
  151 + return uni.$u.addUnit(
  152 + this.urls.length === 1 ? this.singleHeight : this.multipleSize
  153 + )
  154 + },
  155 + // 此变量无实际用途,仅仅是为了利用computed特性,让其在urls长度等变化时,重新计算图片的宽度
  156 + // 因为用户在某些特殊的情况下,需要让文字与相册的宽度相等,所以这里事件的形式对外发送
  157 + albumWidth() {
  158 + let width = 0
  159 + if (this.urls.length === 1) {
  160 + width = this.singleWidth
  161 + } else {
  162 + width =
  163 + this.showUrls[0].length * this.multipleSize +
  164 + this.space * (this.showUrls[0].length - 1)
  165 + }
  166 + this.$emit('albumWidth', width)
  167 + return width
  168 + }
  169 + },
  170 + methods: {
  171 + // 预览图片
  172 + onPreviewTap(url) {
  173 + const urls = this.urls.map((item) => {
  174 + return this.getSrc(item)
  175 + })
  176 + uni.previewImage({
  177 + current: url,
  178 + urls
  179 + })
  180 + },
  181 + // 获取图片的路径
  182 + getSrc(item) {
  183 + return uni.$u.test.object(item)
  184 + ? (this.keyName && item[this.keyName]) || item.src
  185 + : item
  186 + },
  187 + // 单图时,获取图片的尺寸
  188 + // 在小程序中,需要将网络图片的的域名添加到小程序的download域名才可能获取尺寸
  189 + // 在没有添加的情况下,让单图宽度默认为盒子的一定宽度(singlePercent)
  190 + getImageRect() {
  191 + const src = this.getSrc(this.urls[0])
  192 + uni.getImageInfo({
  193 + src,
  194 + success: (res) => {
  195 + // 判断图片横向还是竖向展示方式
  196 + const isHorizotal = res.width >= res.height
  197 + this.singleWidth = isHorizotal
  198 + ? this.singleSize
  199 + : (res.width / res.height) * this.singleSize
  200 + this.singleHeight = !isHorizotal
  201 + ? this.singleSize
  202 + : (res.height / res.width) * this.singleWidth
  203 + },
  204 + fail: () => {
  205 + this.getComponentWidth()
  206 + }
  207 + })
  208 + },
  209 + // 获取组件的宽度
  210 + async getComponentWidth() {
  211 + // 延时一定时间,以获取dom尺寸
  212 + await uni.$u.sleep(30)
  213 + // #ifndef APP-NVUE
  214 + this.$uGetRect('.u-album__row').then((size) => {
  215 + this.singleWidth = size.width * this.singlePercent
  216 + })
  217 + // #endif
  218 +
  219 + // #ifdef APP-NVUE
  220 + // 这里ref="u-album__row"所在的标签为通过for循环出来,导致this.$refs['u-album__row']是一个数组
  221 + const ref = this.$refs['u-album__row'][0]
  222 + ref &&
  223 + dom.getComponentRect(ref, (res) => {
  224 + this.singleWidth = res.size.width * this.singlePercent
  225 + })
  226 + // #endif
  227 + }
  228 + }
  229 +}
  230 +</script>
  231 +
  232 +<style lang="scss" scoped>
  233 +@import '../../libs/css/components.scss';
  234 +
  235 +.u-album {
  236 + @include flex(column);
  237 +
  238 + &__row {
  239 + @include flex(row);
  240 + flex-wrap: wrap;
  241 +
  242 + &__wrapper {
  243 + position: relative;
  244 +
  245 + &__text {
  246 + position: absolute;
  247 + top: 0;
  248 + left: 0;
  249 + right: 0;
  250 + bottom: 0;
  251 + background-color: rgba(0, 0, 0, 0.3);
  252 + @include flex(row);
  253 + justify-content: center;
  254 + align-items: center;
  255 + }
  256 + }
  257 + }
  258 +}
  259 +</style>
0 260 \ No newline at end of file
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-alert/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 显示文字
  4 + title: {
  5 + type: String,
  6 + default: uni.$u.props.alert.title
  7 + },
  8 + // 主题,success/warning/info/error
  9 + type: {
  10 + type: String,
  11 + default: uni.$u.props.alert.type
  12 + },
  13 + // 辅助性文字
  14 + description: {
  15 + type: String,
  16 + default: uni.$u.props.alert.description
  17 + },
  18 + // 是否可关闭
  19 + closable: {
  20 + type: Boolean,
  21 + default: uni.$u.props.alert.closable
  22 + },
  23 + // 是否显示图标
  24 + showIcon: {
  25 + type: Boolean,
  26 + default: uni.$u.props.alert.showIcon
  27 + },
  28 + // 浅或深色调,light-浅色,dark-深色
  29 + effect: {
  30 + type: String,
  31 + default: uni.$u.props.alert.effect
  32 + },
  33 + // 文字是否居中
  34 + center: {
  35 + type: Boolean,
  36 + default: uni.$u.props.alert.center
  37 + },
  38 + // 字体大小
  39 + fontSize: {
  40 + type: [String, Number],
  41 + default: uni.$u.props.alert.fontSize
  42 + }
  43 + }
  44 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-alert/u-alert.vue 0 → 100644
  1 +<template>
  2 + <u-transition
  3 + mode="fade"
  4 + :show="show"
  5 + >
  6 + <view
  7 + class="u-alert"
  8 + :class="[`u-alert--${type}--${effect}`]"
  9 + @tap.stop="clickHandler"
  10 + :style="[$u.addStyle(customStyle)]"
  11 + >
  12 + <view
  13 + class="u-alert__icon"
  14 + v-if="showIcon"
  15 + >
  16 + <u-icon
  17 + :name="iconName"
  18 + size="18"
  19 + :color="iconColor"
  20 + ></u-icon>
  21 + </view>
  22 + <view
  23 + class="u-alert__content"
  24 + :style="[{
  25 + paddingRight: closable ? '20px' : 0
  26 + }]"
  27 + >
  28 + <text
  29 + class="u-alert__content__title"
  30 + v-if="title"
  31 + :style="[{
  32 + fontSize: $u.addUnit(fontSize),
  33 + textAlign: center ? 'center' : 'left'
  34 + }]"
  35 + :class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
  36 + >{{ title }}</text>
  37 + <text
  38 + class="u-alert__content__desc"
  39 + v-if="description"
  40 + :style="[{
  41 + fontSize: $u.addUnit(fontSize),
  42 + textAlign: center ? 'center' : 'left'
  43 + }]"
  44 + :class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
  45 + >{{ description }}</text>
  46 + </view>
  47 + <view
  48 + class="u-alert__close"
  49 + v-if="closable"
  50 + @tap.stop="closeHandler"
  51 + >
  52 + <u-icon
  53 + name="close"
  54 + :color="iconColor"
  55 + size="15"
  56 + ></u-icon>
  57 + </view>
  58 + </view>
  59 + </u-transition>
  60 +</template>
  61 +
  62 +<script>
  63 + import props from './props.js';
  64 + /**
  65 + * Alert 警告提示
  66 + * @description 警告提示,展现需要关注的信息。
  67 + * @tutorial https://www.uviewui.com/components/alertTips.html
  68 + *
  69 + * @property {String} title 显示的文字
  70 + * @property {String} type 使用预设的颜色 (默认 'warning' )
  71 + * @property {String} description 辅助性文字,颜色比title浅一点,字号也小一点,可选
  72 + * @property {Boolean} closable 关闭按钮(默认为叉号icon图标) (默认 false )
  73 + * @property {Boolean} showIcon 是否显示左边的辅助图标 ( 默认 false )
  74 + * @property {String} effect 多图时,图片缩放裁剪的模式 (默认 'light' )
  75 + * @property {Boolean} center 文字是否居中 (默认 false )
  76 + * @property {String | Number} fontSize 字体大小 (默认 14 )
  77 + * @property {Object} customStyle 定义需要用到的外部样式
  78 + * @event {Function} click 点击组件时触发
  79 + * @example <u-alert :title="title" type = "warning" :closable="closable" :description = "description"></u-alert>
  80 + */
  81 + export default {
  82 + name: 'u-alert',
  83 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  84 + data() {
  85 + return {
  86 + show: true
  87 + }
  88 + },
  89 + computed: {
  90 + iconColor() {
  91 + return this.effect === 'light' ? this.type : '#fff'
  92 + },
  93 + // 不同主题对应不同的图标
  94 + iconName() {
  95 + switch (this.type) {
  96 + case 'success':
  97 + return 'checkmark-circle-fill';
  98 + break;
  99 + case 'error':
  100 + return 'close-circle-fill';
  101 + break;
  102 + case 'warning':
  103 + return 'error-circle-fill';
  104 + break;
  105 + case 'info':
  106 + return 'info-circle-fill';
  107 + break;
  108 + case 'primary':
  109 + return 'more-circle-fill';
  110 + break;
  111 + default:
  112 + return 'error-circle-fill';
  113 + }
  114 + }
  115 + },
  116 + methods: {
  117 + // 点击内容
  118 + clickHandler() {
  119 + this.$emit('click')
  120 + },
  121 + // 点击关闭按钮
  122 + closeHandler() {
  123 + this.show = false
  124 + }
  125 + }
  126 + }
  127 +</script>
  128 +
  129 +<style lang="scss" scoped>
  130 + @import "../../libs/css/components.scss";
  131 +
  132 + .u-alert {
  133 + position: relative;
  134 + background-color: $u-primary;
  135 + padding: 8px 10px;
  136 + @include flex(row);
  137 + align-items: center;
  138 + border-top-left-radius: 4px;
  139 + border-top-right-radius: 4px;
  140 + border-bottom-left-radius: 4px;
  141 + border-bottom-right-radius: 4px;
  142 +
  143 + &--primary--dark {
  144 + background-color: $u-primary;
  145 + }
  146 +
  147 + &--primary--light {
  148 + background-color: #ecf5ff;
  149 + }
  150 +
  151 + &--error--dark {
  152 + background-color: $u-error;
  153 + }
  154 +
  155 + &--error--light {
  156 + background-color: #FEF0F0;
  157 + }
  158 +
  159 + &--success--dark {
  160 + background-color: $u-success;
  161 + }
  162 +
  163 + &--success--light {
  164 + background-color: #f5fff0;
  165 + }
  166 +
  167 + &--warning--dark {
  168 + background-color: $u-warning;
  169 + }
  170 +
  171 + &--warning--light {
  172 + background-color: #FDF6EC;
  173 + }
  174 +
  175 + &--info--dark {
  176 + background-color: $u-info;
  177 + }
  178 +
  179 + &--info--light {
  180 + background-color: #f4f4f5;
  181 + }
  182 +
  183 + &__icon {
  184 + margin-right: 5px;
  185 + }
  186 +
  187 + &__content {
  188 + @include flex(column);
  189 + flex: 1;
  190 +
  191 + &__title {
  192 + color: $u-main-color;
  193 + font-size: 14px;
  194 + font-weight: bold;
  195 + color: #fff;
  196 + margin-bottom: 2px;
  197 + }
  198 +
  199 + &__desc {
  200 + color: $u-main-color;
  201 + font-size: 14px;
  202 + flex-wrap: wrap;
  203 + color: #fff;
  204 + }
  205 + }
  206 +
  207 + &__title--dark,
  208 + &__desc--dark {
  209 + color: #FFFFFF;
  210 + }
  211 +
  212 + &__text--primary--light,
  213 + &__text--primary--light {
  214 + color: $u-primary;
  215 + }
  216 +
  217 + &__text--success--light,
  218 + &__text--success--light {
  219 + color: $u-success;
  220 + }
  221 +
  222 + &__text--warning--light,
  223 + &__text--warning--light {
  224 + color: $u-warning;
  225 + }
  226 +
  227 + &__text--error--light,
  228 + &__text--error--light {
  229 + color: $u-error;
  230 + }
  231 +
  232 + &__text--info--light,
  233 + &__text--info--light {
  234 + color: $u-info;
  235 + }
  236 +
  237 + &__close {
  238 + position: absolute;
  239 + top: 11px;
  240 + right: 10px;
  241 + }
  242 + }
  243 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-avatar-group/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 头像图片组
  4 + urls: {
  5 + type: Array,
  6 + default: uni.$u.props.avatarGroup.urls
  7 + },
  8 + // 最多展示的头像数量
  9 + maxCount: {
  10 + type: [String, Number],
  11 + default: uni.$u.props.avatarGroup.maxCount
  12 + },
  13 + // 头像形状
  14 + shape: {
  15 + type: String,
  16 + default: uni.$u.props.avatarGroup.shape
  17 + },
  18 + // 图片裁剪模式
  19 + mode: {
  20 + type: String,
  21 + default: uni.$u.props.avatarGroup.mode
  22 + },
  23 + // 超出maxCount时是否显示查看更多的提示
  24 + showMore: {
  25 + type: Boolean,
  26 + default: uni.$u.props.avatarGroup.showMore
  27 + },
  28 + // 头像大小
  29 + size: {
  30 + type: [String, Number],
  31 + default: uni.$u.props.avatarGroup.size
  32 + },
  33 + // 指定从数组的对象元素中读取哪个属性作为图片地址
  34 + keyName: {
  35 + type: String,
  36 + default: uni.$u.props.avatarGroup.keyName
  37 + },
  38 + // 头像之间的遮挡比例
  39 + gap: {
  40 + type: [String, Number],
  41 + validator(value) {
  42 + return value >= 0 && value <= 1
  43 + },
  44 + default: uni.$u.props.avatarGroup.gap
  45 + },
  46 + // 需额外显示的值
  47 + extraValue: {
  48 + type: [Number, String],
  49 + default: uni.$u.props.avatarGroup.extraValue
  50 + }
  51 + }
  52 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-avatar-group/u-avatar-group.vue 0 → 100644
  1 +<template>
  2 + <view class="u-avatar-group">
  3 + <view
  4 + class="u-avatar-group__item"
  5 + v-for="(item, index) in showUrl"
  6 + :key="index"
  7 + :style="{
  8 + marginLeft: index === 0 ? 0 : $u.addUnit(-size * gap)
  9 + }"
  10 + >
  11 + <u-avatar
  12 + :size="size"
  13 + :shape="shape"
  14 + :mode="mode"
  15 + :src="$u.test.object(item) ? keyName && item[keyName] || item.url : item"
  16 + ></u-avatar>
  17 + <view
  18 + class="u-avatar-group__item__show-more"
  19 + v-if="showMore && index === showUrl.length - 1 && (urls.length > maxCount || extraValue > 0)"
  20 + @tap="clickHandler"
  21 + >
  22 + <u--text
  23 + color="#ffffff"
  24 + :size="size * 0.4"
  25 + :text="`+${extraValue || urls.length - showUrl.length}`"
  26 + align="center"
  27 + customStyle="justify-content: center"
  28 + ></u--text>
  29 + </view>
  30 + </view>
  31 + </view>
  32 +</template>
  33 +
  34 +<script>
  35 + import props from './props.js';
  36 + /**
  37 + * AvatarGroup 头像组
  38 + * @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
  39 + * @tutorial https://www.uviewui.com/components/avatar.html
  40 + *
  41 + * @property {Array} urls 头像图片组 (默认 [] )
  42 + * @property {String | Number} maxCount 最多展示的头像数量 ( 默认 5 )
  43 + * @property {String} shape 头像形状( 'circle' (默认) | 'square' )
  44 + * @property {String} mode 图片裁剪模式(默认 'scaleToFill' )
  45 + * @property {Boolean} showMore 超出maxCount时是否显示查看更多的提示 (默认 true )
  46 + * @property {String | Number} size 头像大小 (默认 40 )
  47 + * @property {String} keyName 指定从数组的对象元素中读取哪个属性作为图片地址
  48 + * @property {String | Number} gap 头像之间的遮挡比例(0.4代表遮挡40%) (默认 0.5 )
  49 + * @property {String | Number} extraValue 需额外显示的值
  50 + * @event {Function} showMore 头像组更多点击
  51 + * @example <u-avatar-group:urls="urls" size="35" gap="0.4" ></u-avatar-group:urls=>
  52 + */
  53 + export default {
  54 + name: 'u-avatar-group',
  55 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  56 + data() {
  57 + return {
  58 +
  59 + }
  60 + },
  61 + computed: {
  62 + showUrl() {
  63 + return this.urls.slice(0, this.maxCount)
  64 + }
  65 + },
  66 + methods: {
  67 + clickHandler() {
  68 + this.$emit('showMore')
  69 + }
  70 + },
  71 + }
  72 +</script>
  73 +
  74 +<style lang="scss" scoped>
  75 + @import "../../libs/css/components.scss";
  76 +
  77 + .u-avatar-group {
  78 + @include flex;
  79 +
  80 + &__item {
  81 + margin-left: -10px;
  82 + position: relative;
  83 +
  84 + &--no-indent {
  85 + // 如果你想质疑作者不会使用:first-child,说明你太年轻,因为nvue不支持
  86 + margin-left: 0;
  87 + }
  88 +
  89 + &__show-more {
  90 + position: absolute;
  91 + top: 0;
  92 + bottom: 0;
  93 + left: 0;
  94 + right: 0;
  95 + background-color: rgba(0, 0, 0, 0.3);
  96 + @include flex;
  97 + align-items: center;
  98 + justify-content: center;
  99 + border-radius: 100px;
  100 + }
  101 + }
  102 + }
  103 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-avatar/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 头像图片路径(不能为相对路径)
  4 + src: {
  5 + type: String,
  6 + default: uni.$u.props.avatar.src
  7 + },
  8 + // 头像形状,circle-圆形,square-方形
  9 + shape: {
  10 + type: String,
  11 + default: uni.$u.props.avatar.shape
  12 + },
  13 + // 头像尺寸
  14 + size: {
  15 + type: [String, Number],
  16 + default: uni.$u.props.avatar.size
  17 + },
  18 + // 裁剪模式
  19 + mode: {
  20 + type: String,
  21 + default: uni.$u.props.avatar.mode
  22 + },
  23 + // 显示的文字
  24 + text: {
  25 + type: String,
  26 + default: uni.$u.props.avatar.text
  27 + },
  28 + // 背景色
  29 + bgColor: {
  30 + type: String,
  31 + default: uni.$u.props.avatar.bgColor
  32 + },
  33 + // 文字颜色
  34 + color: {
  35 + type: String,
  36 + default: uni.$u.props.avatar.color
  37 + },
  38 + // 文字大小
  39 + fontSize: {
  40 + type: [String, Number],
  41 + default: uni.$u.props.avatar.fontSize
  42 + },
  43 + // 显示的图标
  44 + icon: {
  45 + type: String,
  46 + default: uni.$u.props.avatar.icon
  47 + },
  48 + // 显示小程序头像,只对百度,微信,QQ小程序有效
  49 + mpAvatar: {
  50 + type: Boolean,
  51 + default: uni.$u.props.avatar.mpAvatar
  52 + },
  53 + // 是否使用随机背景色
  54 + randomBgColor: {
  55 + type: Boolean,
  56 + default: uni.$u.props.avatar.randomBgColor
  57 + },
  58 + // 加载失败的默认头像(组件有内置默认图片)
  59 + defaultUrl: {
  60 + type: String,
  61 + default: uni.$u.props.avatar.defaultUrl
  62 + },
  63 + // 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
  64 + colorIndex: {
  65 + type: [String, Number],
  66 + // 校验参数规则,索引在0-19之间
  67 + validator(n) {
  68 + return uni.$u.test.range(n, [0, 19]) || n === ''
  69 + },
  70 + default: uni.$u.props.avatar.colorIndex
  71 + },
  72 + // 组件标识符
  73 + name: {
  74 + type: String,
  75 + default: uni.$u.props.avatar.name
  76 + }
  77 + }
  78 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-avatar/u-avatar.vue 0 → 100644
  1 +<template>
  2 + <view
  3 + class="u-avatar"
  4 + :class="[`u-avatar--${shape}`]"
  5 + :style="[{
  6 + backgroundColor: (text || icon) ? (randomBgColor ? colors[colorIndex !== '' ? colorIndex : $u.random(0, 19)] : bgColor) : 'transparent',
  7 + width: $u.addUnit(size),
  8 + height: $u.addUnit(size),
  9 + }, $u.addStyle(customStyle)]"
  10 + @tap="clickHandler"
  11 + >
  12 + <slot>
  13 + <!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU -->
  14 + <open-data
  15 + v-if="mpAvatar && allowMp"
  16 + type="userAvatarUrl"
  17 + :style="[{
  18 + width: $u.addUnit(size),
  19 + height: $u.addUnit(size)
  20 + }]"
  21 + />
  22 + <!-- #endif -->
  23 + <!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU -->
  24 + <template v-if="mpAvatar && allowMp"></template>
  25 + <!-- #endif -->
  26 + <u-icon
  27 + v-else-if="icon"
  28 + :name="icon"
  29 + :size="fontSize"
  30 + :color="color"
  31 + ></u-icon>
  32 + <u--text
  33 + v-else-if="text"
  34 + :text="text"
  35 + :size="fontSize"
  36 + :color="color"
  37 + align="center"
  38 + customStyle="justify-content: center"
  39 + ></u--text>
  40 + <image
  41 + class="u-avatar__image"
  42 + v-else
  43 + :class="[`u-avatar__image--${shape}`]"
  44 + :src="avatarUrl || defaultUrl"
  45 + :mode="mode"
  46 + @error="errorHandler"
  47 + :style="[{
  48 + width: $u.addUnit(size),
  49 + height: $u.addUnit(size)
  50 + }]"
  51 + ></image>
  52 + </slot>
  53 + </view>
  54 +</template>
  55 +
  56 +<script>
  57 + import props from './props.js';
  58 + const base64Avatar =
  59 + "data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjREMEQwRkY0RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjREMEQwRkY1RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NEQwRDBGRjJGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEQwRDBGRjNGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYGCAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8fAQcHBw0MDRgQEBgaFREVGh8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx//wAARCADIAMgDAREAAhEBAxEB/8QAcQABAQEAAwEBAAAAAAAAAAAAAAUEAQMGAgcBAQAAAAAAAAAAAAAAAAAAAAAQAAIBAwICBgkDBQAAAAAAAAABAhEDBCEFMVFBYXGREiKBscHRMkJSEyOh4XLxYjNDFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A/fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHbHFyZ/Dam+yLA+Z2L0Pjtyj2poD4AAAAAAAAAAAAAAAAAAAAAAAAKWFs9y6lcvvwQeqj8z9wFaziY1n/HbUX9XF97A7QAGXI23EvJ1goyfzR0YEfN269jeZ+a03pNe0DIAAAAAAAAAAAAAAAAAAAACvtO3RcVkXlWutuL9YFYAAAAAOJRjKLjJVi9GmB5/csH/mu1h/in8PU+QGMAAAAAAAAAAAAAAAAAAaMDG/6MmMH8C80+xAelSSVFolwQAAAAAAAHVlWI37ErUulaPk+hgeYnCUJuElSUXRrrQHAAAAAAAAAAAAAAAAABa2Oz4bM7r4zdF2ICmAAAAAAAAAg7zZ8GX41wuJP0rRgYAAAAAAAAAAAAAAAAAD0m2R8ODaXU33tsDSAAAAAAAAAlb9HyWZcnJd9PcBHAAAAAAAAAAAAAAAAAPS7e64Vn+KA0AAAAAAAAAJm+v8Ftf3ewCKAAAAAAAAAAAAAAAAAX9muqeGo9NttP06+0DcAAAAAAAAAjb7dTu2ra+VOT9P8AQCWAAAAAAAAAAAAAAAAAUNmyPt5Ltv4bui/kuAF0AAAAAAADiUlGLlJ0SVW+oDzOXfd/Ind6JPRdS0QHSAAAAAAAAAAAAAAAAAE2nVaNcGB6Lbs6OTao9LsF51z60BrAAAAAABJ3jOVHjW3r/sa9QEgAAAAAAAAAAAAAAAAAAAPu1duWriuW34ZR4MC9hbnZyEoy8l36XwfYBsAAADaSq9EuLAlZ+7xSdrGdW9Hc5dgEdtt1erfFgAAAAAAAAAAAAAAAAADVjbblX6NR8MH80tEBRs7HYivyzlN8lovaBPzduvY0m6eK10TXtAyAarO55lpJK54orolr+4GqO/Xaea1FvqbXvA+Z77kNeW3GPbV+4DJfzcm/pcm3H6Vou5AdAFLC2ed2Pjv1txa8sV8T6wOL+yZEKu1JXFy4MDBOE4ScZxcZLinoB8gAAAAAAAAAAAB242LeyJ+C3GvN9C7QLmJtePYpKS+5c+p8F2IDYAANJqj1T4oCfk7Nj3G5Wn9qXJax7gJ93Z82D8sVNc4v30A6Xg5i42Z+iLfqARwcyT0sz9MWvWBps7LlTf5Grce9/oBTxdtxseklHxT+uWr9AGoAB138ezfj4bsFJdD6V2MCPm7RdtJzs1uW1xXzL3gTgAAAAAAAAADRhYc8q74I6RWs5ckB6GxYtWLat21SK731sDsAAAAAAAAAAAAAAAASt021NO/YjrxuQXT1oCOAAAAAAABzGLlJRSq26JAelwsWONYjbXxcZvmwO8AAAAAAAAAAAAAAAAAAef3TEWPkVivx3NY9T6UBiAAAAAABo2+VmGXblddIJ8eivRUD0oAAAAAAAAAAAAAAAAAAAYt4tKeFKVNYNSXfRgefAAAAAAAAr7VuSSWPedKaW5v1MCsAAAAAAAAAAAAAAAAAAIe6bj96Ts2n+JPzSXzP3ATgAAAAAAAAFbbt1UUrOQ9FpC4/UwK6aaqtU+DAAAAAAAAAAAAAAA4lKMIuUmoxWrb4ARNx3R3q2rLpa4Sl0y/YCcAAAAAAAAAAANmFud7G8r89r6X0dgFvGzLGRGtuWvTF6NAdwAAAAAAAAAAAy5W442PVN+K59EePp5ARMvOv5MvO6QXCC4AZwAAAAAAAAAAAAAcxlKLUotprg1owN+PvORborq+7Hnwl3gUbO74VzRydt8pKn68ANcJwmqwkpLmnUDkAAAAfNy9atqtyagut0AxXt5xIV8Fbj6lRd7Am5G65V6qUvtwfyx94GMAAAAAAAAAAAAAAAAAAAOU2nVOj5gdsc3LiqRvTpyqwOxbnnrhdfpSfrQB7pnv/AGvuS9gHXPMy5/Fem1yq0v0A6W29XqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//Z";
  60 + /**
  61 + * Avatar 头像
  62 + * @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
  63 + * @tutorial https://www.uviewui.com/components/avatar.html
  64 + *
  65 + * @property {String} src 头像路径,如加载失败,将会显示默认头像(不能为相对路径)
  66 + * @property {String} shape 头像形状 ( circle (默认) | square)
  67 + * @property {String | Number} size 头像尺寸,可以为指定字符串(large, default, mini),或者数值 (默认 40 )
  68 + * @property {String} mode 头像图片的裁剪类型,与uni的image组件的mode参数一致,如效果达不到需求,可尝试传widthFix值 (默认 'scaleToFill' )
  69 + * @property {String} text 用文字替代图片,级别优先于src
  70 + * @property {String} bgColor 背景颜色,一般显示文字时用 (默认 '#c0c4cc' )
  71 + * @property {String} color 文字颜色 (默认 '#ffffff' )
  72 + * @property {String | Number} fontSize 文字大小 (默认 18 )
  73 + * @property {String} icon 显示的图标
  74 + * @property {Boolean} mpAvatar 显示小程序头像,只对百度,微信,QQ小程序有效 (默认 false )
  75 + * @property {Boolean} randomBgColor 是否使用随机背景色 (默认 false )
  76 + * @property {String} defaultUrl 加载失败的默认头像(组件有内置默认图片)
  77 + * @property {String | Number} colorIndex 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
  78 + * @property {String} name 组件标识符 (默认 'level' )
  79 + * @property {Object} customStyle 定义需要用到的外部样式
  80 + *
  81 + * @event {Function} click 点击组件时触发 index: 用户传递的标识符
  82 + * @example <u-avatar :src="src" mode="square"></u-avatar>
  83 + */
  84 + export default {
  85 + name: 'u-avatar',
  86 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  87 + data() {
  88 + return {
  89 + // 如果配置randomBgColor参数为true,在图标或者文字的模式下,会随机从中取出一个颜色值当做背景色
  90 + colors: ['#ffb34b', '#f2bba9', '#f7a196', '#f18080', '#88a867', '#bfbf39', '#89c152', '#94d554', '#f19ec2',
  91 + '#afaae4', '#e1b0df', '#c38cc1', '#72dcdc', '#9acdcb', '#77b1cc', '#448aca', '#86cefa', '#98d1ee',
  92 + '#73d1f1',
  93 + '#80a7dc'
  94 + ],
  95 + avatarUrl: this.src,
  96 + allowMp: false
  97 + }
  98 + },
  99 + watch: {
  100 + // 监听头像src的变化,赋值给内部的avatarUrl变量,因为图片加载失败时,需要修改图片的src为默认值
  101 + // 而组件内部不能直接修改props的值,所以需要一个中间变量
  102 + src: {
  103 + immediate: true,
  104 + handler(newVal) {
  105 + this.avatarUrl = newVal
  106 + // 如果没有传src,则主动触发error事件,用于显示默认的头像,否则src为''空字符等的时候,会无内容展示
  107 + if(!newVal) {
  108 + this.errorHandler()
  109 + }
  110 + }
  111 + }
  112 + },
  113 + computed: {
  114 + imageStyle() {
  115 + const style = {}
  116 + return style
  117 + }
  118 + },
  119 + created() {
  120 + this.init()
  121 + },
  122 + methods: {
  123 + init() {
  124 + // 目前只有这几个小程序平台具有open-data标签
  125 + // 其他平台可以通过uni.getUserInfo类似接口获取信息,但是需要弹窗授权(首次),不合符组件逻辑
  126 + // 故目前自动获取小程序头像只支持这几个平台
  127 + // #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU
  128 + this.allowMp = true
  129 + // #endif
  130 + },
  131 + // 判断传入的name属性,是否图片路径,只要带有"/"均认为是图片形式
  132 + isImg() {
  133 + return this.src.indexOf('/') !== -1
  134 + },
  135 + // 图片加载时失败时触发
  136 + errorHandler() {
  137 + this.avatarUrl = this.defaultUrl || base64Avatar
  138 + },
  139 + clickHandler() {
  140 + this.$emit('click', this.name)
  141 + }
  142 + }
  143 + }
  144 +</script>
  145 +
  146 +<style lang="scss" scoped>
  147 + @import "../../libs/css/components.scss";
  148 +
  149 + .u-avatar {
  150 + @include flex;
  151 + align-items: center;
  152 + justify-content: center;
  153 +
  154 + &--circle {
  155 + border-radius: 100px;
  156 + }
  157 +
  158 + &--square {
  159 + border-radius: 4px;
  160 + }
  161 +
  162 + &__image {
  163 + &--circle {
  164 + border-radius: 100px;
  165 + }
  166 +
  167 + &--square {
  168 + border-radius: 4px;
  169 + }
  170 + }
  171 + }
  172 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-back-top/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 返回顶部的形状,circle-圆形,square-方形
  4 + mode: {
  5 + type: String,
  6 + default: uni.$u.props.backtop.mode
  7 + },
  8 + // 自定义图标
  9 + icon: {
  10 + type: String,
  11 + default: uni.$u.props.backtop.icon
  12 + },
  13 + // 提示文字
  14 + text: {
  15 + type: String,
  16 + default: uni.$u.props.backtop.text
  17 + },
  18 + // 返回顶部滚动时间
  19 + duration: {
  20 + type: [String, Number],
  21 + default: uni.$u.props.backtop.duration
  22 + },
  23 + // 滚动距离
  24 + scrollTop: {
  25 + type: [String, Number],
  26 + default: uni.$u.props.backtop.scrollTop
  27 + },
  28 + // 距离顶部多少距离显示,单位px
  29 + top: {
  30 + type: [String, Number],
  31 + default: uni.$u.props.backtop.top
  32 + },
  33 + // 返回顶部按钮到底部的距离,单位px
  34 + bottom: {
  35 + type: [String, Number],
  36 + default: uni.$u.props.backtop.bottom
  37 + },
  38 + // 返回顶部按钮到右边的距离,单位px
  39 + right: {
  40 + type: [String, Number],
  41 + default: uni.$u.props.backtop.right
  42 + },
  43 + // 层级
  44 + zIndex: {
  45 + type: [String, Number],
  46 + default: uni.$u.props.backtop.zIndex
  47 + },
  48 + // 图标的样式,对象形式
  49 + iconStyle: {
  50 + type: Object,
  51 + default: uni.$u.props.backtop.iconStyle
  52 + }
  53 + }
  54 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-back-top/u-back-top.vue 0 → 100644
  1 +<template>
  2 + <u-transition
  3 + mode="fade"
  4 + :customStyle="backTopStyle"
  5 + :show="show"
  6 + >
  7 + <view
  8 + class="u-back-top"
  9 + :style="[contentStyle]"
  10 + v-if="!$slots.default && !$slots.$default"
  11 + @click="backToTop"
  12 + >
  13 + <u-icon
  14 + :name="icon"
  15 + :custom-style="iconStyle"
  16 + ></u-icon>
  17 + <text
  18 + v-if="text"
  19 + class="u-back-top__text"
  20 + >{{text}}</text>
  21 + </view>
  22 + <slot v-else />
  23 + </u-transition>
  24 +</template>
  25 +
  26 +<script>
  27 + import props from './props.js';
  28 + // #ifdef APP-NVUE
  29 + const dom = weex.requireModule('dom')
  30 + // #endif
  31 + /**
  32 + * backTop 返回顶部
  33 + * @description 本组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。
  34 + * @tutorial https://uviewui.com/components/backTop.html
  35 + *
  36 + * @property {String} mode 返回顶部的形状,circle-圆形,square-方形 (默认 'circle' )
  37 + * @property {String} icon 自定义图标 (默认 'arrow-upward' ) 见官方文档示例
  38 + * @property {String} text 提示文字
  39 + * @property {String | Number} duration 返回顶部滚动时间 (默认 100)
  40 + * @property {String | Number} scrollTop 滚动距离 (默认 0 )
  41 + * @property {String | Number} top 距离顶部多少距离显示,单位px (默认 400 )
  42 + * @property {String | Number} bottom 返回顶部按钮到底部的距离,单位px (默认 100 )
  43 + * @property {String | Number} right 返回顶部按钮到右边的距离,单位px (默认 20 )
  44 + * @property {String | Number} zIndex 层级 (默认 9 )
  45 + * @property {Object<Object>} iconStyle 图标的样式,对象形式 (默认 {color: '#909399',fontSize: '19px'})
  46 + * @property {Object} customStyle 定义需要用到的外部样式
  47 + *
  48 + * @example <u-back-top :scrollTop="scrollTop"></u-back-top>
  49 + */
  50 + export default {
  51 + name: 'u-back-top',
  52 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  53 + computed: {
  54 + backTopStyle() {
  55 + // 动画组件样式
  56 + const style = {
  57 + bottom: uni.$u.addUnit(this.bottom),
  58 + right: uni.$u.addUnit(this.right),
  59 + width: '40px',
  60 + height: '40px',
  61 + position: 'fixed',
  62 + zIndex: 10,
  63 + }
  64 + return style
  65 + },
  66 + show() {
  67 + return uni.$u.getPx(this.scrollTop) > uni.$u.getPx(this.top)
  68 + },
  69 + contentStyle() {
  70 + const style = {}
  71 + let radius = 0
  72 + // 是否圆形
  73 + if(this.mode === 'circle') {
  74 + radius = '100px'
  75 + } else {
  76 + radius = '4px'
  77 + }
  78 + // 为了兼容安卓nvue,只能这么分开写
  79 + style.borderTopLeftRadius = radius
  80 + style.borderTopRightRadius = radius
  81 + style.borderBottomLeftRadius = radius
  82 + style.borderBottomRightRadius = radius
  83 + return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
  84 + }
  85 + },
  86 + methods: {
  87 + backToTop() {
  88 + // #ifdef APP-NVUE
  89 + if (!this.$parent.$refs['u-back-top']) {
  90 + uni.$u.error(`nvue页面需要给页面最外层元素设置"ref='u-back-top'`)
  91 + }
  92 + dom.scrollToElement(this.$parent.$refs['u-back-top'], {
  93 + offset: 0
  94 + })
  95 + // #endif
  96 +
  97 + // #ifndef APP-NVUE
  98 + uni.pageScrollTo({
  99 + scrollTop: 0,
  100 + duration: this.duration
  101 + });
  102 + // #endif
  103 + this.$emit('click')
  104 + }
  105 + }
  106 + }
  107 +</script>
  108 +
  109 +<style lang="scss" scoped>
  110 + @import '../../libs/css/components.scss';
  111 + $u-back-top-flex:1 !default;
  112 + $u-back-top-height:100% !default;
  113 + $u-back-top-background-color:#E1E1E1 !default;
  114 + $u-back-top-tips-font-size:12px !default;
  115 + .u-back-top {
  116 + @include flex;
  117 + flex-direction: column;
  118 + align-items: center;
  119 + flex:$u-back-top-flex;
  120 + height: $u-back-top-height;
  121 + justify-content: center;
  122 + background-color: $u-back-top-background-color;
  123 +
  124 + &__tips {
  125 + font-size:$u-back-top-tips-font-size;
  126 + transform: scale(0.8);
  127 + }
  128 + }
  129 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-badge/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 是否显示圆点
  4 + isDot: {
  5 + type: Boolean,
  6 + default: uni.$u.props.badge.isDot
  7 + },
  8 + // 显示的内容
  9 + value: {
  10 + type: [Number, String],
  11 + default: uni.$u.props.badge.value
  12 + },
  13 + // 是否显示
  14 + show: {
  15 + type: Boolean,
  16 + default: uni.$u.props.badge.show
  17 + },
  18 + // 最大值,超过最大值会显示 '{max}+'
  19 + max: {
  20 + type: [Number, String],
  21 + default: uni.$u.props.badge.max
  22 + },
  23 + // 主题类型,error|warning|success|primary
  24 + type: {
  25 + type: String,
  26 + default: uni.$u.props.badge.type
  27 + },
  28 + // 当数值为 0 时,是否展示 Badge
  29 + showZero: {
  30 + type: Boolean,
  31 + default: uni.$u.props.badge.showZero
  32 + },
  33 + // 背景颜色,优先级比type高,如设置,type参数会失效
  34 + bgColor: {
  35 + type: [String, null],
  36 + default: uni.$u.props.badge.bgColor
  37 + },
  38 + // 字体颜色
  39 + color: {
  40 + type: [String, null],
  41 + default: uni.$u.props.badge.color
  42 + },
  43 + // 徽标形状,circle-四角均为圆角,horn-左下角为直角
  44 + shape: {
  45 + type: String,
  46 + default: uni.$u.props.badge.shape
  47 + },
  48 + // 设置数字的显示方式,overflow|ellipsis|limit
  49 + // overflow会根据max字段判断,超出显示`${max}+`
  50 + // ellipsis会根据max判断,超出显示`${max}...`
  51 + // limit会依据1000作为判断条件,超出1000,显示`${value/1000}K`,比如2.2k、3.34w,最多保留2位小数
  52 + numberType: {
  53 + type: String,
  54 + default: uni.$u.props.badge.numberType
  55 + },
  56 + // 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效
  57 + offset: {
  58 + type: Array,
  59 + default: uni.$u.props.badge.offset
  60 + },
  61 + // 是否反转背景和字体颜色
  62 + inverted: {
  63 + type: Boolean,
  64 + default: uni.$u.props.badge.inverted
  65 + },
  66 + // 是否绝对定位
  67 + absolute: {
  68 + type: Boolean,
  69 + default: uni.$u.props.badge.absolute
  70 + }
  71 + }
  72 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-badge/u-badge.vue 0 → 100644
  1 +<template>
  2 + <text
  3 + v-if="show && ((Number(value) === 0 ? showZero : true) || isDot)"
  4 + :class="[isDot ? 'u-badge--dot' : 'u-badge--not-dot', inverted && 'u-badge--inverted', shape === 'horn' && 'u-badge--horn', `u-badge--${type}${inverted ? '--inverted' : ''}`]"
  5 + :style="[$u.addStyle(customStyle), badgeStyle]"
  6 + class="u-badge"
  7 + >{{ isDot ? '' :showValue }}</text>
  8 +</template>
  9 +
  10 +<script>
  11 + import props from './props.js';
  12 + /**
  13 + * badge 徽标数
  14 + * @description 该组件一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。
  15 + * @tutorial https://uviewui.com/components/badge.html
  16 + *
  17 + * @property {Boolean} isDot 是否显示圆点 (默认 false )
  18 + * @property {String | Number} value 显示的内容
  19 + * @property {Boolean} show 是否显示 (默认 true )
  20 + * @property {String | Number} max 最大值,超过最大值会显示 '{max}+' (默认999)
  21 + * @property {String} type 主题类型,error|warning|success|primary (默认 'error' )
  22 + * @property {Boolean} showZero 当数值为 0 时,是否展示 Badge (默认 false )
  23 + * @property {String} bgColor 背景颜色,优先级比type高,如设置,type参数会失效
  24 + * @property {String} color 字体颜色 (默认 '#ffffff' )
  25 + * @property {String} shape 徽标形状,circle-四角均为圆角,horn-左下角为直角 (默认 'circle' )
  26 + * @property {String} numberType 设置数字的显示方式,overflow|ellipsis|limit (默认 'overflow' )
  27 + * @property {Array}} offset 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效
  28 + * @property {Boolean} inverted 是否反转背景和字体颜色(默认 false )
  29 + * @property {Boolean} absolute 是否绝对定位(默认 false )
  30 + * @property {Object} customStyle 定义需要用到的外部样式
  31 + * @example <u-badge :type="type" :count="count"></u-badge>
  32 + */
  33 + export default {
  34 + name: 'u-badge',
  35 + mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
  36 + computed: {
  37 + // 是否将badge中心与父组件右上角重合
  38 + boxStyle() {
  39 + let style = {};
  40 + return style;
  41 + },
  42 + // 整个组件的样式
  43 + badgeStyle() {
  44 + const style = {}
  45 + if(this.color) {
  46 + style.color = this.color
  47 + }
  48 + if (this.bgColor && !this.inverted) {
  49 + style.backgroundColor = this.bgColor
  50 + }
  51 + if (this.absolute) {
  52 + style.position = 'absolute'
  53 + // 如果有设置offset参数
  54 + if(this.offset.length) {
  55 + // top和right分为为offset的第一个和第二个值,如果没有第二个值,则right等于top
  56 + const top = this.offset[0]
  57 + const right = this.offset[1] || top
  58 + style.top = uni.$u.addUnit(top)
  59 + style.right = uni.$u.addUnit(right)
  60 + }
  61 + }
  62 + return style
  63 + },
  64 + showValue() {
  65 + switch (this.numberType) {
  66 + case "overflow":
  67 + return Number(this.value) > Number(this.max) ? this.max + "+" : this.value
  68 + break;
  69 + case "ellipsis":
  70 + return Number(this.value) > Number(this.max) ? "..." : this.value
  71 + break;
  72 + case "limit":
  73 + return Number(this.value) > 999 ? Number(this.value) >= 9999 ?
  74 + Math.floor(this.value / 1e4 * 100) / 100 + "w" : Math.floor(this.value /
  75 + 1e3 * 100) / 100 + "k" : this.value
  76 + break;
  77 + default:
  78 + return Number(this.value)
  79 + }
  80 + },
  81 + }
  82 + }
  83 +</script>
  84 +
  85 +<style lang="scss" scoped>
  86 + @import "../../libs/css/components.scss";
  87 +
  88 + $u-badge-primary: $u-primary !default;
  89 + $u-badge-error: $u-error !default;
  90 + $u-badge-success: $u-success !default;
  91 + $u-badge-info: $u-info !default;
  92 + $u-badge-warning: $u-warning !default;
  93 + $u-badge-dot-radius: 100px !default;
  94 + $u-badge-dot-size: 8px !default;
  95 + $u-badge-dot-right: 4px !default;
  96 + $u-badge-dot-top: 0 !default;
  97 + $u-badge-text-font-size: 11px !default;
  98 + $u-badge-text-right: 10px !default;
  99 + $u-badge-text-padding: 2px 5px !default;
  100 + $u-badge-text-align: center !default;
  101 + $u-badge-text-color: #FFFFFF !default;
  102 +
  103 + .u-badge {
  104 + border-top-right-radius: $u-badge-dot-radius;
  105 + border-top-left-radius: $u-badge-dot-radius;
  106 + border-bottom-left-radius: $u-badge-dot-radius;
  107 + border-bottom-right-radius: $u-badge-dot-radius;
  108 + @include flex;
  109 + line-height: $u-badge-text-font-size;
  110 + text-align: $u-badge-text-align;
  111 + font-size: $u-badge-text-font-size;
  112 + color: $u-badge-text-color;
  113 +
  114 + &--dot {
  115 + height: $u-badge-dot-size;
  116 + width: $u-badge-dot-size;
  117 + }
  118 +
  119 + &--inverted {
  120 + font-size: 13px;
  121 + }
  122 +
  123 + &--not-dot {
  124 + padding: $u-badge-text-padding;
  125 + }
  126 +
  127 + &--horn {
  128 + border-bottom-left-radius: 0;
  129 + }
  130 +
  131 + &--primary {
  132 + background-color: $u-badge-primary;
  133 + }
  134 +
  135 + &--primary--inverted {
  136 + color: $u-badge-primary;
  137 + }
  138 +
  139 + &--error {
  140 + background-color: $u-badge-error;
  141 + }
  142 +
  143 + &--error--inverted {
  144 + color: $u-badge-error;
  145 + }
  146 +
  147 + &--success {
  148 + background-color: $u-badge-success;
  149 + }
  150 +
  151 + &--success--inverted {
  152 + color: $u-badge-success;
  153 + }
  154 +
  155 + &--info {
  156 + background-color: $u-badge-info;
  157 + }
  158 +
  159 + &--info--inverted {
  160 + color: $u-badge-info;
  161 + }
  162 +
  163 + &--warning {
  164 + background-color: $u-badge-warning;
  165 + }
  166 +
  167 + &--warning--inverted {
  168 + color: $u-badge-warning;
  169 + }
  170 + }
  171 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-button/nvue.scss 0 → 100644
  1 +$u-button-active-opacity:0.75 !default;
  2 +$u-button-loading-text-margin-left:4px !default;
  3 +$u-button-text-color: #FFFFFF !default;
  4 +$u-button-text-plain-error-color:$u-error !default;
  5 +$u-button-text-plain-warning-color:$u-warning !default;
  6 +$u-button-text-plain-success-color:$u-success !default;
  7 +$u-button-text-plain-info-color:$u-info !default;
  8 +$u-button-text-plain-primary-color:$u-primary !default;
  9 +.u-button {
  10 + &--active {
  11 + opacity: $u-button-active-opacity;
  12 + }
  13 +
  14 + &--active--plain {
  15 + background-color: rgb(217, 217, 217);
  16 + }
  17 +
  18 + &__loading-text {
  19 + margin-left:$u-button-loading-text-margin-left;
  20 + }
  21 +
  22 + &__text,
  23 + &__loading-text {
  24 + color:$u-button-text-color;
  25 + }
  26 +
  27 + &__text--plain--error {
  28 + color:$u-button-text-plain-error-color;
  29 + }
  30 +
  31 + &__text--plain--warning {
  32 + color:$u-button-text-plain-warning-color;
  33 + }
  34 +
  35 + &__text--plain--success{
  36 + color:$u-button-text-plain-success-color;
  37 + }
  38 +
  39 + &__text--plain--info {
  40 + color:$u-button-text-plain-info-color;
  41 + }
  42 +
  43 + &__text--plain--primary {
  44 + color:$u-button-text-plain-primary-color;
  45 + }
  46 +}
0 47 \ No newline at end of file
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-button/props.js 0 → 100644
  1 +/*
  2 + * @Author : LQ
  3 + * @Description :
  4 + * @version : 1.0
  5 + * @Date : 2021-08-16 10:04:04
  6 + * @LastAuthor : LQ
  7 + * @lastTime : 2021-08-16 10:04:24
  8 + * @FilePath : /u-view2.0/uview-ui/components/u-button/props.js
  9 + */
  10 +export default {
  11 + props: {
  12 + // 是否细边框
  13 + hairline: {
  14 + type: Boolean,
  15 + default: uni.$u.props.button.hairline
  16 + },
  17 + // 按钮的预置样式,info,primary,error,warning,success
  18 + type: {
  19 + type: String,
  20 + default: uni.$u.props.button.type
  21 + },
  22 + // 按钮尺寸,large,normal,small,mini
  23 + size: {
  24 + type: String,
  25 + default: uni.$u.props.button.size
  26 + },
  27 + // 按钮形状,circle(两边为半圆),square(带圆角)
  28 + shape: {
  29 + type: String,
  30 + default: uni.$u.props.button.shape
  31 + },
  32 + // 按钮是否镂空
  33 + plain: {
  34 + type: Boolean,
  35 + default: uni.$u.props.button.plain
  36 + },
  37 + // 是否禁止状态
  38 + disabled: {
  39 + type: Boolean,
  40 + default: uni.$u.props.button.disabled
  41 + },
  42 + // 是否加载中
  43 + loading: {
  44 + type: Boolean,
  45 + default: uni.$u.props.button.loading
  46 + },
  47 + // 加载中提示文字
  48 + loadingText: {
  49 + type: [String, Number],
  50 + default: uni.$u.props.button.loadingText
  51 + },
  52 + // 加载状态图标类型
  53 + loadingMode: {
  54 + type: String,
  55 + default: uni.$u.props.button.loadingMode
  56 + },
  57 + // 加载图标大小
  58 + loadingSize: {
  59 + type: [String, Number],
  60 + default: uni.$u.props.button.loadingSize
  61 + },
  62 + // 开放能力,具体请看uniapp稳定关于button组件部分说明
  63 + // https://uniapp.dcloud.io/component/button
  64 + openType: {
  65 + type: String,
  66 + default: uni.$u.props.button.openType
  67 + },
  68 + // 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件
  69 + // 取值为submit(提交表单),reset(重置表单)
  70 + formType: {
  71 + type: String,
  72 + default: uni.$u.props.button.formType
  73 + },
  74 + // 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效
  75 + // 只微信小程序、QQ小程序有效
  76 + appParameter: {
  77 + type: String,
  78 + default: uni.$u.props.button.appParameter
  79 + },
  80 + // 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效
  81 + hoverStopPropagation: {
  82 + type: Boolean,
  83 + default: uni.$u.props.button.hoverStopPropagation
  84 + },
  85 + // 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效
  86 + lang: {
  87 + type: String,
  88 + default: uni.$u.props.button.lang
  89 + },
  90 + // 会话来源,open-type="contact"时有效。只微信小程序有效
  91 + sessionFrom: {
  92 + type: String,
  93 + default: uni.$u.props.button.sessionFrom
  94 + },
  95 + // 会话内消息卡片标题,open-type="contact"时有效
  96 + // 默认当前标题,只微信小程序有效
  97 + sendMessageTitle: {
  98 + type: String,
  99 + default: uni.$u.props.button.sendMessageTitle
  100 + },
  101 + // 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效
  102 + // 默认当前分享路径,只微信小程序有效
  103 + sendMessagePath: {
  104 + type: String,
  105 + default: uni.$u.props.button.sendMessagePath
  106 + },
  107 + // 会话内消息卡片图片,open-type="contact"时有效
  108 + // 默认当前页面截图,只微信小程序有效
  109 + sendMessageImg: {
  110 + type: String,
  111 + default: uni.$u.props.button.sendMessageImg
  112 + },
  113 + // 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,
  114 + // 用户点击后可以快速发送小程序消息,open-type="contact"时有效
  115 + showMessageCard: {
  116 + type: Boolean,
  117 + default: uni.$u.props.button.showMessageCard
  118 + },
  119 + // 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
  120 + dataName: {
  121 + type: String,
  122 + default: uni.$u.props.button.dataName
  123 + },
  124 + // 节流,一定时间内只能触发一次
  125 + throttleTime: {
  126 + type: [String, Number],
  127 + default: uni.$u.props.button.throttleTime
  128 + },
  129 + // 按住后多久出现点击态,单位毫秒
  130 + hoverStartTime: {
  131 + type: [String, Number],
  132 + default: uni.$u.props.button.hoverStartTime
  133 + },
  134 + // 手指松开后点击态保留时间,单位毫秒
  135 + hoverStayTime: {
  136 + type: [String, Number],
  137 + default: uni.$u.props.button.hoverStayTime
  138 + },
  139 + // 按钮文字,之所以通过props传入,是因为slot传入的话
  140 + // nvue中无法控制文字的样式
  141 + text: {
  142 + type: [String, Number],
  143 + default: uni.$u.props.button.text
  144 + },
  145 + // 按钮图标
  146 + icon: {
  147 + type: String,
  148 + default: uni.$u.props.button.icon
  149 + },
  150 + // 按钮图标
  151 + iconColor: {
  152 + type: String,
  153 + default: uni.$u.props.button.icon
  154 + },
  155 + // 按钮颜色,支持传入linear-gradient渐变色
  156 + color: {
  157 + type: String,
  158 + default: uni.$u.props.button.color
  159 + }
  160 + }
  161 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-button/u-button.vue 0 → 100644
  1 +<template>
  2 + <!-- #ifndef APP-NVUE -->
  3 + <button
  4 + :hover-start-time="Number(hoverStartTime)"
  5 + :hover-stay-time="Number(hoverStayTime)"
  6 + :form-type="formType"
  7 + :open-type="openType"
  8 + :app-parameter="appParameter"
  9 + :hover-stop-propagation="hoverStopPropagation"
  10 + :send-message-title="sendMessageTitle"
  11 + :send-message-path="sendMessagePath"
  12 + :lang="lang"
  13 + :data-name="dataName"
  14 + :session-from="sessionFrom"
  15 + :send-message-img="sendMessageImg"
  16 + :show-message-card="showMessageCard"
  17 + @getphonenumber="getphonenumber"
  18 + @getuserinfo="getuserinfo"
  19 + @error="error"
  20 + @opensetting="opensetting"
  21 + @launchapp="launchapp"
  22 + :hover-class="!disabled && !loading ? 'u-button--active' : ''"
  23 + class="u-button u-reset-button"
  24 + :style="[baseColor, $u.addStyle(customStyle)]"
  25 + @tap="clickHandler"
  26 + :class="bemClass"
  27 + >
  28 + <template v-if="loading">
  29 + <u-loading-icon
  30 + :mode="loadingMode"
  31 + :size="textSize * 1.15"
  32 + :color="loadingColor"
  33 + ></u-loading-icon>
  34 + <text
  35 + class="u-button__loading-text"
  36 + :style="[{ fontSize: textSize + 'px' }]"
  37 + >{{ loadingText || text }}</text
  38 + >
  39 + </template>
  40 + <template v-else>
  41 + <u-icon
  42 + v-if="icon"
  43 + :name="icon"
  44 + :color="iconColorCom"
  45 + :size="textSize * 1.35"
  46 + :customStyle="{ marginRight: '2px' }"
  47 + ></u-icon>
  48 + <slot>
  49 + <text
  50 + class="u-button__text"
  51 + :style="[{ fontSize: textSize + 'px' }]"
  52 + >{{ text }}</text
  53 + >
  54 + </slot>
  55 + </template>
  56 + </button>
  57 + <!-- #endif -->
  58 +
  59 + <!-- #ifdef APP-NVUE -->
  60 + <view
  61 + :hover-start-time="Number(hoverStartTime)"
  62 + :hover-stay-time="Number(hoverStayTime)"
  63 + class="u-button"
  64 + :hover-class="
  65 + !disabled && !loading && !color && (plain || type === 'info')
  66 + ? 'u-button--active--plain'
  67 + : !disabled && !loading && !plain
  68 + ? 'u-button--active'
  69 + : ''
  70 + "
  71 + @tap="clickHandler"
  72 + :class="bemClass"
  73 + :style="[baseColor, $u.addStyle(customStyle)]"
  74 + >
  75 + <template v-if="loading">
  76 + <u-loading-icon
  77 + :mode="loadingMode"
  78 + :size="textSize * 1.15"
  79 + :color="loadingColor"
  80 + ></u-loading-icon>
  81 + <text
  82 + class="u-button__loading-text"
  83 + :style="[nvueTextStyle]"
  84 + :class="[plain && `u-button__text--plain--${type}`]"
  85 + >{{ loadingText || text }}</text
  86 + >
  87 + </template>
  88 + <template v-else>
  89 + <u-icon
  90 + v-if="icon"
  91 + :name="icon"
  92 + :color="iconColorCom"
  93 + :size="textSize * 1.35"
  94 + ></u-icon>
  95 + <text
  96 + class="u-button__text"
  97 + :style="[
  98 + {
  99 + marginLeft: icon ? '2px' : 0,
  100 + },
  101 + nvueTextStyle,
  102 + ]"
  103 + :class="[plain && `u-button__text--plain--${type}`]"
  104 + >{{ text }}</text
  105 + >
  106 + </template>
  107 + </view>
  108 + <!-- #endif -->
  109 +</template>
  110 +
  111 +<script>
  112 +import button from "../../libs/mixin/button.js";
  113 +import openType from "../../libs/mixin/openType.js";
  114 +import props from "./props.js";
  115 +/**
  116 + * button 按钮
  117 + * @description Button 按钮
  118 + * @tutorial https://www.uviewui.com/components/button.html
  119 + *
  120 + * @property {Boolean} hairline 是否显示按钮的细边框 (默认 true )
  121 + * @property {String} type 按钮的预置样式,info,primary,error,warning,success (默认 'info' )
  122 + * @property {String} size 按钮尺寸,large,normal,mini (默认 normal)
  123 + * @property {String} shape 按钮形状,circle(两边为半圆),square(带圆角) (默认 'square' )
  124 + * @property {Boolean} plain 按钮是否镂空,背景色透明 (默认 false)
  125 + * @property {Boolean} disabled 是否禁用 (默认 false)
  126 + * @property {Boolean} loading 按钮名称前是否带 loading 图标(App-nvue 平台,在 ios 上为雪花,Android上为圆圈) (默认 false)
  127 + * @property {String | Number} loadingText 加载中提示文字
  128 + * @property {String} loadingMode 加载状态图标类型 (默认 'spinner' )
  129 + * @property {String | Number} loadingSize 加载图标大小 (默认 15 )
  130 + * @property {String} openType 开放能力,具体请看uniapp稳定关于button组件部分说明
  131 + * @property {String} formType 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件
  132 + * @property {String} appParameter 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 (注:只微信小程序、QQ小程序有效)
  133 + * @property {Boolean} hoverStopPropagation 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效(默认 true )
  134 + * @property {String} lang 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文(默认 en )
  135 + * @property {String} sessionFrom 会话来源,openType="contact"时有效
  136 + * @property {String} sendMessageTitle 会话内消息卡片标题,openType="contact"时有效
  137 + * @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径,openType="contact"时有效
  138 + * @property {String} sendMessageImg 会话内消息卡片图片,openType="contact"时有效
  139 + * @property {Boolean} showMessageCard 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效(默认false)
  140 + * @property {String} dataName 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
  141 + * @property {String | Number} throttleTime 节流,一定时间内只能触发一次 (默认 0 )
  142 + * @property {String | Number} hoverStartTime 按住后多久出现点击态,单位毫秒 (默认 0 )
  143 + * @property {String | Number} hoverStayTime 手指松开后点击态保留时间,单位毫秒 (默认 200 )
  144 + * @property {String | Number} text 按钮文字,之所以通过props传入,是因为slot传入的话(注:nvue中无法控制文字的样式)
  145 + * @property {String} icon 按钮图标
  146 + * @property {String} iconColor 按钮图标颜色
  147 + * @property {String} color 按钮颜色,支持传入linear-gradient渐变色
  148 + * @property {Object} customStyle 定义需要用到的外部样式
  149 + *
  150 + * @event {Function} click 非禁止并且非加载中,才能点击
  151 + * @event {Function} getphonenumber open-type="getPhoneNumber"时有效
  152 + * @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,从返回参数的detail中获取到的值同uni.getUserInfo
  153 + * @event {Function} error 当使用开放能力时,发生错误的回调
  154 + * @event {Function} opensetting 在打开授权设置页并关闭后回调
  155 + * @event {Function} launchapp 打开 APP 成功的回调
  156 + * @example <u-button>月落</u-button>
  157 + */
  158 +export default {
  159 + name: "u-button",
  160 + // #ifdef MP
  161 + mixins: [uni.$u.mpMixin, uni.$u.mixin, button, openType, props],
  162 + // #endif
  163 + // #ifndef MP
  164 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  165 + // #endif
  166 + data() {
  167 + return {};
  168 + },
  169 + computed: {
  170 + // 生成bem风格的类名
  171 + bemClass() {
  172 + // this.bem为一个computed变量,在mixin中
  173 + if (!this.color) {
  174 + return this.bem(
  175 + "button",
  176 + ["type", "shape", "size"],
  177 + ["disabled", "plain", "hairline"]
  178 + );
  179 + } else {
  180 + // 由于nvue的原因,在有color参数时,不需要传入type,否则会生成type相关的类型,影响最终的样式
  181 + return this.bem(
  182 + "button",
  183 + ["shape", "size"],
  184 + ["disabled", "plain", "hairline"]
  185 + );
  186 + }
  187 + },
  188 + loadingColor() {
  189 + if (this.plain) {
  190 + // 如果有设置color值,则用color值,否则使用type主题颜色
  191 + return this.color
  192 + ? this.color
  193 + : uni.$u.config.color[`u-${this.type}`];
  194 + }
  195 + if (this.type === "info") {
  196 + return "#c9c9c9";
  197 + }
  198 + return "rgb(200, 200, 200)";
  199 + },
  200 + iconColorCom() {
  201 + // 如果是镂空状态,设置了color就用color值,否则使用主题颜色,
  202 + // u-icon的color能接受一个主题颜色的值
  203 + if (this.iconColor) return this.iconColor;
  204 + if (this.plain) {
  205 + return this.color ? this.color : this.type;
  206 + } else {
  207 + return this.type === "info" ? "#000000" : "#ffffff";
  208 + }
  209 + },
  210 + baseColor() {
  211 + let style = {};
  212 + if (this.color) {
  213 + // 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
  214 + style.color = this.plain ? this.color : "white";
  215 + if (!this.plain) {
  216 + // 非镂空,背景色使用自定义的颜色
  217 + style["background-color"] = this.color;
  218 + }
  219 + if (this.color.indexOf("gradient") !== -1) {
  220 + // 如果自定义的颜色为渐变色,不显示边框,以及通过backgroundImage设置渐变色
  221 + // weex文档说明可以写borderWidth的形式,为什么这里需要分开写?
  222 + // 因为weex是阿里巴巴为了部门业绩考核而做的你懂的东西,所以需要这么写才有效
  223 + style.borderTopWidth = 0;
  224 + style.borderRightWidth = 0;
  225 + style.borderBottomWidth = 0;
  226 + style.borderLeftWidth = 0;
  227 + if (!this.plain) {
  228 + style.backgroundImage = this.color;
  229 + }
  230 + } else {
  231 + // 非渐变色,则设置边框相关的属性
  232 + style.borderColor = this.color;
  233 + style.borderWidth = "1px";
  234 + style.borderStyle = "solid";
  235 + }
  236 + }
  237 + return style;
  238 + },
  239 + // nvue版本按钮的字体不会继承父组件的颜色,需要对每一个text组件进行单独的设置
  240 + nvueTextStyle() {
  241 + let style = {};
  242 + // 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
  243 + if (this.type === "info") {
  244 + style.color = "#323233";
  245 + }
  246 + if (this.color) {
  247 + style.color = this.plain ? this.color : "white";
  248 + }
  249 + style.fontSize = this.textSize + "px";
  250 + return style;
  251 + },
  252 + // 字体大小
  253 + textSize() {
  254 + let fontSize = 14,
  255 + { size } = this;
  256 + if (size === "large") fontSize = 16;
  257 + if (size === "normal") fontSize = 14;
  258 + if (size === "small") fontSize = 12;
  259 + if (size === "mini") fontSize = 10;
  260 + return fontSize;
  261 + },
  262 + },
  263 + methods: {
  264 + clickHandler() {
  265 + // 非禁止并且非加载中,才能点击
  266 + if (!this.disabled && !this.loading) {
  267 + // 进行节流控制,每this.throttle毫秒内,只在开始处执行
  268 + uni.$u.throttle(() => {
  269 + this.$emit("click");
  270 + }, this.throttleTime);
  271 + }
  272 + },
  273 + // 下面为对接uniapp官方按钮开放能力事件回调的对接
  274 + getphonenumber(res) {
  275 + this.$emit("getphonenumber", res);
  276 + },
  277 + getuserinfo(res) {
  278 + this.$emit("getuserinfo", res);
  279 + },
  280 + error(res) {
  281 + this.$emit("error", res);
  282 + },
  283 + opensetting(res) {
  284 + this.$emit("opensetting", res);
  285 + },
  286 + launchapp(res) {
  287 + this.$emit("launchapp", res);
  288 + },
  289 + },
  290 +};
  291 +</script>
  292 +
  293 +<style lang="scss" scoped>
  294 +@import "../../libs/css/components.scss";
  295 +
  296 +/* #ifndef APP-NVUE */
  297 +@import "./vue.scss";
  298 +/* #endif */
  299 +
  300 +/* #ifdef APP-NVUE */
  301 +@import "./nvue.scss";
  302 +/* #endif */
  303 +
  304 +$u-button-u-button-height: 40px !default;
  305 +$u-button-text-font-size: 15px !default;
  306 +$u-button-loading-text-font-size: 15px !default;
  307 +$u-button-loading-text-margin-left: 4px !default;
  308 +$u-button-large-width: 100% !default;
  309 +$u-button-large-height: 50px !default;
  310 +$u-button-normal-padding: 0 12px !default;
  311 +$u-button-large-padding: 0 15px !default;
  312 +$u-button-normal-font-size: 14px !default;
  313 +$u-button-small-min-width: 60px !default;
  314 +$u-button-small-height: 30px !default;
  315 +$u-button-small-padding: 0px 8px !default;
  316 +$u-button-mini-padding: 0px 8px !default;
  317 +$u-button-small-font-size: 12px !default;
  318 +$u-button-mini-height: 22px !default;
  319 +$u-button-mini-font-size: 10px !default;
  320 +$u-button-mini-min-width: 50px !default;
  321 +$u-button-disabled-opacity: 0.5 !default;
  322 +$u-button-info-color: #323233 !default;
  323 +$u-button-info-background-color: #fff !default;
  324 +$u-button-info-border-color: #ebedf0 !default;
  325 +$u-button-info-border-width: 1px !default;
  326 +$u-button-info-border-style: solid !default;
  327 +$u-button-success-color: #fff !default;
  328 +$u-button-success-background-color: $u-success !default;
  329 +$u-button-success-border-color: $u-button-success-background-color !default;
  330 +$u-button-success-border-width: 1px !default;
  331 +$u-button-success-border-style: solid !default;
  332 +$u-button-primary-color: #fff !default;
  333 +$u-button-primary-background-color: $u-primary !default;
  334 +$u-button-primary-border-color: $u-button-primary-background-color !default;
  335 +$u-button-primary-border-width: 1px !default;
  336 +$u-button-primary-border-style: solid !default;
  337 +$u-button-error-color: #fff !default;
  338 +$u-button-error-background-color: $u-error !default;
  339 +$u-button-error-border-color: $u-button-error-background-color !default;
  340 +$u-button-error-border-width: 1px !default;
  341 +$u-button-error-border-style: solid !default;
  342 +$u-button-warning-color: #fff !default;
  343 +$u-button-warning-background-color: $u-warning !default;
  344 +$u-button-warning-border-color: $u-button-warning-background-color !default;
  345 +$u-button-warning-border-width: 1px !default;
  346 +$u-button-warning-border-style: solid !default;
  347 +$u-button-block-width: 100% !default;
  348 +$u-button-circle-border-top-right-radius: 100px !default;
  349 +$u-button-circle-border-top-left-radius: 100px !default;
  350 +$u-button-circle-border-bottom-left-radius: 100px !default;
  351 +$u-button-circle-border-bottom-right-radius: 100px !default;
  352 +$u-button-square-border-top-right-radius: 3px !default;
  353 +$u-button-square-border-top-left-radius: 3px !default;
  354 +$u-button-square-border-bottom-left-radius: 3px !default;
  355 +$u-button-square-border-bottom-right-radius: 3px !default;
  356 +$u-button-icon-min-width: 1em !default;
  357 +$u-button-plain-background-color: #fff !default;
  358 +$u-button-hairline-border-width: 0.5px !default;
  359 +
  360 +.u-button {
  361 + height: $u-button-u-button-height;
  362 + position: relative;
  363 + align-items: center;
  364 + justify-content: center;
  365 + @include flex;
  366 + /* #ifndef APP-NVUE */
  367 + box-sizing: border-box;
  368 + /* #endif */
  369 + flex-direction: row;
  370 +
  371 + &__text {
  372 + font-size: $u-button-text-font-size;
  373 + }
  374 +
  375 + &__loading-text {
  376 + font-size: $u-button-loading-text-font-size;
  377 + margin-left: $u-button-loading-text-margin-left;
  378 + }
  379 +
  380 + &--large {
  381 + /* #ifndef APP-NVUE */
  382 + width: $u-button-large-width;
  383 + /* #endif */
  384 + height: $u-button-large-height;
  385 + padding: $u-button-large-padding;
  386 + }
  387 +
  388 + &--normal {
  389 + padding: $u-button-normal-padding;
  390 + font-size: $u-button-normal-font-size;
  391 + }
  392 +
  393 + &--small {
  394 + /* #ifndef APP-NVUE */
  395 + min-width: $u-button-small-min-width;
  396 + /* #endif */
  397 + height: $u-button-small-height;
  398 + padding: $u-button-small-padding;
  399 + font-size: $u-button-small-font-size;
  400 + }
  401 +
  402 + &--mini {
  403 + height: $u-button-mini-height;
  404 + font-size: $u-button-mini-font-size;
  405 + /* #ifndef APP-NVUE */
  406 + min-width: $u-button-mini-min-width;
  407 + /* #endif */
  408 + padding: $u-button-mini-padding;
  409 + }
  410 +
  411 + &--disabled {
  412 + opacity: $u-button-disabled-opacity;
  413 + }
  414 +
  415 + &--info {
  416 + color: $u-button-info-color;
  417 + background-color: $u-button-info-background-color;
  418 + border-color: $u-button-info-border-color;
  419 + border-width: $u-button-info-border-width;
  420 + border-style: $u-button-info-border-style;
  421 + }
  422 +
  423 + &--success {
  424 + color: $u-button-success-color;
  425 + background-color: $u-button-success-background-color;
  426 + border-color: $u-button-success-border-color;
  427 + border-width: $u-button-success-border-width;
  428 + border-style: $u-button-success-border-style;
  429 + }
  430 +
  431 + &--primary {
  432 + color: $u-button-primary-color;
  433 + background-color: $u-button-primary-background-color;
  434 + border-color: $u-button-primary-border-color;
  435 + border-width: $u-button-primary-border-width;
  436 + border-style: $u-button-primary-border-style;
  437 + }
  438 +
  439 + &--error {
  440 + color: $u-button-error-color;
  441 + background-color: $u-button-error-background-color;
  442 + border-color: $u-button-error-border-color;
  443 + border-width: $u-button-error-border-width;
  444 + border-style: $u-button-error-border-style;
  445 + }
  446 +
  447 + &--warning {
  448 + color: $u-button-warning-color;
  449 + background-color: $u-button-warning-background-color;
  450 + border-color: $u-button-warning-border-color;
  451 + border-width: $u-button-warning-border-width;
  452 + border-style: $u-button-warning-border-style;
  453 + }
  454 +
  455 + &--block {
  456 + @include flex;
  457 + width: $u-button-block-width;
  458 + }
  459 +
  460 + &--circle {
  461 + border-top-right-radius: $u-button-circle-border-top-right-radius;
  462 + border-top-left-radius: $u-button-circle-border-top-left-radius;
  463 + border-bottom-left-radius: $u-button-circle-border-bottom-left-radius;
  464 + border-bottom-right-radius: $u-button-circle-border-bottom-right-radius;
  465 + }
  466 +
  467 + &--square {
  468 + border-bottom-left-radius: $u-button-square-border-top-right-radius;
  469 + border-bottom-right-radius: $u-button-square-border-top-left-radius;
  470 + border-top-left-radius: $u-button-square-border-bottom-left-radius;
  471 + border-top-right-radius: $u-button-square-border-bottom-right-radius;
  472 + }
  473 +
  474 + &__icon {
  475 + /* #ifndef APP-NVUE */
  476 + min-width: $u-button-icon-min-width;
  477 + line-height: inherit !important;
  478 + vertical-align: top;
  479 + /* #endif */
  480 + }
  481 +
  482 + &--plain {
  483 + background-color: $u-button-plain-background-color;
  484 + }
  485 +
  486 + &--hairline {
  487 + border-width: $u-button-hairline-border-width !important;
  488 + }
  489 +}
  490 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-button/vue.scss 0 → 100644
  1 +// nvue下hover-class无效
  2 +$u-button-before-top:50% !default;
  3 +$u-button-before-left:50% !default;
  4 +$u-button-before-width:100% !default;
  5 +$u-button-before-height:100% !default;
  6 +$u-button-before-transform:translate(-50%, -50%) !default;
  7 +$u-button-before-opacity:0 !default;
  8 +$u-button-before-background-color:#000 !default;
  9 +$u-button-before-border-color:#000 !default;
  10 +$u-button-active-before-opacity:.15 !default;
  11 +$u-button-icon-margin-left:4px !default;
  12 +$u-button-plain-u-button-info-color:$u-info;
  13 +$u-button-plain-u-button-success-color:$u-success;
  14 +$u-button-plain-u-button-error-color:$u-error;
  15 +$u-button-plain-u-button-warning-color:$u-error;
  16 +
  17 +.u-button {
  18 + width: 100%;
  19 +
  20 + &__text {
  21 + white-space: nowrap;
  22 + line-height: 1;
  23 + }
  24 +
  25 + &:before {
  26 + position: absolute;
  27 + top:$u-button-before-top;
  28 + left:$u-button-before-left;
  29 + width:$u-button-before-width;
  30 + height:$u-button-before-height;
  31 + border: inherit;
  32 + border-radius: inherit;
  33 + transform:$u-button-before-transform;
  34 + opacity:$u-button-before-opacity;
  35 + content: " ";
  36 + background-color:$u-button-before-background-color;
  37 + border-color:$u-button-before-border-color;
  38 + }
  39 +
  40 + &--active {
  41 + &:before {
  42 + opacity: .15
  43 + }
  44 + }
  45 +
  46 + &__icon+&__text:not(:empty),
  47 + &__loading-text {
  48 + margin-left:$u-button-icon-margin-left;
  49 + }
  50 +
  51 + &--plain {
  52 + &.u-button--primary {
  53 + color: $u-primary;
  54 + }
  55 + }
  56 +
  57 + &--plain {
  58 + &.u-button--info {
  59 + color:$u-button-plain-u-button-info-color;
  60 + }
  61 + }
  62 +
  63 + &--plain {
  64 + &.u-button--success {
  65 + color:$u-button-plain-u-button-success-color;
  66 + }
  67 + }
  68 +
  69 + &--plain {
  70 + &.u-button--error {
  71 + color:$u-button-plain-u-button-error-color;
  72 + }
  73 + }
  74 +
  75 + &--plain {
  76 + &.u-button--warning {
  77 + color:$u-button-plain-u-button-warning-color;
  78 + }
  79 + }
  80 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-calendar/header.vue 0 → 100644
  1 +<template>
  2 + <view class="u-calendar-header u-border-bottom">
  3 + <text
  4 + class="u-calendar-header__title"
  5 + v-if="showTitle"
  6 + >{{ title }}</text>
  7 + <text
  8 + class="u-calendar-header__subtitle"
  9 + v-if="showSubtitle"
  10 + >{{ subtitle }}</text>
  11 + <view class="u-calendar-header__weekdays">
  12 + <text class="u-calendar-header__weekdays__weekday">一</text>
  13 + <text class="u-calendar-header__weekdays__weekday">二</text>
  14 + <text class="u-calendar-header__weekdays__weekday">三</text>
  15 + <text class="u-calendar-header__weekdays__weekday">四</text>
  16 + <text class="u-calendar-header__weekdays__weekday">五</text>
  17 + <text class="u-calendar-header__weekdays__weekday">六</text>
  18 + <text class="u-calendar-header__weekdays__weekday">日</text>
  19 + </view>
  20 + </view>
  21 +</template>
  22 +
  23 +<script>
  24 + export default {
  25 + name: 'u-calendar-header',
  26 + mixins: [uni.$u.mpMixin, uni.$u.mixin],
  27 + props: {
  28 + // 标题
  29 + title: {
  30 + type: String,
  31 + default: ''
  32 + },
  33 + // 副标题
  34 + subtitle: {
  35 + type: String,
  36 + default: ''
  37 + },
  38 + // 是否显示标题
  39 + showTitle: {
  40 + type: Boolean,
  41 + default: true
  42 + },
  43 + // 是否显示副标题
  44 + showSubtitle: {
  45 + type: Boolean,
  46 + default: true
  47 + },
  48 + },
  49 + data() {
  50 + return {
  51 +
  52 + }
  53 + },
  54 + methods: {
  55 + name() {
  56 +
  57 + }
  58 + },
  59 + }
  60 +</script>
  61 +
  62 +<style lang="scss" scoped>
  63 + @import "../../libs/css/components.scss";
  64 +
  65 + .u-calendar-header {
  66 + padding-bottom: 4px;
  67 +
  68 + &__title {
  69 + font-size: 16px;
  70 + color: $u-main-color;
  71 + text-align: center;
  72 + height: 42px;
  73 + line-height: 42px;
  74 + font-weight: bold;
  75 + }
  76 +
  77 + &__subtitle {
  78 + font-size: 14px;
  79 + color: $u-main-color;
  80 + height: 40px;
  81 + text-align: center;
  82 + line-height: 40px;
  83 + font-weight: bold;
  84 + }
  85 +
  86 + &__weekdays {
  87 + @include flex;
  88 + justify-content: space-between;
  89 +
  90 + &__weekday {
  91 + font-size: 13px;
  92 + color: $u-main-color;
  93 + line-height: 30px;
  94 + flex: 1;
  95 + text-align: center;
  96 + }
  97 + }
  98 + }
  99 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-calendar/month.vue 0 → 100644
  1 +<template>
  2 + <view class="u-calendar-month-wrapper" ref="u-calendar-month-wrapper">
  3 + <view v-for="(item, index) in months" :key="index" :class="[`u-calendar-month-${index}`]"
  4 + :ref="`u-calendar-month-${index}`" :id="`month-${index}`">
  5 + <text v-if="index !== 0" class="u-calendar-month__title">{{ item.year }}年{{ item.month }}月</text>
  6 + <view class="u-calendar-month__days">
  7 + <view v-if="showMark" class="u-calendar-month__days__month-mark-wrapper">
  8 + <text class="u-calendar-month__days__month-mark-wrapper__text">{{ item.month }}</text>
  9 + </view>
  10 + <view class="u-calendar-month__days__day" v-for="(item1, index1) in item.date" :key="index1"
  11 + :style="[dayStyle(index, index1, item1)]" @tap="clickHandler(index, index1, item1)"
  12 + :class="[item1.selected && 'u-calendar-month__days__day__select--selected']">
  13 + <view class="u-calendar-month__days__day__select" :style="[daySelectStyle(index, index1, item1)]">
  14 + <text class="u-calendar-month__days__day__select__info"
  15 + :class="[item1.disabled && 'u-calendar-month__days__day__select__info--disabled']"
  16 + :style="[textStyle(item1)]">{{ item1.day }}</text>
  17 + <text v-if="getBottomInfo(index, index1, item1)"
  18 + class="u-calendar-month__days__day__select__buttom-info"
  19 + :class="[item1.disabled && 'u-calendar-month__days__day__select__buttom-info--disabled']"
  20 + :style="[textStyle(item1)]">{{ getBottomInfo(index, index1, item1) }}</text>
  21 + <text v-if="item1.dot" class="u-calendar-month__days__day__select__dot"></text>
  22 + </view>
  23 + </view>
  24 + </view>
  25 + </view>
  26 + </view>
  27 +</template>
  28 +
  29 +<script>
  30 + // #ifdef APP-NVUE
  31 + // 由于nvue不支持百分比单位,需要查询宽度来计算每个日期的宽度
  32 + const dom = uni.requireNativePlugin('dom')
  33 + // #endif
  34 + import dayjs from '../../libs/util/dayjs.js';
  35 + export default {
  36 + name: 'u-calendar-month',
  37 + mixins: [uni.$u.mpMixin, uni.$u.mixin],
  38 + props: {
  39 + // 是否显示月份背景色
  40 + showMark: {
  41 + type: Boolean,
  42 + default: true
  43 + },
  44 + // 主题色,对底部按钮和选中日期有效
  45 + color: {
  46 + type: String,
  47 + default: '#3c9cff'
  48 + },
  49 + // 月份数据
  50 + months: {
  51 + type: Array,
  52 + default: () => []
  53 + },
  54 + // 日期选择类型
  55 + mode: {
  56 + type: String,
  57 + default: 'single'
  58 + },
  59 + // 日期行高
  60 + rowHeight: {
  61 + type: [String, Number],
  62 + default: 58
  63 + },
  64 + // mode=multiple时,最多可选多少个日期
  65 + maxCount: {
  66 + type: [String, Number],
  67 + default: Infinity
  68 + },
  69 + // mode=range时,第一个日期底部的提示文字
  70 + startText: {
  71 + type: String,
  72 + default: '开始'
  73 + },
  74 + // mode=range时,最后一个日期底部的提示文字
  75 + endText: {
  76 + type: String,
  77 + default: '结束'
  78 + },
  79 + // 默认选中的日期,mode为multiple或range是必须为数组格式
  80 + defaultDate: {
  81 + type: [Array, String, Date],
  82 + default: null
  83 + },
  84 + // 最小的可选日期
  85 + minDate: {
  86 + type: [String, Number],
  87 + default: 0
  88 + },
  89 + // 最大可选日期
  90 + maxDate: {
  91 + type: [String, Number],
  92 + default: 0
  93 + },
  94 + // 如果没有设置maxDate,则往后推多少个月
  95 + maxMonth: {
  96 + type: [String, Number],
  97 + default: 2
  98 + },
  99 + // 是否为只读状态,只读状态下禁止选择日期
  100 + readonly: {
  101 + type: Boolean,
  102 + default: uni.$u.props.calendar.readonly
  103 + },
  104 + // 日期区间最多可选天数,默认无限制,mode = range时有效
  105 + maxRange: {
  106 + type: [Number, String],
  107 + default: Infinity
  108 + },
  109 + // 范围选择超过最多可选天数时的提示文案,mode = range时有效
  110 + rangePrompt: {
  111 + type: String,
  112 + default: ''
  113 + },
  114 + // 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效
  115 + showRangePrompt: {
  116 + type: Boolean,
  117 + default: true
  118 + },
  119 + // 是否允许日期范围的起止时间为同一天,mode = range时有效
  120 + allowSameDay: {
  121 + type: Boolean,
  122 + default: false
  123 + }
  124 + },
  125 + data() {
  126 + return {
  127 + // 每个日期的宽度
  128 + width: 0,
  129 + // 当前选中的日期item
  130 + item: {},
  131 + selected: []
  132 + }
  133 + },
  134 + watch: {
  135 + selectedChange: {
  136 + immediate: true,
  137 + handler(n) {
  138 + this.setDefaultDate()
  139 + }
  140 + }
  141 + },
  142 + computed: {
  143 + // 多个条件的变化,会引起选中日期的变化,这里统一管理监听
  144 + selectedChange() {
  145 + return [this.minDate, this.maxDate, this.defaultDate]
  146 + },
  147 + dayStyle(index1, index2, item) {
  148 + return (index1, index2, item) => {
  149 + const style = {}
  150 + let week = item.week
  151 + // 不进行四舍五入的形式保留2位小数
  152 + const dayWidth = Number(parseFloat(this.width / 7).toFixed(3).slice(0, -1))
  153 + // 得出每个日期的宽度
  154 + // #ifdef APP-NVUE
  155 + style.width = uni.$u.addUnit(dayWidth)
  156 + // #endif
  157 + style.height = uni.$u.addUnit(this.rowHeight)
  158 + if (index2 === 0) {
  159 + // 获取当前为星期几,如果为0,则为星期天,减一为每月第一天时,需要向左偏移的item个数
  160 + week = (week === 0 ? 7 : week) - 1
  161 + style.marginLeft = uni.$u.addUnit(week * dayWidth)
  162 + }
  163 + if (this.mode === 'range') {
  164 + // 之所以需要这么写,是因为DCloud公司的iOS客户端的开发者能力有限导致的bug
  165 + style.paddingLeft = 0
  166 + style.paddingRight = 0
  167 + style.paddingBottom = 0
  168 + style.paddingTop = 0
  169 + }
  170 + return style
  171 + }
  172 + },
  173 + daySelectStyle() {
  174 + return (index1, index2, item) => {
  175 + let date = dayjs(item.date).format("YYYY-MM-DD"),
  176 + style = {}
  177 + // 判断date是否在selected数组中,因为月份可能会需要补0,所以使用dateSame判断,而不用数组的includes判断
  178 + if (this.selected.some(item => this.dateSame(item, date))) {
  179 + style.backgroundColor = this.color
  180 + }
  181 + if (this.mode === 'single') {
  182 + if (date === this.selected[0]) {
  183 + // 因为需要对nvue的兼容,只能这么写,无法缩写,也无法通过类名控制等等
  184 + style.borderTopLeftRadius = '3px'
  185 + style.borderBottomLeftRadius = '3px'
  186 + style.borderTopRightRadius = '3px'
  187 + style.borderBottomRightRadius = '3px'
  188 + }
  189 + } else if (this.mode === 'range') {
  190 + if (this.selected.length >= 2) {
  191 + const len = this.selected.length - 1
  192 + // 第一个日期设置左上角和左下角的圆角
  193 + if (this.dateSame(date, this.selected[0])) {
  194 + style.borderTopLeftRadius = '3px'
  195 + style.borderBottomLeftRadius = '3px'
  196 + }
  197 + // 最后一个日期设置右上角和右下角的圆角
  198 + if (this.dateSame(date, this.selected[len])) {
  199 + style.borderTopRightRadius = '3px'
  200 + style.borderBottomRightRadius = '3px'
  201 + }
  202 + // 处于第一和最后一个之间的日期,背景色设置为浅色,通过将对应颜色进行等分,再取其尾部的颜色值
  203 + if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
  204 + .selected[len]))) {
  205 + style.backgroundColor = uni.$u.colorGradient(this.color, '#ffffff', 100)[90]
  206 + // 增加一个透明度,让范围区间的背景色也能看到底部的mark水印字符
  207 + style.opacity = 0.7
  208 + }
  209 + } else if (this.selected.length === 1) {
  210 + // 之所以需要这么写,是因为DCloud公司的iOS客户端的开发者能力有限导致的bug
  211 + // 进行还原操作,否则在nvue的iOS,uni-app有bug,会导致诡异的表现
  212 + style.borderTopLeftRadius = '3px'
  213 + style.borderBottomLeftRadius = '3px'
  214 + }
  215 + } else {
  216 + if (this.selected.some(item => this.dateSame(item, date))) {
  217 + style.borderTopLeftRadius = '3px'
  218 + style.borderBottomLeftRadius = '3px'
  219 + style.borderTopRightRadius = '3px'
  220 + style.borderBottomRightRadius = '3px'
  221 + }
  222 + }
  223 + return style
  224 + }
  225 + },
  226 + // 某个日期是否被选中
  227 + textStyle() {
  228 + return (item) => {
  229 + const date = dayjs(item.date).format("YYYY-MM-DD"),
  230 + style = {}
  231 + // 选中的日期,提示文字设置白色
  232 + if (this.selected.some(item => this.dateSame(item, date))) {
  233 + style.color = '#ffffff'
  234 + }
  235 + if (this.mode === 'range') {
  236 + const len = this.selected.length - 1
  237 + // 如果是范围选择模式,第一个和最后一个之间的日期,文字颜色设置为高亮的主题色
  238 + if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
  239 + .selected[len]))) {
  240 + style.color = this.color
  241 + }
  242 + }
  243 + return style
  244 + }
  245 + },
  246 + // 获取底部的提示文字
  247 + getBottomInfo() {
  248 + return (index1, index2, item) => {
  249 + const date = dayjs(item.date).format("YYYY-MM-DD")
  250 + const bottomInfo = item.bottomInfo
  251 + // 当为日期范围模式时,且选择的日期个数大于0时
  252 + if (this.mode === 'range' && this.selected.length > 0) {
  253 + if (this.selected.length === 1) {
  254 + // 选择了一个日期时,如果当前日期为数组中的第一个日期,则显示底部文字为“开始”
  255 + if (this.dateSame(date, this.selected[0])) return this.startText
  256 + else return bottomInfo
  257 + } else {
  258 + const len = this.selected.length - 1
  259 + // 如果数组中的日期大于2个时,第一个和最后一个显示为开始和结束日期
  260 + if (this.dateSame(date, this.selected[0]) && this.dateSame(date, this.selected[1]) &&
  261 + len === 1) {
  262 + // 如果长度为2,且第一个等于第二个日期,则提示语放在同一个item中
  263 + return `${this.startText}/${this.endText}`
  264 + } else if (this.dateSame(date, this.selected[0])) {
  265 + return this.startText
  266 + } else if (this.dateSame(date, this.selected[len])) {
  267 + return this.endText
  268 + } else {
  269 + return bottomInfo
  270 + }
  271 + }
  272 + } else {
  273 + return bottomInfo
  274 + }
  275 + }
  276 + }
  277 + },
  278 + mounted() {
  279 + this.init()
  280 + },
  281 + methods: {
  282 + init() {
  283 + // 初始化默认选中
  284 + this.$emit('monthSelected', this.selected)
  285 + this.$nextTick(() => {
  286 + // 这里需要另一个延时,因为获取宽度后,会进行月份数据渲染,只有渲染完成之后,才有真正的高度
  287 + // 因为nvue下,$nextTick并不是100%可靠的
  288 + uni.$u.sleep(10).then(() => {
  289 + this.getWrapperWidth()
  290 + this.getMonthRect()
  291 + })
  292 + })
  293 + },
  294 + // 判断两个日期是否相等
  295 + dateSame(date1, date2) {
  296 + return dayjs(date1).isSame(dayjs(date2))
  297 + },
  298 + // 获取月份数据区域的宽度,因为nvue不支持百分比,所以无法通过css设置每个日期item的宽度
  299 + getWrapperWidth() {
  300 + // #ifdef APP-NVUE
  301 + dom.getComponentRect(this.$refs['u-calendar-month-wrapper'], res => {
  302 + this.width = res.size.width
  303 + })
  304 + // #endif
  305 + // #ifndef APP-NVUE
  306 + this.$uGetRect('.u-calendar-month-wrapper').then(size => {
  307 + this.width = size.width
  308 + })
  309 + // #endif
  310 + },
  311 + getMonthRect() {
  312 + // 获取每个月份数据的尺寸,用于父组件在scroll-view滚动事件中,监听当前滚动到了第几个月份
  313 + const promiseAllArr = this.months.map((item, index) => this.getMonthRectByPromise(
  314 + `u-calendar-month-${index}`))
  315 + // 一次性返回
  316 + Promise.all(promiseAllArr).then(
  317 + sizes => {
  318 + let height = 1
  319 + const topArr = []
  320 + for (let i = 0; i < this.months.length; i++) {
  321 + // 添加到months数组中,供scroll-view滚动事件中,判断当前滚动到哪个月份
  322 + topArr[i] = height
  323 + height += sizes[i].height
  324 + }
  325 + // 由于微信下,无法通过this.months[i].top的形式(引用类型)去修改父组件的month的top值,所以使用事件形式对外发出
  326 + this.$emit('updateMonthTop', topArr)
  327 + })
  328 + },
  329 + // 获取每个月份区域的尺寸
  330 + getMonthRectByPromise(el) {
  331 + // #ifndef APP-NVUE
  332 + // $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://www.uviewui.com/js/getRect.html
  333 + // 组件内部一般用this.$uGetRect,对外的为uni.$u.getRect,二者功能一致,名称不同
  334 + return new Promise(resolve => {
  335 + this.$uGetRect(`.${el}`).then(size => {
  336 + resolve(size)
  337 + })
  338 + })
  339 + // #endif
  340 +
  341 + // #ifdef APP-NVUE
  342 + // nvue下,使用dom模块查询元素高度
  343 + // 返回一个promise,让调用此方法的主体能使用then回调
  344 + return new Promise(resolve => {
  345 + dom.getComponentRect(this.$refs[el][0], res => {
  346 + resolve(res.size)
  347 + })
  348 + })
  349 + // #endif
  350 + },
  351 + // 点击某一个日期
  352 + clickHandler(index1, index2, item) {
  353 + if (this.readonly) {
  354 + return;
  355 + }
  356 + this.item = item
  357 + const date = dayjs(item.date).format("YYYY-MM-DD")
  358 + if (item.disabled) return
  359 + // 对上一次选择的日期数组进行深度克隆
  360 + let selected = uni.$u.deepClone(this.selected)
  361 + if (this.mode === 'single') {
  362 + // 单选情况下,让数组中的元素为当前点击的日期
  363 + selected = [date]
  364 + } else if (this.mode === 'multiple') {
  365 + if (selected.some(item => this.dateSame(item, date))) {
  366 + // 如果点击的日期已在数组中,则进行移除操作,也就是达到反选的效果
  367 + const itemIndex = selected.findIndex(item => item === date)
  368 + selected.splice(itemIndex, 1)
  369 + } else {
  370 + // 如果点击的日期不在数组中,且已有的长度小于总可选长度时,则添加到数组中去
  371 + if (selected.length < this.maxCount) selected.push(date)
  372 + }
  373 + } else {
  374 + // 选择区间形式
  375 + if (selected.length === 0 || selected.length >= 2) {
  376 + // 如果原来就为0或者大于2的长度,则当前点击的日期,就是开始日期
  377 + selected = [date]
  378 + } else if (selected.length === 1) {
  379 + // 如果已经选择了开始日期
  380 + const existsDate = selected[0]
  381 + // 如果当前选择的日期小于上一次选择的日期,则当前的日期定为开始日期
  382 + if (dayjs(date).isBefore(existsDate)) {
  383 + selected = [date]
  384 + } else if (dayjs(date).isAfter(existsDate)) {
  385 + // 当前日期减去最大可选的日期天数,如果大于起始时间,则进行提示
  386 + if(dayjs(dayjs(date).subtract(this.maxRange, 'day')).isAfter(dayjs(selected[0])) && this.showRangePrompt) {
  387 + if(this.rangePrompt) {
  388 + uni.$u.toast(this.rangePrompt)
  389 + } else {
  390 + uni.$u.toast(`选择天数不能超过 ${this.maxRange} 天`)
  391 + }
  392 + return
  393 + }
  394 + // 如果当前日期大于已有日期,将当前的添加到数组尾部
  395 + selected.push(date)
  396 + const startDate = selected[0]
  397 + const endDate = selected[1]
  398 + const arr = []
  399 + let i = 0
  400 + do {
  401 + // 将开始和结束日期之间的日期添加到数组中
  402 + arr.push(dayjs(startDate).add(i, 'day').format("YYYY-MM-DD"))
  403 + i++
  404 + // 累加的日期小于结束日期时,继续下一次的循环
  405 + } while (dayjs(startDate).add(i, 'day').isBefore(dayjs(endDate)))
  406 + // 为了一次性修改数组,避免computed中多次触发,这里才用arr变量一次性赋值的方式,同时将最后一个日期添加近来
  407 + arr.push(endDate)
  408 + selected = arr
  409 + } else {
  410 + // 选择区间时,只有一个日期的情况下,且不允许选择起止为同一天的话,不允许选择自己
  411 + if (selected[0] === date && !this.allowSameDay) return
  412 + selected.push(date)
  413 + }
  414 + }
  415 + }
  416 + this.setSelected(selected)
  417 + },
  418 + // 设置默认日期
  419 + setDefaultDate() {
  420 + if (!this.defaultDate) {
  421 + // 如果没有设置默认日期,则将当天日期设置为默认选中的日期
  422 + const selected = [dayjs().format("YYYY-MM-DD")]
  423 + return this.setSelected(selected, false)
  424 + }
  425 + let defaultDate = []
  426 + const minDate = this.minDate || dayjs().format("YYYY-MM-DD")
  427 + const maxDate = this.maxDate || dayjs(minDate).add(this.maxMonth - 1, 'month').format("YYYY-MM-DD")
  428 + if (this.mode === 'single') {
  429 + // 单选模式,可以是字符串或数组,Date对象等
  430 + if (!uni.$u.test.array(this.defaultDate)) {
  431 + defaultDate = [dayjs(this.defaultDate).format("YYYY-MM-DD")]
  432 + } else {
  433 + defaultDate = [this.defaultDate[0]]
  434 + }
  435 + } else {
  436 + // 如果为非数组,则不执行
  437 + if (!uni.$u.test.array(this.defaultDate)) return
  438 + defaultDate = this.defaultDate
  439 + }
  440 + // 过滤用户传递的默认数组,取出只在可允许最大值与最小值之间的元素
  441 + defaultDate = defaultDate.filter(item => {
  442 + return dayjs(item).isAfter(dayjs(minDate).subtract(1, 'day')) && dayjs(item).isBefore(dayjs(
  443 + maxDate).add(1, 'day'))
  444 + })
  445 + this.setSelected(defaultDate, false)
  446 + },
  447 + setSelected(selected, event = true) {
  448 + this.selected = selected
  449 + event && this.$emit('monthSelected', this.selected)
  450 + }
  451 + }
  452 + }
  453 +</script>
  454 +
  455 +<style lang="scss" scoped>
  456 + @import "../../libs/css/components.scss";
  457 +
  458 + .u-calendar-month-wrapper {
  459 + margin-top: 4px;
  460 + }
  461 +
  462 + .u-calendar-month {
  463 +
  464 + &__title {
  465 + font-size: 14px;
  466 + line-height: 42px;
  467 + height: 42px;
  468 + color: $u-main-color;
  469 + text-align: center;
  470 + font-weight: bold;
  471 + }
  472 +
  473 + &__days {
  474 + position: relative;
  475 + @include flex;
  476 + flex-wrap: wrap;
  477 +
  478 + &__month-mark-wrapper {
  479 + position: absolute;
  480 + top: 0;
  481 + bottom: 0;
  482 + left: 0;
  483 + right: 0;
  484 + @include flex;
  485 + justify-content: center;
  486 + align-items: center;
  487 +
  488 + &__text {
  489 + font-size: 155px;
  490 + color: rgba(231, 232, 234, 0.83);
  491 + }
  492 + }
  493 +
  494 + &__day {
  495 + @include flex;
  496 + padding: 2px;
  497 + /* #ifndef APP-NVUE */
  498 + // vue下使用css进行宽度计算,因为某些安卓机会无法进行js获取父元素宽度进行计算得出,会有偏移
  499 + width: calc(100% / 7);
  500 + box-sizing: border-box;
  501 + /* #endif */
  502 +
  503 + &__select {
  504 + flex: 1;
  505 + @include flex;
  506 + align-items: center;
  507 + justify-content: center;
  508 + position: relative;
  509 +
  510 + &__dot {
  511 + width: 7px;
  512 + height: 7px;
  513 + border-radius: 100px;
  514 + background-color: $u-error;
  515 + position: absolute;
  516 + top: 12px;
  517 + right: 7px;
  518 + }
  519 +
  520 + &__buttom-info {
  521 + color: $u-content-color;
  522 + text-align: center;
  523 + position: absolute;
  524 + bottom: 5px;
  525 + font-size: 10px;
  526 + text-align: center;
  527 + left: 0;
  528 + right: 0;
  529 +
  530 + &--selected {
  531 + color: #ffffff;
  532 + }
  533 +
  534 + &--disabled {
  535 + color: #cacbcd;
  536 + }
  537 + }
  538 +
  539 + &__info {
  540 + text-align: center;
  541 + font-size: 16px;
  542 +
  543 + &--selected {
  544 + color: #ffffff;
  545 + }
  546 +
  547 + &--disabled {
  548 + color: #cacbcd;
  549 + }
  550 + }
  551 +
  552 + &--selected {
  553 + background-color: $u-primary;
  554 + @include flex;
  555 + justify-content: center;
  556 + align-items: center;
  557 + flex: 1;
  558 + border-radius: 3px;
  559 + }
  560 +
  561 + &--range-selected {
  562 + opacity: 0.3;
  563 + border-radius: 0;
  564 + }
  565 +
  566 + &--range-start-selected {
  567 + border-top-right-radius: 0;
  568 + border-bottom-right-radius: 0;
  569 + }
  570 +
  571 + &--range-end-selected {
  572 + border-top-left-radius: 0;
  573 + border-bottom-left-radius: 0;
  574 + }
  575 + }
  576 + }
  577 + }
  578 + }
  579 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-calendar/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 日历顶部标题
  4 + title: {
  5 + type: String,
  6 + default: uni.$u.props.calendar.title
  7 + },
  8 + // 是否显示标题
  9 + showTitle: {
  10 + type: Boolean,
  11 + default: uni.$u.props.calendar.showTitle
  12 + },
  13 + // 是否显示副标题
  14 + showSubtitle: {
  15 + type: Boolean,
  16 + default: uni.$u.props.calendar.showSubtitle
  17 + },
  18 + // 日期类型选择,single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围
  19 + mode: {
  20 + type: String,
  21 + default: uni.$u.props.calendar.mode
  22 + },
  23 + // mode=range时,第一个日期底部的提示文字
  24 + startText: {
  25 + type: String,
  26 + default: uni.$u.props.calendar.startText
  27 + },
  28 + // mode=range时,最后一个日期底部的提示文字
  29 + endText: {
  30 + type: String,
  31 + default: uni.$u.props.calendar.endText
  32 + },
  33 + // 自定义列表
  34 + customList: {
  35 + type: Array,
  36 + default: uni.$u.props.calendar.customList
  37 + },
  38 + // 主题色,对底部按钮和选中日期有效
  39 + color: {
  40 + type: String,
  41 + default: uni.$u.props.calendar.color
  42 + },
  43 + // 最小的可选日期
  44 + minDate: {
  45 + type: [String, Number],
  46 + default: uni.$u.props.calendar.minDate
  47 + },
  48 + // 最大可选日期
  49 + maxDate: {
  50 + type: [String, Number],
  51 + default: uni.$u.props.calendar.maxDate
  52 + },
  53 + // 默认选中的日期,mode为multiple或range是必须为数组格式
  54 + defaultDate: {
  55 + type: [Array, String, Date, null],
  56 + default: uni.$u.props.calendar.defaultDate
  57 + },
  58 + // mode=multiple时,最多可选多少个日期
  59 + maxCount: {
  60 + type: [String, Number],
  61 + default: uni.$u.props.calendar.maxCount
  62 + },
  63 + // 日期行高
  64 + rowHeight: {
  65 + type: [String, Number],
  66 + default: uni.$u.props.calendar.rowHeight
  67 + },
  68 + // 日期格式化函数
  69 + formatter: {
  70 + type: [Function, null],
  71 + default: uni.$u.props.calendar.formatter
  72 + },
  73 + // 是否显示农历
  74 + showLunar: {
  75 + type: Boolean,
  76 + default: uni.$u.props.calendar.showLunar
  77 + },
  78 + // 是否显示月份背景色
  79 + showMark: {
  80 + type: Boolean,
  81 + default: uni.$u.props.calendar.showMark
  82 + },
  83 + // 确定按钮的文字
  84 + confirmText: {
  85 + type: String,
  86 + default: uni.$u.props.calendar.confirmText
  87 + },
  88 + // 确认按钮处于禁用状态时的文字
  89 + confirmDisabledText: {
  90 + type: String,
  91 + default: uni.$u.props.calendar.confirmDisabledText
  92 + },
  93 + // 是否显示日历弹窗
  94 + show: {
  95 + type: Boolean,
  96 + default: uni.$u.props.calendar.show
  97 + },
  98 + // 是否允许点击遮罩关闭日历
  99 + closeOnClickOverlay: {
  100 + type: Boolean,
  101 + default: uni.$u.props.calendar.closeOnClickOverlay
  102 + },
  103 + // 是否为只读状态,只读状态下禁止选择日期
  104 + readonly: {
  105 + type: Boolean,
  106 + default: uni.$u.props.calendar.readonly
  107 + },
  108 + // 是否展示确认按钮
  109 + showConfirm: {
  110 + type: Boolean,
  111 + default: uni.$u.props.calendar.showConfirm
  112 + },
  113 + // 日期区间最多可选天数,默认无限制,mode = range时有效
  114 + maxRange: {
  115 + type: [Number, String],
  116 + default: uni.$u.props.calendar.maxRange
  117 + },
  118 + // 范围选择超过最多可选天数时的提示文案,mode = range时有效
  119 + rangePrompt: {
  120 + type: String,
  121 + default: uni.$u.props.calendar.rangePrompt
  122 + },
  123 + // 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效
  124 + showRangePrompt: {
  125 + type: Boolean,
  126 + default: uni.$u.props.calendar.showRangePrompt
  127 + },
  128 + // 是否允许日期范围的起止时间为同一天,mode = range时有效
  129 + allowSameDay: {
  130 + type: Boolean,
  131 + default: uni.$u.props.calendar.allowSameDay
  132 + },
  133 + // 圆角值
  134 + round: {
  135 + type: [Boolean, String, Number],
  136 + default: uni.$u.props.calendar.round
  137 + },
  138 + // 最多展示月份数量
  139 + monthNum: {
  140 + type: [Number, String],
  141 + default: 3
  142 + }
  143 + }
  144 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-calendar/u-calendar.vue 0 → 100644
  1 +<template>
  2 + <u-popup
  3 + :show="show"
  4 + mode="bottom"
  5 + closeable
  6 + @close="close"
  7 + :round="round"
  8 + :closeOnClickOverlay="closeOnClickOverlay"
  9 + >
  10 + <view class="u-calendar">
  11 + <uHeader
  12 + :title="title"
  13 + :subtitle="subtitle"
  14 + :showSubtitle="showSubtitle"
  15 + :showTitle="showTitle"
  16 + ></uHeader>
  17 + <scroll-view
  18 + :style="{
  19 + height: $u.addUnit(listHeight)
  20 + }"
  21 + scroll-y
  22 + @scroll="onScroll"
  23 + :scroll-top="scrollTop"
  24 + :scrollIntoView="scrollIntoView"
  25 + >
  26 + <uMonth
  27 + :color="color"
  28 + :rowHeight="rowHeight"
  29 + :showMark="showMark"
  30 + :months="months"
  31 + :mode="mode"
  32 + :maxCount="maxCount"
  33 + :startText="startText"
  34 + :endText="endText"
  35 + :defaultDate="defaultDate"
  36 + :minDate="innerMinDate"
  37 + :maxDate="innerMaxDate"
  38 + :maxMonth="monthNum"
  39 + :readonly="readonly"
  40 + :maxRange="maxRange"
  41 + :rangePrompt="rangePrompt"
  42 + :showRangePrompt="showRangePrompt"
  43 + :allowSameDay="allowSameDay"
  44 + ref="month"
  45 + @monthSelected="monthSelected"
  46 + @updateMonthTop="updateMonthTop"
  47 + ></uMonth>
  48 + </scroll-view>
  49 + <slot name="footer" v-if="showConfirm">
  50 + <view class="u-calendar__confirm">
  51 + <u-button
  52 + shape="circle"
  53 + :text="
  54 + buttonDisabled ? confirmDisabledText : confirmText
  55 + "
  56 + :color="color"
  57 + @click="confirm"
  58 + :disabled="buttonDisabled"
  59 + ></u-button>
  60 + </view>
  61 + </slot>
  62 + </view>
  63 + </u-popup>
  64 +</template>
  65 +
  66 +<script>
  67 +import uHeader from './header.vue'
  68 +import uMonth from './month.vue'
  69 +import props from './props.js'
  70 +import util from './util.js'
  71 +import dayjs from '../../libs/util/dayjs.js'
  72 +import Calendar from '../../libs/util/calendar.js'
  73 +/**
  74 + * Calendar 日历
  75 + * @description 此组件用于单个选择日期,范围选择日期等,日历被包裹在底部弹起的容器中.
  76 + * @tutorial https://www.uviewui.com/components/calendar.html
  77 + *
  78 + * @property {String} title 标题内容 (默认 日期选择 )
  79 + * @property {Boolean} showTitle 是否显示标题 (默认 true )
  80 + * @property {Boolean} showSubtitle 是否显示副标题 (默认 true )
  81 + * @property {String} mode 日期类型选择 single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围 ( 默认 'single' )
  82 + * @property {String} startText mode=range时,第一个日期底部的提示文字 (默认 '开始' )
  83 + * @property {String} endText mode=range时,最后一个日期底部的提示文字 (默认 '结束' )
  84 + * @property {Array} customList 自定义列表
  85 + * @property {String} color 主题色,对底部按钮和选中日期有效 (默认 ‘#3c9cff' )
  86 + * @property {String | Number} minDate 最小的可选日期 (默认 0 )
  87 + * @property {String | Number} maxDate 最大可选日期 (默认 0 )
  88 + * @property {Array | String| Date} defaultDate 默认选中的日期,mode为multiple或range是必须为数组格式
  89 + * @property {String | Number} maxCount mode=multiple时,最多可选多少个日期 (默认 Number.MAX_SAFE_INTEGER )
  90 + * @property {String | Number} rowHeight 日期行高 (默认 56 )
  91 + * @property {Function} formatter 日期格式化函数
  92 + * @property {Boolean} showLunar 是否显示农历 (默认 false )
  93 + * @property {Boolean} showMark 是否显示月份背景色 (默认 true )
  94 + * @property {String} confirmText 确定按钮的文字 (默认 '确定' )
  95 + * @property {String} confirmDisabledText 确认按钮处于禁用状态时的文字 (默认 '确定' )
  96 + * @property {Boolean} show 是否显示日历弹窗 (默认 false )
  97 + * @property {Boolean} closeOnClickOverlay 是否允许点击遮罩关闭日历 (默认 false )
  98 + * @property {Boolean} readonly 是否为只读状态,只读状态下禁止选择日期 (默认 false )
  99 + * @property {String | Number} maxRange 日期区间最多可选天数,默认无限制,mode = range时有效
  100 + * @property {String} rangePrompt 范围选择超过最多可选天数时的提示文案,mode = range时有效
  101 + * @property {Boolean} showRangePrompt 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效 (默认 true )
  102 + * @property {Boolean} allowSameDay 是否允许日期范围的起止时间为同一天,mode = range时有效 (默认 false )
  103 + * @property {Number|String} round 圆角值,默认无圆角 (默认 0 )
  104 + * @property {Number|String} monthNum 最多展示的月份数量 (默认 3 )
  105 + *
  106 + * @event {Function()} confirm 点击确定按钮时触发 选择日期相关的返回参数
  107 + * @event {Function()} close 日历关闭时触发 可定义页面关闭时的回调事件
  108 + * @example <u-calendar :defaultDate="defaultDateMultiple" :show="show" mode="multiple" @confirm="confirm">
  109 + </u-calendar>
  110 + * */
  111 +export default {
  112 + name: 'u-calendar',
  113 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  114 + components: {
  115 + uHeader,
  116 + uMonth
  117 + },
  118 + data() {
  119 + return {
  120 + // 需要显示的月份的数组
  121 + months: [],
  122 + // 在月份滚动区域中,当前视图中月份的index索引
  123 + monthIndex: 0,
  124 + // 月份滚动区域的高度
  125 + listHeight: 0,
  126 + // month组件中选择的日期数组
  127 + selected: [],
  128 + scrollIntoView: '',
  129 + scrollTop:0,
  130 + // 过滤处理方法
  131 + innerFormatter: (value) => value
  132 + }
  133 + },
  134 + watch: {
  135 + selectedChange: {
  136 + immediate: true,
  137 + handler(n) {
  138 + this.setMonth()
  139 + }
  140 + },
  141 + // 打开弹窗时,设置月份数据
  142 + show: {
  143 + immediate: true,
  144 + handler(n) {
  145 + this.setMonth()
  146 + }
  147 + }
  148 + },
  149 + computed: {
  150 + // 由于maxDate和minDate可以为字符串(2021-10-10),或者数值(时间戳),但是dayjs如果接受字符串形式的时间戳会有问题,这里进行处理
  151 + innerMaxDate() {
  152 + return uni.$u.test.number(this.maxDate)
  153 + ? Number(this.maxDate)
  154 + : this.maxDate
  155 + },
  156 + innerMinDate() {
  157 + return uni.$u.test.number(this.minDate)
  158 + ? Number(this.minDate)
  159 + : this.minDate
  160 + },
  161 + // 多个条件的变化,会引起选中日期的变化,这里统一管理监听
  162 + selectedChange() {
  163 + return [this.innerMinDate, this.innerMaxDate, this.defaultDate]
  164 + },
  165 + subtitle() {
  166 + // 初始化时,this.months为空数组,所以需要特别判断处理
  167 + if (this.months.length) {
  168 + return `${this.months[this.monthIndex].year}年${
  169 + this.months[this.monthIndex].month
  170 + }月`
  171 + } else {
  172 + return ''
  173 + }
  174 + },
  175 + buttonDisabled() {
  176 + // 如果为range类型,且选择的日期个数不足1个时,让底部的按钮出于disabled状态
  177 + if (this.mode === 'range') {
  178 + if (this.selected.length <= 1) {
  179 + return true
  180 + } else {
  181 + return false
  182 + }
  183 + } else {
  184 + return false
  185 + }
  186 + }
  187 + },
  188 + mounted() {
  189 + this.start = Date.now()
  190 + this.init()
  191 + },
  192 + methods: {
  193 + // 在微信小程序中,不支持将函数当做props参数,故只能通过ref形式调用
  194 + setFormatter(e) {
  195 + this.innerFormatter = e
  196 + },
  197 + // month组件内部选择日期后,通过事件通知给父组件
  198 + monthSelected(e) {
  199 + this.selected = e
  200 + if (!this.showConfirm) {
  201 + // 在不需要确认按钮的情况下,如果为单选,或者范围多选且已选长度大于2,则直接进行返还
  202 + if (
  203 + this.mode === 'multiple' ||
  204 + this.mode === 'single' ||
  205 + (this.mode === 'range' && this.selected.length >= 2)
  206 + ) {
  207 + this.$emit('confirm', this.selected)
  208 + }
  209 + }
  210 + },
  211 + init() {
  212 + // 校验maxDate,不能小于当前时间
  213 + if (
  214 + this.innerMaxDate &&
  215 + new Date(this.innerMaxDate).getTime() <= Date.now()
  216 + ) {
  217 + return uni.$u.error('maxDate不能小于当前时间')
  218 + }
  219 + // 滚动区域的高度
  220 + this.listHeight = this.rowHeight * 5 + 30
  221 + this.setMonth()
  222 + },
  223 + close() {
  224 + this.$emit('close')
  225 + },
  226 + // 点击确定按钮
  227 + confirm() {
  228 + if (!this.buttonDisabled) {
  229 + this.$emit('confirm', this.selected)
  230 + }
  231 + },
  232 + // 获得两个日期之间的月份数
  233 + getMonths(minDate, maxDate) {
  234 + const minYear = dayjs(minDate).year()
  235 + const minMonth = dayjs(minDate).month() + 1
  236 + const maxYear = dayjs(maxDate).year()
  237 + const maxMonth = dayjs(maxDate).month() + 1
  238 + return (maxYear - minYear) * 12 + (maxMonth - minMonth) + 1
  239 + },
  240 + // 设置月份数据
  241 + setMonth() {
  242 + // 最小日期的毫秒数
  243 + const minDate = this.innerMinDate || dayjs().valueOf()
  244 + // 如果没有指定最大日期,则往后推3个月
  245 + const maxDate =
  246 + this.innerMaxDate ||
  247 + dayjs(minDate)
  248 + .add(this.monthNum - 1, 'month')
  249 + .valueOf()
  250 + // 最大最小月份之间的共有多少个月份,
  251 + const months = uni.$u.range(
  252 + 1,
  253 + this.monthNum,
  254 + this.getMonths(minDate, maxDate)
  255 + )
  256 + // 先清空数组
  257 + this.months = []
  258 + for (let i = 0; i < months; i++) {
  259 + this.months.push({
  260 + date: new Array(
  261 + dayjs(minDate).add(i, 'month').daysInMonth()
  262 + )
  263 + .fill(1)
  264 + .map((item, index) => {
  265 + // 日期,取值1-31
  266 + let day = index + 1
  267 + // 星期,0-6,0为周日
  268 + const week = dayjs(minDate)
  269 + .add(i, 'month')
  270 + .date(day)
  271 + .day()
  272 + const date = dayjs(minDate)
  273 + .add(i, 'month')
  274 + .date(day)
  275 + .format('YYYY-MM-DD')
  276 + let bottomInfo = ''
  277 + if (this.showLunar) {
  278 + // 将日期转为农历格式
  279 + const lunar = Calendar.solar2lunar(
  280 + dayjs(date).year(),
  281 + dayjs(date).month() + 1,
  282 + dayjs(date).date()
  283 + )
  284 + bottomInfo = lunar.IDayCn
  285 + }
  286 + let config = {
  287 + day,
  288 + week,
  289 + // 小于最小允许的日期,或者大于最大的日期,则设置为disabled状态
  290 + disabled:
  291 + dayjs(date).isBefore(
  292 + dayjs(minDate).format('YYYY-MM-DD')
  293 + ) ||
  294 + dayjs(date).isAfter(
  295 + dayjs(maxDate).format('YYYY-MM-DD')
  296 + ),
  297 + // 返回一个日期对象,供外部的formatter获取当前日期的年月日等信息,进行加工处理
  298 + date: new Date(date),
  299 + bottomInfo,
  300 + dot: false,
  301 + month:
  302 + dayjs(minDate).add(i, 'month').month() + 1
  303 + }
  304 + const formatter =
  305 + this.formatter || this.innerFormatter
  306 + return formatter(config)
  307 + }),
  308 + // 当前所属的月份
  309 + month: dayjs(minDate).add(i, 'month').month() + 1,
  310 + // 当前年份
  311 + year: dayjs(minDate).add(i, 'month').year()
  312 + })
  313 + }
  314 +
  315 + },
  316 + // 滚动到默认设置的月份
  317 + scrollIntoDefaultMonth(selected) {
  318 + // 查询默认日期在可选列表的下标
  319 + const _index = this.months.findIndex(({
  320 + year,
  321 + month
  322 + }) => {
  323 + month = uni.$u.padZero(month)
  324 + return `${year}-${month}` === selected
  325 + })
  326 + if (_index !== -1) {
  327 + // #ifndef MP-WEIXIN
  328 + this.$nextTick(() => {
  329 + this.scrollIntoView = `month-${_index}`
  330 + })
  331 + // #endif
  332 + // #ifdef MP-WEIXIN
  333 + this.scrollTop = this.months[_index].top || 0;
  334 + // #endif
  335 + }
  336 + },
  337 + // scroll-view滚动监听
  338 + onScroll(event) {
  339 + // 不允许小于0的滚动值,如果scroll-view到顶了,继续下拉,会出现负数值
  340 + const scrollTop = Math.max(0, event.detail.scrollTop)
  341 + // 将当前滚动条数值,除以滚动区域的高度,可以得出当前滚动到了哪一个月份的索引
  342 + for (let i = 0; i < this.months.length; i++) {
  343 + if (scrollTop >= (this.months[i].top || this.listHeight)) {
  344 + this.monthIndex = i
  345 + }
  346 + }
  347 + },
  348 + // 更新月份的top值
  349 + updateMonthTop(topArr = []) {
  350 + // 设置对应月份的top值,用于onScroll方法更新月份
  351 + topArr.map((item, index) => {
  352 + this.months[index].top = item
  353 + })
  354 +
  355 + // 获取默认日期的下标
  356 + if (!this.defaultDate) {
  357 + // 如果没有设置默认日期,则将当天日期设置为默认选中的日期
  358 + const selected = dayjs().format("YYYY-MM")
  359 + this.scrollIntoDefaultMonth(selected)
  360 + return
  361 + }
  362 + let selected = dayjs().format("YYYY-MM");
  363 + // 单选模式,可以是字符串或数组,Date对象等
  364 + if (!uni.$u.test.array(this.defaultDate)) {
  365 + selected = dayjs(this.defaultDate).format("YYYY-MM")
  366 + } else {
  367 + selected = dayjs(this.defaultDate[0]).format("YYYY-MM");
  368 + }
  369 + this.scrollIntoDefaultMonth(selected)
  370 + }
  371 + }
  372 +}
  373 +</script>
  374 +
  375 +<style lang="scss" scoped>
  376 +@import '../../libs/css/components.scss';
  377 +
  378 +.u-calendar {
  379 + &__confirm {
  380 + padding: 7px 18px;
  381 + }
  382 +}
  383 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-calendar/util.js 0 → 100644
  1 +export default {
  2 + methods: {
  3 + // 设置月份数据
  4 + setMonth() {
  5 + // 月初是周几
  6 + const day = dayjs(this.date).date(1).day()
  7 + const start = day == 0 ? 6 : day - 1
  8 +
  9 + // 本月天数
  10 + const days = dayjs(this.date).endOf('month').format('D')
  11 +
  12 + // 上个月天数
  13 + const prevDays = dayjs(this.date).endOf('month').subtract(1, 'month').format('D')
  14 +
  15 + // 日期数据
  16 + const arr = []
  17 + // 清空表格
  18 + this.month = []
  19 +
  20 + // 添加上月数据
  21 + arr.push(
  22 + ...new Array(start).fill(1).map((e, i) => {
  23 + const day = prevDays - start + i + 1
  24 +
  25 + return {
  26 + value: day,
  27 + disabled: true,
  28 + date: dayjs(this.date).subtract(1, 'month').date(day).format('YYYY-MM-DD')
  29 + }
  30 + })
  31 + )
  32 +
  33 + // 添加本月数据
  34 + arr.push(
  35 + ...new Array(days - 0).fill(1).map((e, i) => {
  36 + const day = i + 1
  37 +
  38 + return {
  39 + value: day,
  40 + date: dayjs(this.date).date(day).format('YYYY-MM-DD')
  41 + }
  42 + })
  43 + )
  44 +
  45 + // 添加下个月
  46 + arr.push(
  47 + ...new Array(42 - days - start).fill(1).map((e, i) => {
  48 + const day = i + 1
  49 +
  50 + return {
  51 + value: day,
  52 + disabled: true,
  53 + date: dayjs(this.date).add(1, 'month').date(day).format('YYYY-MM-DD')
  54 + }
  55 + })
  56 + )
  57 +
  58 + // 分割数组
  59 + for (let n = 0; n < arr.length; n += 7) {
  60 + this.month.push(
  61 + arr.slice(n, n + 7).map((e, i) => {
  62 + e.index = i + n
  63 +
  64 + // 自定义信息
  65 + const custom = this.customList.find((c) => c.date == e.date)
  66 +
  67 + // 农历
  68 + if (this.lunar) {
  69 + const {
  70 + IDayCn,
  71 + IMonthCn
  72 + } = this.getLunar(e.date)
  73 + e.lunar = IDayCn == '初一' ? IMonthCn : IDayCn
  74 + }
  75 +
  76 + return {
  77 + ...e,
  78 + ...custom
  79 + }
  80 + })
  81 + )
  82 + }
  83 + }
  84 + }
  85 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-car-keyboard/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 是否打乱键盘按键的顺序
  4 + random: {
  5 + type: Boolean,
  6 + default: false
  7 + },
  8 + // 输入一个中文后,是否自动切换到英文
  9 + autoChange: {
  10 + type: Boolean,
  11 + default: false
  12 + }
  13 + }
  14 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-car-keyboard/u-car-keyboard.vue 0 → 100644
  1 +<template>
  2 + <view
  3 + class="u-keyboard"
  4 + @touchmove.stop.prevent="noop"
  5 + >
  6 + <view
  7 + v-for="(group, i) in abc ? engKeyBoardList : areaList"
  8 + :key="i"
  9 + class="u-keyboard__button"
  10 + :index="i"
  11 + :class="[i + 1 === 4 && 'u-keyboard__button--center']"
  12 + >
  13 + <view
  14 + v-if="i === 3"
  15 + class="u-keyboard__button__inner-wrapper"
  16 + >
  17 + <view
  18 + class="u-keyboard__button__inner-wrapper__left"
  19 + hover-class="u-hover-class"
  20 + :hover-stay-time="200"
  21 + @tap="changeCarInputMode"
  22 + >
  23 + <text
  24 + class="u-keyboard__button__inner-wrapper__left__lang"
  25 + :class="[!abc && 'u-keyboard__button__inner-wrapper__left__lang--active']"
  26 + >中</text>
  27 + <text class="u-keyboard__button__inner-wrapper__left__line">/</text>
  28 + <text
  29 + class="u-keyboard__button__inner-wrapper__left__lang"
  30 + :class="[abc && 'u-keyboard__button__inner-wrapper__left__lang--active']"
  31 + >英</text>
  32 + </view>
  33 + </view>
  34 + <view
  35 + class="u-keyboard__button__inner-wrapper"
  36 + v-for="(item, j) in group"
  37 + :key="j"
  38 + >
  39 + <view
  40 + class="u-keyboard__button__inner-wrapper__inner"
  41 + :hover-stay-time="200"
  42 + @tap="carInputClick(i, j)"
  43 + hover-class="u-hover-class"
  44 + >
  45 + <text class="u-keyboard__button__inner-wrapper__inner__text">{{ item }}</text>
  46 + </view>
  47 + </view>
  48 + <view
  49 + v-if="i === 3"
  50 + @touchstart="backspaceClick"
  51 + @touchend="clearTimer"
  52 + class="u-keyboard__button__inner-wrapper"
  53 + >
  54 + <view
  55 + class="u-keyboard__button__inner-wrapper__right"
  56 + hover-class="u-hover-class"
  57 + :hover-stay-time="200"
  58 + >
  59 + <u-icon
  60 + size="28"
  61 + name="backspace"
  62 + color="#303133"
  63 + ></u-icon>
  64 + </view>
  65 + </view>
  66 + </view>
  67 + </view>
  68 +</template>
  69 +
  70 +<script>
  71 + import props from './props.js';
  72 + /**
  73 + * keyboard 键盘组件
  74 + * @description 此为uView自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3种模式,都有可以打乱按键顺序的选项。
  75 + * @tutorial https://uviewui.com/components/keyboard.html
  76 + * @property {Boolean} random 是否打乱键盘的顺序
  77 + * @event {Function} change 点击键盘触发
  78 + * @event {Function} backspace 点击退格键触发
  79 + * @example <u-keyboard ref="uKeyboard" mode="car" v-model="show"></u-keyboard>
  80 + */
  81 + export default {
  82 + name: "u-keyboard",
  83 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  84 + data() {
  85 + return {
  86 + // 车牌输入时,abc=true为输入车牌号码,bac=false为输入省份中文简称
  87 + abc: false
  88 + };
  89 + },
  90 + computed: {
  91 + areaList() {
  92 + let data = [
  93 + '京',
  94 + '沪',
  95 + '粤',
  96 + '津',
  97 + '冀',
  98 + '豫',
  99 + '云',
  100 + '辽',
  101 + '黑',
  102 + '湘',
  103 + '皖',
  104 + '鲁',
  105 + '苏',
  106 + '浙',
  107 + '赣',
  108 + '鄂',
  109 + '桂',
  110 + '甘',
  111 + '晋',
  112 + '陕',
  113 + '蒙',
  114 + '吉',
  115 + '闽',
  116 + '贵',
  117 + '渝',
  118 + '川',
  119 + '青',
  120 + '琼',
  121 + '宁',
  122 + '挂',
  123 + '藏',
  124 + '港',
  125 + '澳',
  126 + '新',
  127 + '使',
  128 + '学'
  129 + ];
  130 + let tmp = [];
  131 + // 打乱顺序
  132 + if (this.random) data = uni.$u.randomArray(data);
  133 + // 切割成二维数组
  134 + tmp[0] = data.slice(0, 10);
  135 + tmp[1] = data.slice(10, 20);
  136 + tmp[2] = data.slice(20, 30);
  137 + tmp[3] = data.slice(30, 36);
  138 + return tmp;
  139 + },
  140 + engKeyBoardList() {
  141 + let data = [
  142 + 1,
  143 + 2,
  144 + 3,
  145 + 4,
  146 + 5,
  147 + 6,
  148 + 7,
  149 + 8,
  150 + 9,
  151 + 0,
  152 + 'Q',
  153 + 'W',
  154 + 'E',
  155 + 'R',
  156 + 'T',
  157 + 'Y',
  158 + 'U',
  159 + 'I',
  160 + 'O',
  161 + 'P',
  162 + 'A',
  163 + 'S',
  164 + 'D',
  165 + 'F',
  166 + 'G',
  167 + 'H',
  168 + 'J',
  169 + 'K',
  170 + 'L',
  171 + 'Z',
  172 + 'X',
  173 + 'C',
  174 + 'V',
  175 + 'B',
  176 + 'N',
  177 + 'M'
  178 + ];
  179 + let tmp = [];
  180 + if (this.random) data = uni.$u.randomArray(data);
  181 + tmp[0] = data.slice(0, 10);
  182 + tmp[1] = data.slice(10, 20);
  183 + tmp[2] = data.slice(20, 30);
  184 + tmp[3] = data.slice(30, 36);
  185 + return tmp;
  186 + }
  187 + },
  188 + methods: {
  189 + // 点击键盘按钮
  190 + carInputClick(i, j) {
  191 + let value = '';
  192 + // 不同模式,获取不同数组的值
  193 + if (this.abc) value = this.engKeyBoardList[i][j];
  194 + else value = this.areaList[i][j];
  195 + // 如果允许自动切换,则将中文状态切换为英文
  196 + if (!this.abc && this.autoChange) uni.$u.sleep(200).then(() => this.abc = true)
  197 + this.$emit('change', value);
  198 + },
  199 + // 修改汽车牌键盘的输入模式,中文|英文
  200 + changeCarInputMode() {
  201 + this.abc = !this.abc;
  202 + },
  203 + // 点击退格键
  204 + backspaceClick() {
  205 + this.$emit('backspace');
  206 + clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
  207 + this.timer = null;
  208 + this.timer = setInterval(() => {
  209 + this.$emit('backspace');
  210 + }, 250);
  211 + },
  212 + clearTimer() {
  213 + clearInterval(this.timer);
  214 + this.timer = null;
  215 + },
  216 + }
  217 + };
  218 +</script>
  219 +
  220 +<style lang="scss" scoped>
  221 + @import "../../libs/css/components.scss";
  222 + $u-car-keyboard-background-color: rgb(224, 228, 230) !default;
  223 + $u-car-keyboard-padding:6px 0 6px !default;
  224 + $u-car-keyboard-button-inner-width:64rpx !default;
  225 + $u-car-keyboard-button-inner-background-color:#FFFFFF !default;
  226 + $u-car-keyboard-button-height:80rpx !default;
  227 + $u-car-keyboard-button-inner-box-shadow:0 1px 0px #999992 !default;
  228 + $u-car-keyboard-button-border-radius:4px !default;
  229 + $u-car-keyboard-button-inner-margin:8rpx 5rpx !default;
  230 + $u-car-keyboard-button-text-font-size:16px !default;
  231 + $u-car-keyboard-button-text-color:$u-main-color !default;
  232 + $u-car-keyboard-center-inner-margin: 0 4rpx !default;
  233 + $u-car-keyboard-special-button-width:134rpx !default;
  234 + $u-car-keyboard-lang-font-size:16px !default;
  235 + $u-car-keyboard-lang-color:$u-main-color !default;
  236 + $u-car-keyboard-active-color:$u-primary !default;
  237 + $u-car-keyboard-line-font-size:15px !default;
  238 + $u-car-keyboard-line-color:$u-main-color !default;
  239 + $u-car-keyboard-line-margin:0 1px !default;
  240 + $u-car-keyboard-u-hover-class-background-color:#BBBCC6 !default;
  241 +
  242 + .u-keyboard {
  243 + @include flex(column);
  244 + justify-content: space-around;
  245 + background-color: $u-car-keyboard-background-color;
  246 + align-items: stretch;
  247 + padding: $u-car-keyboard-padding;
  248 +
  249 + &__button {
  250 + @include flex;
  251 + justify-content: center;
  252 + flex: 1;
  253 + /* #ifndef APP-NVUE */
  254 + /* #endif */
  255 +
  256 + &__inner-wrapper {
  257 + box-shadow: $u-car-keyboard-button-inner-box-shadow;
  258 + margin: $u-car-keyboard-button-inner-margin;
  259 + border-radius: $u-car-keyboard-button-border-radius;
  260 +
  261 + &__inner {
  262 + @include flex;
  263 + justify-content: center;
  264 + align-items: center;
  265 + width: $u-car-keyboard-button-inner-width;
  266 + background-color: $u-car-keyboard-button-inner-background-color;
  267 + height: $u-car-keyboard-button-height;
  268 + border-radius: $u-car-keyboard-button-border-radius;
  269 +
  270 + &__text {
  271 + font-size: $u-car-keyboard-button-text-font-size;
  272 + color: $u-car-keyboard-button-text-color;
  273 + }
  274 + }
  275 +
  276 + &__left,
  277 + &__right {
  278 + border-radius: $u-car-keyboard-button-border-radius;
  279 + width: $u-car-keyboard-special-button-width;
  280 + height: $u-car-keyboard-button-height;
  281 + background-color: $u-car-keyboard-u-hover-class-background-color;
  282 + @include flex;
  283 + justify-content: center;
  284 + align-items: center;
  285 + box-shadow: $u-car-keyboard-button-inner-box-shadow;
  286 + }
  287 +
  288 + &__left {
  289 + &__line {
  290 + font-size: $u-car-keyboard-line-font-size;
  291 + color: $u-car-keyboard-line-color;
  292 + margin: $u-car-keyboard-line-margin;
  293 + }
  294 +
  295 + &__lang {
  296 + font-size: $u-car-keyboard-lang-font-size;
  297 + color: $u-car-keyboard-lang-color;
  298 +
  299 + &--active {
  300 + color: $u-car-keyboard-active-color;
  301 + }
  302 + }
  303 + }
  304 + }
  305 + }
  306 + }
  307 +
  308 + .u-hover-class {
  309 + background-color: $u-car-keyboard-u-hover-class-background-color;
  310 + }
  311 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-cell-group/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 分组标题
  4 + title: {
  5 + type: String,
  6 + default: uni.$u.props.cellGroup.title
  7 + },
  8 + // 是否显示外边框
  9 + border: {
  10 + type: Boolean,
  11 + default: uni.$u.props.cellGroup.border
  12 + }
  13 + }
  14 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-cell-group/u-cell-group.vue 0 → 100644
  1 +<template>
  2 + <view :style="[$u.addStyle(customStyle)]" :class="[customClass]" class="u-cell-group">
  3 + <view v-if="title" class="u-cell-group__title">
  4 + <slot name="title">
  5 + <text class="u-cell-group__title__text">{{ title }}</text>
  6 + </slot>
  7 + </view>
  8 + <view class="u-cell-group__wrapper">
  9 + <u-line v-if="border"></u-line>
  10 + <slot />
  11 + </view>
  12 + </view>
  13 +</template>
  14 +
  15 +<script>
  16 + import props from './props.js';
  17 + /**
  18 + * cellGroup 单元格
  19 + * @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。
  20 + * @tutorial https://uviewui.com/components/cell.html
  21 + *
  22 + * @property {String} title 分组标题
  23 + * @property {Boolean} border 是否显示外边框 (默认 true )
  24 + * @property {Object} customStyle 定义需要用到的外部样式
  25 + *
  26 + * @event {Function} click 点击cell列表时触发
  27 + * @example <u-cell-group title="设置喜好">
  28 + */
  29 + export default {
  30 + name: 'u-cell-group',
  31 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  32 + }
  33 +</script>
  34 +
  35 +<style lang="scss" scoped>
  36 + @import "../../libs/css/components.scss";
  37 +
  38 + $u-cell-group-title-padding: 16px 16px 8px !default;
  39 + $u-cell-group-title-font-size: 15px !default;
  40 + $u-cell-group-title-line-height: 16px !default;
  41 + $u-cell-group-title-color: $u-main-color !default;
  42 +
  43 + .u-cell-group {
  44 + flex: 1;
  45 +
  46 + &__title {
  47 + padding: $u-cell-group-title-padding;
  48 +
  49 + &__text {
  50 + font-size: $u-cell-group-title-font-size;
  51 + line-height: $u-cell-group-title-line-height;
  52 + color: $u-cell-group-title-color;
  53 + }
  54 + }
  55 +
  56 + &__wrapper {
  57 + position: relative;
  58 + }
  59 + }
  60 +</style>
  61 +
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-cell/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 标题
  4 + title: {
  5 + type: [String, Number],
  6 + default: uni.$u.props.cell.title
  7 + },
  8 + // 标题下方的描述信息
  9 + label: {
  10 + type: [String, Number],
  11 + default: uni.$u.props.cell.label
  12 + },
  13 + // 右侧的内容
  14 + value: {
  15 + type: [String, Number],
  16 + default: uni.$u.props.cell.value
  17 + },
  18 + // 左侧图标名称,或者图片链接(本地文件建议使用绝对地址)
  19 + icon: {
  20 + type: String,
  21 + default: uni.$u.props.cell.icon
  22 + },
  23 + // 是否禁用cell
  24 + disabled: {
  25 + type: Boolean,
  26 + default: uni.$u.props.cell.disabled
  27 + },
  28 + // 是否显示下边框
  29 + border: {
  30 + type: Boolean,
  31 + default: uni.$u.props.cell.border
  32 + },
  33 + // 内容是否垂直居中(主要是针对右侧的value部分)
  34 + center: {
  35 + type: Boolean,
  36 + default: uni.$u.props.cell.center
  37 + },
  38 + // 点击后跳转的URL地址
  39 + url: {
  40 + type: String,
  41 + default: uni.$u.props.cell.url
  42 + },
  43 + // 链接跳转的方式,内部使用的是uView封装的route方法,可能会进行拦截操作
  44 + linkType: {
  45 + type: String,
  46 + default: uni.$u.props.cell.linkType
  47 + },
  48 + // 是否开启点击反馈(表现为点击时加上灰色背景)
  49 + clickable: {
  50 + type: Boolean,
  51 + default: uni.$u.props.cell.clickable
  52 + },
  53 + // 是否展示右侧箭头并开启点击反馈
  54 + isLink: {
  55 + type: Boolean,
  56 + default: uni.$u.props.cell.isLink
  57 + },
  58 + // 是否显示表单状态下的必填星号(此组件可能会内嵌入input组件)
  59 + required: {
  60 + type: Boolean,
  61 + default: uni.$u.props.cell.required
  62 + },
  63 + // 右侧的图标箭头
  64 + rightIcon: {
  65 + type: String,
  66 + default: uni.$u.props.cell.rightIcon
  67 + },
  68 + // 右侧箭头的方向,可选值为:left,up,down
  69 + arrowDirection: {
  70 + type: String,
  71 + default: uni.$u.props.cell.arrowDirection
  72 + },
  73 + // 左侧图标样式
  74 + iconStyle: {
  75 + type: [Object, String],
  76 + default: () => {
  77 + return uni.$u.props.cell.iconStyle
  78 + }
  79 + },
  80 + // 右侧箭头图标的样式
  81 + rightIconStyle: {
  82 + type: [Object, String],
  83 + default: () => {
  84 + return uni.$u.props.cell.rightIconStyle
  85 + }
  86 + },
  87 + // 标题的样式
  88 + titleStyle: {
  89 + type: [Object, String],
  90 + default: () => {
  91 + return uni.$u.props.cell.titleStyle
  92 + }
  93 + },
  94 + // 单位元的大小,可选值为large
  95 + size: {
  96 + type: String,
  97 + default: uni.$u.props.cell.size
  98 + },
  99 + // 点击cell是否阻止事件传播
  100 + stop: {
  101 + type: Boolean,
  102 + default: uni.$u.props.cell.stop
  103 + },
  104 + // 标识符,cell被点击时返回
  105 + name: {
  106 + type: [Number, String],
  107 + default: uni.$u.props.cell.name
  108 + }
  109 + }
  110 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-cell/u-cell.vue 0 → 100644
  1 +<template>
  2 + <view class="u-cell" :class="[customClass]" :style="[$u.addStyle(customStyle)]"
  3 + :hover-class="(!disabled && (clickable || isLink)) ? 'u-cell--clickable' : ''" :hover-stay-time="250"
  4 + @tap="clickHandler">
  5 + <view class="u-cell__body" :class="[ center && 'u-cell--center', size === 'large' && 'u-cell__body--large']">
  6 + <view class="u-cell__body__content">
  7 + <view class="u-cell__left-icon-wrap" v-if="$slots.icon || icon">
  8 + <slot name="icon" v-if="$slots.icon">
  9 + </slot>
  10 + <u-icon v-else :name="icon" :custom-style="iconStyle" :size="size === 'large' ? 22 : 18"></u-icon>
  11 + </view>
  12 + <view class="u-cell__title">
  13 + <slot name="title">
  14 + <text v-if="title" class="u-cell__title-text" :style="[titleTextStyle]"
  15 + :class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__title-text--large']">{{ title }}</text>
  16 + </slot>
  17 + <slot name="label">
  18 + <text class="u-cell__label" v-if="label"
  19 + :class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__label--large']">{{ label }}</text>
  20 + </slot>
  21 + </view>
  22 + </view>
  23 + <slot name="value">
  24 + <text class="u-cell__value"
  25 + :class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__value--large']"
  26 + v-if="!$u.test.empty(value)">{{ value }}</text>
  27 + </slot>
  28 + <view class="u-cell__right-icon-wrap" v-if="$slots['right-icon'] || isLink"
  29 + :class="[`u-cell__right-icon-wrap--${arrowDirection}`]">
  30 + <slot name="right-icon" v-if="$slots['right-icon']">
  31 + </slot>
  32 + <u-icon v-else :name="rightIcon" :custom-style="rightIconStyle" :color="disabled ? '#c8c9cc' : 'info'"
  33 + :size="size === 'large' ? 18 : 16"></u-icon>
  34 + </view>
  35 + </view>
  36 + <u-line v-if="border"></u-line>
  37 + </view>
  38 +</template>
  39 +
  40 +<script>
  41 + import props from './props.js';
  42 + /**
  43 + * cell 单元格
  44 + * @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。
  45 + * @tutorial https://uviewui.com/components/cell.html
  46 + * @property {String | Number} title 标题
  47 + * @property {String | Number} label 标题下方的描述信息
  48 + * @property {String | Number} value 右侧的内容
  49 + * @property {String} icon 左侧图标名称,或者图片链接(本地文件建议使用绝对地址)
  50 + * @property {Boolean} disabled 是否禁用cell
  51 + * @property {Boolean} border 是否显示下边框 (默认 true )
  52 + * @property {Boolean} center 内容是否垂直居中(主要是针对右侧的value部分) (默认 false )
  53 + * @property {String} url 点击后跳转的URL地址
  54 + * @property {String} linkType 链接跳转的方式,内部使用的是uView封装的route方法,可能会进行拦截操作 (默认 'navigateTo' )
  55 + * @property {Boolean} clickable 是否开启点击反馈(表现为点击时加上灰色背景) (默认 false )
  56 + * @property {Boolean} isLink 是否展示右侧箭头并开启点击反馈 (默认 false )
  57 + * @property {Boolean} required 是否显示表单状态下的必填星号(此组件可能会内嵌入input组件) (默认 false )
  58 + * @property {String} rightIcon 右侧的图标箭头 (默认 'arrow-right')
  59 + * @property {String} arrowDirection 右侧箭头的方向,可选值为:left,up,down
  60 + * @property {Object | String} rightIconStyle 右侧箭头图标的样式
  61 + * @property {Object | String} titleStyle 标题的样式
  62 + * @property {Object | String} iconStyle 左侧图标样式
  63 + * @property {String} size 单位元的大小,可选值为 large,normal,mini
  64 + * @property {Boolean} stop 点击cell是否阻止事件传播 (默认 true )
  65 + * @property {Object} customStyle 定义需要用到的外部样式
  66 + *
  67 + * @event {Function} click 点击cell列表时触发
  68 + * @example 该组件需要搭配cell-group组件使用,见官方文档示例
  69 + */
  70 + export default {
  71 + name: 'u-cell',
  72 + data() {
  73 + return {
  74 +
  75 + }
  76 + },
  77 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  78 + computed: {
  79 + titleTextStyle() {
  80 + return uni.$u.addStyle(this.titleStyle)
  81 + }
  82 + },
  83 + methods: {
  84 + // 点击cell
  85 + clickHandler(e) {
  86 + if (this.disabled) return
  87 + this.$emit('click', {
  88 + name: this.name
  89 + })
  90 + // 如果配置了url(此props参数通过mixin引入)参数,跳转页面
  91 + this.openPage()
  92 + // 是否阻止事件传播
  93 + this.stop && this.preventEvent(e)
  94 + },
  95 + }
  96 + }
  97 +</script>
  98 +
  99 +<style lang="scss" scoped>
  100 + @import "../../libs/css/components.scss";
  101 +
  102 + $u-cell-padding: 10px 15px !default;
  103 + $u-cell-font-size: 15px !default;
  104 + $u-cell-line-height: 24px !default;
  105 + $u-cell-color: $u-main-color !default;
  106 + $u-cell-icon-size: 16px !default;
  107 + $u-cell-title-font-size: 15px !default;
  108 + $u-cell-title-line-height: 22px !default;
  109 + $u-cell-title-color: $u-main-color !default;
  110 + $u-cell-label-font-size: 12px !default;
  111 + $u-cell-label-color: $u-tips-color !default;
  112 + $u-cell-label-line-height: 18px !default;
  113 + $u-cell-value-font-size: 14px !default;
  114 + $u-cell-value-color: $u-content-color !default;
  115 + $u-cell-clickable-color: $u-bg-color !default;
  116 + $u-cell-disabled-color: #c8c9cc !default;
  117 + $u-cell-padding-top-large: 13px !default;
  118 + $u-cell-padding-bottom-large: 13px !default;
  119 + $u-cell-value-font-size-large: 15px !default;
  120 + $u-cell-label-font-size-large: 14px !default;
  121 + $u-cell-title-font-size-large: 16px !default;
  122 + $u-cell-left-icon-wrap-margin-right: 4px !default;
  123 + $u-cell-right-icon-wrap-margin-left: 4px !default;
  124 + $u-cell-title-flex:1 !default;
  125 + $u-cell-label-margin-top:5px !default;
  126 +
  127 +
  128 + .u-cell {
  129 + &__body {
  130 + @include flex();
  131 + /* #ifndef APP-NVUE */
  132 + box-sizing: border-box;
  133 + /* #endif */
  134 + padding: $u-cell-padding;
  135 + font-size: $u-cell-font-size;
  136 + color: $u-cell-color;
  137 + // line-height: $u-cell-line-height;
  138 + align-items: center;
  139 +
  140 + &__content {
  141 + @include flex(row);
  142 + align-items: center;
  143 + flex: 1;
  144 + }
  145 +
  146 + &--large {
  147 + padding-top: $u-cell-padding-top-large;
  148 + padding-bottom: $u-cell-padding-bottom-large;
  149 + }
  150 + }
  151 +
  152 + &__left-icon-wrap,
  153 + &__right-icon-wrap {
  154 + @include flex();
  155 + align-items: center;
  156 + // height: $u-cell-line-height;
  157 + font-size: $u-cell-icon-size;
  158 + }
  159 +
  160 + &__left-icon-wrap {
  161 + margin-right: $u-cell-left-icon-wrap-margin-right;
  162 + }
  163 +
  164 + &__right-icon-wrap {
  165 + margin-left: $u-cell-right-icon-wrap-margin-left;
  166 + transition: transform 0.3s;
  167 +
  168 + &--up {
  169 + transform: rotate(-90deg);
  170 + }
  171 +
  172 + &--down {
  173 + transform: rotate(90deg);
  174 + }
  175 + }
  176 +
  177 + &__title {
  178 + flex: $u-cell-title-flex;
  179 +
  180 + &-text {
  181 + font-size: $u-cell-title-font-size;
  182 + line-height: $u-cell-title-line-height;
  183 + color: $u-cell-title-color;
  184 +
  185 + &--large {
  186 + font-size: $u-cell-title-font-size-large;
  187 + }
  188 + }
  189 +
  190 + }
  191 +
  192 + &__label {
  193 + margin-top: $u-cell-label-margin-top;
  194 + font-size: $u-cell-label-font-size;
  195 + color: $u-cell-label-color;
  196 + line-height: $u-cell-label-line-height;
  197 +
  198 + &--large {
  199 + font-size: $u-cell-label-font-size-large;
  200 + }
  201 + }
  202 +
  203 + &__value {
  204 + text-align: right;
  205 + font-size: $u-cell-value-font-size;
  206 + line-height: $u-cell-line-height;
  207 + color: $u-cell-value-color;
  208 +
  209 + &--large {
  210 + font-size: $u-cell-value-font-size-large;
  211 + }
  212 + }
  213 +
  214 + &--clickable {
  215 + background-color: $u-cell-clickable-color;
  216 + }
  217 +
  218 + &--disabled {
  219 + color: $u-cell-disabled-color;
  220 + /* #ifndef APP-NVUE */
  221 + cursor: not-allowed;
  222 + /* #endif */
  223 + }
  224 +
  225 + &--center {
  226 + align-items: center;
  227 + }
  228 + }
  229 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-checkbox-group/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 标识符
  4 + name: {
  5 + type: String,
  6 + default: uni.$u.props.checkboxGroup.name
  7 + },
  8 + // 绑定的值
  9 + value: {
  10 + type: Array,
  11 + default: uni.$u.props.checkboxGroup.value
  12 + },
  13 + // 形状,circle-圆形,square-方形
  14 + shape: {
  15 + type: String,
  16 + default: uni.$u.props.checkboxGroup.shape
  17 + },
  18 + // 是否禁用全部checkbox
  19 + disabled: {
  20 + type: Boolean,
  21 + default: uni.$u.props.checkboxGroup.disabled
  22 + },
  23 +
  24 + // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
  25 + activeColor: {
  26 + type: String,
  27 + default: uni.$u.props.checkboxGroup.activeColor
  28 + },
  29 + // 未选中的颜色
  30 + inactiveColor: {
  31 + type: String,
  32 + default: uni.$u.props.checkboxGroup.inactiveColor
  33 + },
  34 +
  35 + // 整个组件的尺寸,默认px
  36 + size: {
  37 + type: [String, Number],
  38 + default: uni.$u.props.checkboxGroup.size
  39 + },
  40 + // 布局方式,row-横向,column-纵向
  41 + placement: {
  42 + type: String,
  43 + default: uni.$u.props.checkboxGroup.placement
  44 + },
  45 + // label的字体大小,px单位
  46 + labelSize: {
  47 + type: [String, Number],
  48 + default: uni.$u.props.checkboxGroup.labelSize
  49 + },
  50 + // label的字体颜色
  51 + labelColor: {
  52 + type: [String],
  53 + default: uni.$u.props.checkboxGroup.labelColor
  54 + },
  55 + // 是否禁止点击文本操作
  56 + labelDisabled: {
  57 + type: Boolean,
  58 + default: uni.$u.props.checkboxGroup.labelDisabled
  59 + },
  60 + // 图标颜色
  61 + iconColor: {
  62 + type: String,
  63 + default: uni.$u.props.checkboxGroup.iconColor
  64 + },
  65 + // 图标的大小,单位px
  66 + iconSize: {
  67 + type: [String, Number],
  68 + default: uni.$u.props.checkboxGroup.iconSize
  69 + },
  70 + // 勾选图标的对齐方式,left-左边,right-右边
  71 + iconPlacement: {
  72 + type: String,
  73 + default: uni.$u.props.checkboxGroup.iconPlacement
  74 + },
  75 + // 竖向配列时,是否显示下划线
  76 + borderBottom: {
  77 + type: Boolean,
  78 + default: uni.$u.props.checkboxGroup.borderBottom
  79 + }
  80 +
  81 + }
  82 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue 0 → 100644
  1 +<template>
  2 + <view
  3 + class="u-checkbox-group"
  4 + :class="bemClass"
  5 + >
  6 + <slot></slot>
  7 + </view>
  8 +</template>
  9 +
  10 +<script>
  11 + import props from './props.js';
  12 + /**
  13 + * checkboxGroup 复选框组
  14 + * @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
  15 + * @tutorial https://www.uviewui.com/components/checkbox.html
  16 + * @property {String} name 标识符
  17 + * @property {Array} value 绑定的值
  18 + * @property {String} shape 形状,circle-圆形,square-方形 (默认 'square' )
  19 + * @property {Boolean} disabled 是否禁用全部checkbox (默认 false )
  20 + * @property {String} activeColor 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 (默认 '#2979ff' )
  21 + * @property {String} inactiveColor 未选中的颜色 (默认 '#c8c9cc' )
  22 + * @property {String | Number} size 整个组件的尺寸 单位px (默认 18 )
  23 + * @property {String} placement 布局方式,row-横向,column-纵向 (默认 'row' )
  24 + * @property {String | Number} labelSize label的字体大小,px单位 (默认 14 )
  25 + * @property {String} labelColor label的字体颜色 (默认 '#303133' )
  26 + * @property {Boolean} labelDisabled 是否禁止点击文本操作 (默认 false )
  27 + * @property {String} iconColor 图标颜色 (默认 '#ffffff' )
  28 + * @property {String | Number} iconSize 图标的大小,单位px (默认 12 )
  29 + * @property {String} iconPlacement 勾选图标的对齐方式,left-左边,right-右边 (默认 'left' )
  30 + * @property {Boolean} borderBottom placement为row时,是否显示下边框 (默认 false )
  31 + * @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
  32 + * @event {Function} input 修改通过v-model绑定的值时触发,回调为一个对象
  33 + * @example <u-checkbox-group></u-checkbox-group>
  34 + */
  35 + export default {
  36 + name: 'u-checkbox-group',
  37 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  38 + computed: {
  39 + // 这里computed的变量,都是子组件u-checkbox需要用到的,由于头条小程序的兼容性差异,子组件无法实时监听父组件参数的变化
  40 + // 所以需要手动通知子组件,这里返回一个parentData变量,供watch监听,在其中去通知每一个子组件重新从父组件(u-checkbox-group)
  41 + // 拉取父组件新的变化后的参数
  42 + parentData() {
  43 + return [this.value, this.disabled, this.inactiveColor, this.activeColor, this.size, this.labelDisabled, this.shape,
  44 + this.iconSize, this.borderBottom, this.placement
  45 + ]
  46 + },
  47 + bemClass() {
  48 + // this.bem为一个computed变量,在mixin中
  49 + return this.bem('checkbox-group', ['placement'])
  50 + },
  51 + },
  52 + watch: {
  53 + // 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件
  54 + parentData() {
  55 + if (this.children.length) {
  56 + this.children.map(child => {
  57 + // 判断子组件(u-checkbox)如果有init方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
  58 + typeof(child.init) === 'function' && child.init()
  59 + })
  60 + }
  61 + },
  62 + },
  63 + data() {
  64 + return {
  65 +
  66 + }
  67 + },
  68 + created() {
  69 + this.children = []
  70 + },
  71 + methods: {
  72 + // 将其他的checkbox设置为未选中的状态
  73 + unCheckedOther(childInstance) {
  74 + const values = []
  75 + this.children.map(child => {
  76 + // 将被选中的checkbox,放到数组中返回
  77 + if (child.isChecked) {
  78 + values.push(child.name)
  79 + }
  80 + })
  81 + // 发出事件
  82 + this.$emit('change', values)
  83 + // 修改通过v-model绑定的值
  84 + this.$emit('input', values)
  85 + },
  86 + }
  87 + }
  88 +</script>
  89 +
  90 +<style lang="scss" scoped>
  91 + @import "../../libs/css/components.scss";
  92 +
  93 + .u-checkbox-group {
  94 +
  95 + &--row {
  96 + @include flex;
  97 + }
  98 +
  99 + &--column {
  100 + @include flex(column);
  101 + }
  102 + }
  103 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-checkbox/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // checkbox的名称
  4 + name: {
  5 + type: [String, Number, Boolean],
  6 + default: uni.$u.props.checkbox.name
  7 + },
  8 + // 形状,square为方形,circle为圆型
  9 + shape: {
  10 + type: String,
  11 + default: uni.$u.props.checkbox.shape
  12 + },
  13 + // 整体的大小
  14 + size: {
  15 + type: [String, Number],
  16 + default: uni.$u.props.checkbox.size
  17 + },
  18 + // 是否默认选中
  19 + checked: {
  20 + type: Boolean,
  21 + default: uni.$u.props.checkbox.checked
  22 + },
  23 + // 是否禁用
  24 + disabled: {
  25 + type: [String, Boolean],
  26 + default: uni.$u.props.checkbox.disabled
  27 + },
  28 + // 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
  29 + activeColor: {
  30 + type: String,
  31 + default: uni.$u.props.checkbox.activeColor
  32 + },
  33 + // 未选中的颜色
  34 + inactiveColor: {
  35 + type: String,
  36 + default: uni.$u.props.checkbox.inactiveColor
  37 + },
  38 + // 图标的大小,单位px
  39 + iconSize: {
  40 + type: [String, Number],
  41 + default: uni.$u.props.checkbox.iconSize
  42 + },
  43 + // 图标颜色
  44 + iconColor: {
  45 + type: String,
  46 + default: uni.$u.props.checkbox.iconColor
  47 + },
  48 + // label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式
  49 + label: {
  50 + type: [String, Number],
  51 + default: uni.$u.props.checkbox.label
  52 + },
  53 + // label的字体大小,px单位
  54 + labelSize: {
  55 + type: [String, Number],
  56 + default: uni.$u.props.checkbox.labelSize
  57 + },
  58 + // label的颜色
  59 + labelColor: {
  60 + type: String,
  61 + default: uni.$u.props.checkbox.labelColor
  62 + },
  63 + // 是否禁止点击提示语选中复选框
  64 + labelDisabled: {
  65 + type: [String, Boolean],
  66 + default: uni.$u.props.checkbox.labelDisabled
  67 + }
  68 + }
  69 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue 0 → 100644
  1 +<template>
  2 + <view
  3 + class="u-checkbox"
  4 + :style="[checkboxStyle]"
  5 + @tap.stop="wrapperClickHandler"
  6 + :class="[`u-checkbox-label--${parentData.iconPlacement}`, parentData.borderBottom && parentData.placement === 'column' && 'u-border-bottom']"
  7 + >
  8 + <view
  9 + class="u-checkbox__icon-wrap"
  10 + @tap.stop="iconClickHandler"
  11 + :class="iconClasses"
  12 + :style="[iconWrapStyle]"
  13 + >
  14 + <slot name="icon">
  15 + <u-icon
  16 + class="u-checkbox__icon-wrap__icon"
  17 + name="checkbox-mark"
  18 + :size="elIconSize"
  19 + :color="elIconColor"
  20 + />
  21 + </slot>
  22 + </view>
  23 + <text
  24 + @tap.stop="labelClickHandler"
  25 + :style="{
  26 + color: elDisabled ? elInactiveColor : elLabelColor,
  27 + fontSize: elLabelSize,
  28 + lineHeight: elLabelSize
  29 + }"
  30 + >{{label}}</text>
  31 + </view>
  32 +</template>
  33 +
  34 +<script>
  35 + import props from './props.js';
  36 + /**
  37 + * checkbox 复选框
  38 + * @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
  39 + * @tutorial https://uviewui.com/components/checkbox.html
  40 + * @property {String | Number | Boolean} name checkbox组件的标示符
  41 + * @property {String} shape 形状,square为方形,circle为圆型
  42 + * @property {String | Number} size 整体的大小
  43 + * @property {Boolean} checked 是否默认选中
  44 + * @property {String | Boolean} disabled 是否禁用
  45 + * @property {String} activeColor 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
  46 + * @property {String} inactiveColor 未选中的颜色
  47 + * @property {String | Number} iconSize 图标的大小,单位px
  48 + * @property {String} iconColor 图标颜色
  49 + * @property {String | Number} label label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式
  50 + * @property {String} labelColor label的颜色
  51 + * @property {String | Number} labelSize label的字体大小,px单位
  52 + * @property {String | Boolean} labelDisabled 是否禁止点击提示语选中复选框
  53 + * @property {Object} customStyle 定义需要用到的外部样式
  54 + *
  55 + * @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
  56 + * @example <u-checkbox v-model="checked" :disabled="false">天涯</u-checkbox>
  57 + */
  58 + export default {
  59 + name: "u-checkbox",
  60 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  61 + data() {
  62 + return {
  63 + isChecked: false,
  64 + // 父组件的默认值,因为头条小程序不支持在computed中使用this.parent.shape的形式
  65 + // 故只能使用如此方法
  66 + parentData: {
  67 + iconSize: 12,
  68 + labelDisabled: null,
  69 + disabled: null,
  70 + shape: 'square',
  71 + activeColor: null,
  72 + inactiveColor: null,
  73 + size: 18,
  74 + value: null,
  75 + iconColor: null,
  76 + placement: 'row',
  77 + borderBottom: false,
  78 + iconPlacement: 'left'
  79 + }
  80 + }
  81 + },
  82 + computed: {
  83 + // 是否禁用,如果父组件u-raios-group禁用的话,将会忽略子组件的配置
  84 + elDisabled() {
  85 + return this.disabled !== '' ? this.disabled : this.parentData.disabled !== null ? this.parentData.disabled : false;
  86 + },
  87 + // 是否禁用label点击
  88 + elLabelDisabled() {
  89 + return this.labelDisabled !== '' ? this.labelDisabled : this.parentData.labelDisabled !== null ? this.parentData.labelDisabled :
  90 + false;
  91 + },
  92 + // 组件尺寸,对应size的值,默认值为21px
  93 + elSize() {
  94 + return this.size ? this.size : (this.parentData.size ? this.parentData.size : 21);
  95 + },
  96 + // 组件的勾选图标的尺寸,默认12px
  97 + elIconSize() {
  98 + return this.iconSize ? this.iconSize : (this.parentData.iconSize ? this.parentData.iconSize : 12);
  99 + },
  100 + // 组件选中激活时的颜色
  101 + elActiveColor() {
  102 + return this.activeColor ? this.activeColor : (this.parentData.activeColor ? this.parentData.activeColor : '#2979ff');
  103 + },
  104 + // 组件选未中激活时的颜色
  105 + elInactiveColor() {
  106 + return this.inactiveColor ? this.inactiveColor : (this.parentData.inactiveColor ? this.parentData.inactiveColor :
  107 + '#c8c9cc');
  108 + },
  109 + // label的颜色
  110 + elLabelColor() {
  111 + return this.labelColor ? this.labelColor : (this.parentData.labelColor ? this.parentData.labelColor : '#606266')
  112 + },
  113 + // 组件的形状
  114 + elShape() {
  115 + return this.shape ? this.shape : (this.parentData.shape ? this.parentData.shape : 'circle');
  116 + },
  117 + // label大小
  118 + elLabelSize() {
  119 + return uni.$u.addUnit(this.labelSize ? this.labelSize : (this.parentData.labelSize ? this.parentData.labelSize :
  120 + '15'))
  121 + },
  122 + elIconColor() {
  123 + const iconColor = this.iconColor ? this.iconColor : (this.parentData.iconColor ? this.parentData.iconColor :
  124 + '#ffffff');
  125 + // 图标的颜色
  126 + if (this.elDisabled) {
  127 + // disabled状态下,已勾选的checkbox图标改为elInactiveColor
  128 + return this.isChecked ? this.elInactiveColor : 'transparent'
  129 + } else {
  130 + return this.isChecked ? iconColor : 'transparent'
  131 + }
  132 + },
  133 + iconClasses() {
  134 + let classes = []
  135 + // 组件的形状
  136 + classes.push('u-checkbox__icon-wrap--' + this.elShape)
  137 + if (this.elDisabled) {
  138 + classes.push('u-checkbox__icon-wrap--disabled')
  139 + }
  140 + if (this.isChecked && this.elDisabled) {
  141 + classes.push('u-checkbox__icon-wrap--disabled--checked')
  142 + }
  143 + // 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
  144 + // #ifdef MP-ALIPAY || MP-TOUTIAO
  145 + classes = classes.join(' ')
  146 + // #endif
  147 + return classes
  148 + },
  149 + iconWrapStyle() {
  150 + // checkbox的整体样式
  151 + const style = {}
  152 + style.backgroundColor = this.isChecked && !this.elDisabled ? this.elActiveColor : '#ffffff'
  153 + style.borderColor = this.isChecked && !this.elDisabled ? this.elActiveColor : this.elInactiveColor
  154 + style.width = uni.$u.addUnit(this.elSize)
  155 + style.height = uni.$u.addUnit(this.elSize)
  156 + // 如果是图标在右边的话,移除它的右边距
  157 + if (this.parentData.iconPlacement === 'right') {
  158 + style.marginRight = 0
  159 + }
  160 + return style
  161 + },
  162 + checkboxStyle() {
  163 + const style = {}
  164 + if (this.parentData.borderBottom && this.parentData.placement === 'row') {
  165 + uni.$u.error('检测到您将borderBottom设置为true,需要同时将u-checkbox-group的placement设置为column才有效')
  166 + }
  167 + // 当父组件设置了显示下边框并且排列形式为纵向时,给内容和边框之间加上一定间隔
  168 + if (this.parentData.borderBottom && this.parentData.placement === 'column') {
  169 + style.paddingBottom = '8px'
  170 + }
  171 + return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
  172 + }
  173 + },
  174 + mounted() {
  175 + this.init()
  176 + },
  177 + methods: {
  178 + init() {
  179 + // 支付宝小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环引用
  180 + this.updateParentData()
  181 + if (!this.parent) {
  182 + uni.$u.error('u-checkbox必须搭配u-checkbox-group组件使用')
  183 + }
  184 + // 设置初始化时,是否默认选中的状态,父组件u-checkbox-group的value可能是array,所以额外判断
  185 + if (this.checked) {
  186 + this.isChecked = true
  187 + } else if (uni.$u.test.array(this.parentData.value)) {
  188 + // 查找数组是是否存在this.name元素值
  189 + this.isChecked = this.parentData.value.some(item => {
  190 + return item === this.name
  191 + })
  192 + }
  193 + },
  194 + updateParentData() {
  195 + this.getParentData('u-checkbox-group')
  196 + },
  197 + // 横向两端排列时,点击组件即可触发选中事件
  198 + wrapperClickHandler(e) {
  199 + this.parentData.iconPlacement === 'right' && this.iconClickHandler(e)
  200 + },
  201 + // 点击图标
  202 + iconClickHandler(e) {
  203 + this.preventEvent(e)
  204 + // 如果整体被禁用,不允许被点击
  205 + if (!this.elDisabled) {
  206 + this.setRadioCheckedStatus()
  207 + }
  208 + },
  209 + // 点击label
  210 + labelClickHandler(e) {
  211 + this.preventEvent(e)
  212 + // 如果按钮整体被禁用或者label被禁用,则不允许点击文字修改状态
  213 + if (!this.elLabelDisabled && !this.elDisabled) {
  214 + this.setRadioCheckedStatus()
  215 + }
  216 + },
  217 + emitEvent() {
  218 + this.$emit('change', this.isChecked)
  219 + // 尝试调用u-form的验证方法,进行一定延迟,否则微信小程序更新可能会不及时
  220 + this.$nextTick(() => {
  221 + uni.$u.formValidate(this, 'change')
  222 + })
  223 + },
  224 + // 改变组件选中状态
  225 + // 这里的改变的依据是,更改本组件的checked值为true,同时通过父组件遍历所有u-checkbox实例
  226 + // 将本组件外的其他u-checkbox的checked都设置为false(都被取消选中状态),因而只剩下一个为选中状态
  227 + setRadioCheckedStatus() {
  228 + // 将本组件标记为与原来相反的状态
  229 + this.isChecked = !this.isChecked
  230 + this.emitEvent()
  231 + typeof this.parent.unCheckedOther === 'function' && this.parent.unCheckedOther(this)
  232 + }
  233 + },
  234 + watch:{
  235 + checked(){
  236 + this.isChecked = this.checked
  237 + }
  238 + }
  239 + }
  240 +</script>
  241 +
  242 +<style lang="scss" scoped>
  243 + @import "../../libs/css/components.scss";
  244 + $u-checkbox-icon-wrap-margin-right:6px !default;
  245 + $u-checkbox-icon-wrap-font-size:6px !default;
  246 + $u-checkbox-icon-wrap-border-width:1px !default;
  247 + $u-checkbox-icon-wrap-border-color:#c8c9cc !default;
  248 + $u-checkbox-icon-wrap-icon-line-height:0 !default;
  249 + $u-checkbox-icon-wrap-circle-border-radius:100% !default;
  250 + $u-checkbox-icon-wrap-square-border-radius:3px !default;
  251 + $u-checkbox-icon-wrap-checked-color:#fff !default;
  252 + $u-checkbox-icon-wrap-checked-background-color:red !default;
  253 + $u-checkbox-icon-wrap-checked-border-color:#2979ff !default;
  254 + $u-checkbox-icon-wrap-disabled-background-color:#ebedf0 !default;
  255 + $u-checkbox-icon-wrap-disabled-checked-color:#c8c9cc !default;
  256 + $u-checkbox-label-margin-left:5px !default;
  257 + $u-checkbox-label-margin-right:12px !default;
  258 + $u-checkbox-label-color:$u-content-color !default;
  259 + $u-checkbox-label-font-size:15px !default;
  260 + $u-checkbox-label-disabled-color:#c8c9cc !default;
  261 +
  262 + .u-checkbox {
  263 + /* #ifndef APP-NVUE */
  264 + @include flex(row);
  265 + /* #endif */
  266 + overflow: hidden;
  267 + flex-direction: row;
  268 + align-items: center;
  269 +
  270 + &-label--left {
  271 + flex-direction: row
  272 + }
  273 +
  274 + &-label--right {
  275 + flex-direction: row-reverse;
  276 + justify-content: space-between
  277 + }
  278 +
  279 + &__icon-wrap {
  280 + /* #ifndef APP-NVUE */
  281 + box-sizing: border-box;
  282 + // nvue下,border-color过渡有问题
  283 + transition-property: border-color, background-color, color;
  284 + transition-duration: 0.2s;
  285 + /* #endif */
  286 + color: $u-content-color;
  287 + @include flex;
  288 + align-items: center;
  289 + justify-content: center;
  290 + color: transparent;
  291 + text-align: center;
  292 + margin-right: $u-checkbox-icon-wrap-margin-right;
  293 +
  294 + font-size: $u-checkbox-icon-wrap-font-size;
  295 + border-width: $u-checkbox-icon-wrap-border-width;
  296 + border-color: $u-checkbox-icon-wrap-border-color;
  297 + border-style: solid;
  298 +
  299 + /* #ifdef MP-TOUTIAO */
  300 + // 头条小程序兼容性问题,需要设置行高为0,否则图标偏下
  301 + &__icon {
  302 + line-height: $u-checkbox-icon-wrap-icon-line-height;
  303 + }
  304 +
  305 + /* #endif */
  306 +
  307 + &--circle {
  308 + border-radius: $u-checkbox-icon-wrap-circle-border-radius;
  309 + }
  310 +
  311 + &--square {
  312 + border-radius: $u-checkbox-icon-wrap-square-border-radius;
  313 + }
  314 +
  315 + &--checked {
  316 + color: $u-checkbox-icon-wrap-checked-color;
  317 + background-color: $u-checkbox-icon-wrap-checked-background-color;
  318 + border-color: $u-checkbox-icon-wrap-checked-border-color;
  319 + }
  320 +
  321 + &--disabled {
  322 + background-color: $u-checkbox-icon-wrap-disabled-background-color !important;
  323 + }
  324 +
  325 + &--disabled--checked {
  326 + color: $u-checkbox-icon-wrap-disabled-checked-color !important;
  327 + }
  328 + }
  329 +
  330 + &__label {
  331 + /* #ifndef APP-NVUE */
  332 + word-wrap: break-word;
  333 + /* #endif */
  334 + margin-left: $u-checkbox-label-margin-left;
  335 + margin-right: $u-checkbox-label-margin-right;
  336 + color: $u-checkbox-label-color;
  337 + font-size: $u-checkbox-label-font-size;
  338 +
  339 + &--disabled {
  340 + color: $u-checkbox-label-disabled-color;
  341 + }
  342 + }
  343 + }
  344 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-circle-progress/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + percentage: {
  4 + type: [String, Number],
  5 + default: uni.$u.props.circleProgress.percentage
  6 + }
  7 + }
  8 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-circle-progress/u-circle-progress.vue 0 → 100644
  1 +<template>
  2 + <view class="u-circle-progress">
  3 + <view class="u-circle-progress__left">
  4 + <view
  5 + class="u-circle-progress__left__circle"
  6 + :style="[leftSyle]"
  7 + ref="left-circle"
  8 + >
  9 +
  10 + </view>
  11 + </view>
  12 + <view
  13 + class="u-circle-progress__right"
  14 + >
  15 + <view
  16 + class="u-circle-progress__right__circle"
  17 + ref="right-circle"
  18 + :style="[rightSyle]"
  19 + >
  20 +
  21 + </view>
  22 + </view>
  23 + <view class="u-circle-progress__circle">
  24 +
  25 + </view>
  26 + </view>
  27 +</template>
  28 +
  29 +<script>
  30 + import props from './props.js';
  31 + // #ifdef APP-NVUE
  32 + const animation = uni.requireNativePlugin('animation')
  33 + // #endif
  34 + /**
  35 + * CircleProgress 圆形进度条 TODO: 待完善
  36 + * @description 展示操作或任务的当前进度,比如上传文件,是一个圆形的进度环。
  37 + * @tutorial https://www.uviewui.com/components/circleProgress.html
  38 + * @property {String | Number} percentage 圆环进度百分比值,为数值类型,0-100 (默认 30 )
  39 + * @example
  40 + */
  41 + export default {
  42 + name: 'u-circle-progress',
  43 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  44 + data() {
  45 + return {
  46 + leftBorderColor: 'rgb(200, 200, 200)',
  47 + rightBorderColor: 'rgb(200, 200, 200)',
  48 + }
  49 + },
  50 + computed: {
  51 + leftSyle() {
  52 + const style = {}
  53 + style.borderTopColor = this.leftBorderColor
  54 + style.borderRightColor = this.leftBorderColor
  55 + return style
  56 + },
  57 + rightSyle() {
  58 + const style = {}
  59 + style.borderLeftColor = this.rightBorderColor
  60 + style.borderBottomColor = this.rightBorderColor
  61 + return style
  62 + }
  63 + },
  64 + mounted() {
  65 + uni.$u.sleep().then(() => {
  66 + this.rightBorderColor = 'rgb(66, 185, 131)'
  67 + // this.init()
  68 + })
  69 + },
  70 + methods: {
  71 + init() {
  72 + animation.transition(this.$refs['right-circle'].ref, {
  73 + styles: {
  74 + transform: 'rotate(45deg)',
  75 + transformOrigin: 'center center'
  76 + },
  77 + }, () => {
  78 + this.rightBorderColor = 'rgb(66, 185, 131)'
  79 + // animation.transition(this.$refs['right-circle'].ref, {
  80 + // styles: {
  81 + // transform: 'rotate(225deg)',
  82 + // transformOrigin: 'center center'
  83 + // },
  84 + // duration: 3000,
  85 + // }, () => {
  86 + // animation.transition(this.$refs['left-circle'].ref, {
  87 + // styles: {
  88 + // transform: 'rotate(45deg)',
  89 + // transformOrigin: 'center center'
  90 + // },
  91 + // }, () => {
  92 + // this.leftBorderColor = 'rgb(66, 185, 131)'
  93 + // animation.transition(this.$refs['left-circle'].ref, {
  94 + // styles: {
  95 + // transform: 'rotate(225deg)',
  96 + // transformOrigin: 'center center'
  97 + // },
  98 + // duration: 1500,
  99 + // }, () => {
  100 +
  101 + // })
  102 + // })
  103 + // })
  104 + })
  105 +
  106 + }
  107 + },
  108 + }
  109 +</script>
  110 +
  111 +<style lang="scss" scoped>
  112 + @import "../../libs/css/components.scss";
  113 +
  114 + .u-circle-progress {
  115 + @include flex(row);
  116 + position: relative;
  117 + border-radius: 100px;
  118 + height: 100px;
  119 + width: 100px;
  120 + // transform: rotate(0deg);
  121 + // background-color: rgb(66, 185, 131);
  122 + background-color: rgb(200, 200, 200);
  123 + overflow: hidden;
  124 + justify-content: space-between;
  125 +
  126 + &__circle {
  127 + border-radius: 100px;
  128 + height: 90px;
  129 + width: 90px;
  130 + transform: translate(-50%, -50%);
  131 + background-color: rgb(255, 255, 255);
  132 + left: 50px;
  133 + top: 50px;
  134 + position: absolute;
  135 + }
  136 +
  137 + &__left {
  138 + position: absolute;
  139 + left: 0;
  140 + width: 50px;
  141 + height: 100px;
  142 + overflow: hidden;
  143 + box-sizing: border-box;
  144 + // background-color: rgb(66, 185, 131);
  145 + // background-color: rgb(200, 200, 200);
  146 + // transform-origin: left center;
  147 +
  148 + &__circle {
  149 + box-sizing: border-box;
  150 + // background-color: red;
  151 + border-left-color: transparent;
  152 + border-bottom-color: transparent;
  153 + border-top-left-radius: 50px;
  154 + border-top-right-radius: 50px;
  155 + border-bottom-right-radius: 50px;
  156 + // border-left-color: rgb(66, 185, 131);
  157 + // border-bottom-color: rgb(66, 185, 131);
  158 + border-top-color: rgb(66, 185, 131);
  159 + border-right-color: rgb(66, 185, 131);
  160 + border-width: 5px;
  161 + width: 100px;
  162 + height: 100px;
  163 + transform: rotate(225deg);
  164 + // border-radius: 100px;
  165 + }
  166 + }
  167 +
  168 + &__right {
  169 + position: absolute;
  170 + right: 0;
  171 + width: 50px;
  172 + height: 100px;
  173 + overflow: hidden;
  174 +
  175 + &__circle {
  176 + position: absolute;
  177 + right: 0;
  178 + box-sizing: border-box;
  179 + // background-color: red;
  180 + border-top-color: transparent;
  181 + border-right-color: transparent;
  182 + border-top-left-radius: 50px;
  183 + border-bottom-left-radius: 50px;
  184 + border-bottom-right-radius: 50px;
  185 + // border-left-color: rgb(66, 185, 131);
  186 + // border-bottom-color: rgb(66, 185, 131);
  187 + border-left-color: rgb(200, 200, 200);
  188 + border-bottom-color: rgb(200, 200, 200);
  189 + border-width: 5px;
  190 + width: 100px;
  191 + height: 100px;
  192 + transform: rotate(45deg);
  193 + transform-origin: center center;
  194 + // border-radius: 100px;
  195 + }
  196 + }
  197 + }
  198 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-code-input/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 最大输入长度
  4 + maxlength: {
  5 + type: [String, Number],
  6 + default: uni.$u.props.codeInput.maxlength
  7 + },
  8 + // 是否用圆点填充
  9 + dot: {
  10 + type: Boolean,
  11 + default: uni.$u.props.codeInput.dot
  12 + },
  13 + // 显示模式,box-盒子模式,line-底部横线模式
  14 + mode: {
  15 + type: String,
  16 + default: uni.$u.props.codeInput.mode
  17 + },
  18 + // 是否细边框
  19 + hairline: {
  20 + type: Boolean,
  21 + default: uni.$u.props.codeInput.hairline
  22 + },
  23 + // 字符间的距离
  24 + space: {
  25 + type: [String, Number],
  26 + default: uni.$u.props.codeInput.space
  27 + },
  28 + // 预置值
  29 + value: {
  30 + type: [String, Number],
  31 + default: uni.$u.props.codeInput.value
  32 + },
  33 + // 是否自动获取焦点
  34 + focus: {
  35 + type: Boolean,
  36 + default: uni.$u.props.codeInput.focus
  37 + },
  38 + // 字体是否加粗
  39 + bold: {
  40 + type: Boolean,
  41 + default: uni.$u.props.codeInput.bold
  42 + },
  43 + // 字体颜色
  44 + color: {
  45 + type: String,
  46 + default: uni.$u.props.codeInput.color
  47 + },
  48 + // 字体大小
  49 + fontSize: {
  50 + type: [String, Number],
  51 + default: uni.$u.props.codeInput.fontSize
  52 + },
  53 + // 输入框的大小,宽等于高
  54 + size: {
  55 + type: [String, Number],
  56 + default: uni.$u.props.codeInput.size
  57 + },
  58 + // 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true
  59 + disabledKeyboard: {
  60 + type: Boolean,
  61 + default: uni.$u.props.codeInput.disabledKeyboard
  62 + },
  63 + // 边框和线条颜色
  64 + borderColor: {
  65 + type: String,
  66 + default: uni.$u.props.codeInput.borderColor
  67 + },
  68 + // 是否禁止输入"."符号
  69 + disabledDot: {
  70 + type: Boolean,
  71 + default: uni.$u.props.codeInput.disabledDot
  72 + }
  73 + }
  74 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-code-input/u-code-input.vue 0 → 100644
  1 +<template>
  2 + <view class="u-code-input">
  3 + <view
  4 + class="u-code-input__item"
  5 + :style="[itemStyle(index)]"
  6 + v-for="(item, index) in codeLength"
  7 + :key="index"
  8 + >
  9 + <view
  10 + class="u-code-input__item__dot"
  11 + v-if="dot && codeArray.length > index"
  12 + ></view>
  13 + <text
  14 + v-else
  15 + :style="{
  16 + fontSize: $u.addUnit(fontSize),
  17 + fontWeight: bold ? 'bold' : 'normal',
  18 + color: color
  19 + }"
  20 + >{{codeArray[index]}}</text>
  21 + <view
  22 + class="u-code-input__item__line"
  23 + v-if="mode === 'line'"
  24 + :style="[lineStyle]"
  25 + ></view>
  26 + <view v-if="codeArray.length === index" :style="{backgroundColor: color}" class="u-code-input__item__cursor"></view>
  27 + </view>
  28 + <input
  29 + :disabled="disabledKeyboard"
  30 + type="number"
  31 + :focus="focus"
  32 + :value="inputValue"
  33 + :maxlength="maxlength"
  34 + class="u-code-input__input"
  35 + @input="inputHandler"
  36 + :style="{
  37 + height: $u.addUnit(size)
  38 + }"
  39 + />
  40 + </view>
  41 +</template>
  42 +
  43 +<script>
  44 + import props from './props.js';
  45 + /**
  46 + * CodeInput 验证码输入
  47 + * @description 该组件一般用于验证用户短信验证码的场景,也可以结合uView的键盘组件使用
  48 + * @tutorial https://www.uviewui.com/components/codeInput.html
  49 + * @property {String | Number} maxlength 最大输入长度 (默认 6 )
  50 + * @property {Boolean} dot 是否用圆点填充 (默认 false )
  51 + * @property {String} mode 显示模式,box-盒子模式,line-底部横线模式 (默认 'box' )
  52 + * @property {Boolean} hairline 是否细边框 (默认 false )
  53 + * @property {String | Number} space 字符间的距离 (默认 10 )
  54 + * @property {String | Number} value 预置值
  55 + * @property {Boolean} focus 是否自动获取焦点 (默认 false )
  56 + * @property {Boolean} bold 字体和输入横线是否加粗 (默认 false )
  57 + * @property {String} color 字体颜色 (默认 '#606266' )
  58 + * @property {String | Number} fontSize 字体大小,单位px (默认 18 )
  59 + * @property {String | Number} size 输入框的大小,宽等于高 (默认 35 )
  60 + * @property {Boolean} disabledKeyboard 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true (默认 false )
  61 + * @property {String} borderColor 边框和线条颜色 (默认 '#c9cacc' )
  62 + * @property {Boolean} disabledDot 是否禁止输入"."符号 (默认 true )
  63 + *
  64 + * @event {Function} change 输入内容发生改变时触发,具体见上方说明 value:当前输入的值
  65 + * @event {Function} finish 输入字符个数达maxlength值时触发,见上方说明 value:当前输入的值
  66 + * @example <u-code-input v-model="value4" :focus="true"></u-code-input>
  67 + */
  68 + export default {
  69 + name: 'u-code-input',
  70 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  71 + data() {
  72 + return {
  73 + inputValue: ''
  74 + }
  75 + },
  76 + watch: {
  77 + value: {
  78 + immediate: true,
  79 + handler(val) {
  80 + // 转为字符串,超出部分截掉
  81 + this.inputValue = String(val).substring(0, this.maxlength)
  82 + }
  83 + },
  84 + },
  85 + computed: {
  86 + // 根据长度,循环输入框的个数,因为头条小程序数值不能用于v-for
  87 + codeLength() {
  88 + return new Array(Number(this.maxlength))
  89 + },
  90 + // 循环item的样式
  91 + itemStyle() {
  92 + return index => {
  93 + const addUnit = uni.$u.addUnit
  94 + const style = {
  95 + width: addUnit(this.size),
  96 + height: addUnit(this.size)
  97 + }
  98 + // 盒子模式下,需要额外进行处理
  99 + if (this.mode === 'box') {
  100 + // 设置盒子的边框,如果是细边框,则设置为0.5px宽度
  101 + style.border = `${this.hairline ? 0.5 : 1}px solid ${this.borderColor}`
  102 + // 如果盒子间距为0的话
  103 + if (uni.$u.getPx(this.space) === 0) {
  104 + // 给第一和最后一个盒子设置圆角
  105 + if (index === 0) {
  106 + style.borderTopLeftRadius = '3px'
  107 + style.borderBottomLeftRadius = '3px'
  108 + }
  109 + if (index === this.codeLength.length - 1) {
  110 + style.borderTopRightRadius = '3px'
  111 + style.borderBottomRightRadius = '3px'
  112 + }
  113 + // 最后一个盒子的右边框需要保留
  114 + if (index !== this.codeLength.length - 1) {
  115 + style.borderRight = 'none'
  116 + }
  117 + }
  118 + }
  119 + if (index !== this.codeLength.length - 1) {
  120 + // 设置验证码字符之间的距离,通过margin-right设置,最后一个字符,无需右边框
  121 + style.marginRight = addUnit(this.space)
  122 + } else {
  123 + // 最后一个盒子的有边框需要保留
  124 + style.marginRight = 0
  125 + }
  126 +
  127 + return style
  128 + }
  129 + },
  130 + // 将输入的值,转为数组,给item历遍时,根据当前的索引显示数组的元素
  131 + codeArray() {
  132 + return String(this.inputValue).split('')
  133 + },
  134 + // 下划线模式下,横线的样式
  135 + lineStyle() {
  136 + const style = {}
  137 + style.height = this.hairline ? '2px' : '4px'
  138 + style.width = uni.$u.addUnit(this.size)
  139 + // 线条模式下,背景色即为边框颜色
  140 + style.backgroundColor = this.borderColor
  141 + return style
  142 + }
  143 + },
  144 + methods: {
  145 + // 监听输入框的值发生变化
  146 + inputHandler(e) {
  147 + const value = e.detail.value
  148 + this.inputValue = value
  149 + // 是否允许输入“.”符号
  150 + if(this.disabledDot) {
  151 + this.$nextTick(() => {
  152 + this.inputValue = value.replace('.', '')
  153 + })
  154 + }
  155 + // 未达到maxlength之前,发送change事件,达到后发送finish事件
  156 + this.$emit('change', value)
  157 + // 修改通过v-model双向绑定的值
  158 + this.$emit('input', value)
  159 + // 达到用户指定输入长度时,发出完成事件
  160 + if (String(value).length >= Number(this.maxlength)) {
  161 + this.$emit('finish', value)
  162 + }
  163 + }
  164 + }
  165 + }
  166 +</script>
  167 +
  168 +<style lang="scss" scoped>
  169 + @import "../../libs/css/components.scss";
  170 + $u-code-input-cursor-width: 1px;
  171 + $u-code-input-cursor-height: 40%;
  172 + $u-code-input-cursor-animation-duration: 1s;
  173 + $u-code-input-cursor-animation-name: u-cursor-flicker;
  174 +
  175 + .u-code-input {
  176 + @include flex;
  177 + position: relative;
  178 + overflow: hidden;
  179 +
  180 + &__item {
  181 + @include flex;
  182 + justify-content: center;
  183 + align-items: center;
  184 + position: relative;
  185 +
  186 + &__text {
  187 + font-size: 15px;
  188 + color: $u-content-color;
  189 + }
  190 +
  191 + &__dot {
  192 + width: 7px;
  193 + height: 7px;
  194 + border-radius: 100px;
  195 + background-color: $u-content-color;
  196 + }
  197 +
  198 + &__line {
  199 + position: absolute;
  200 + bottom: 0;
  201 + height: 4px;
  202 + border-radius: 100px;
  203 + width: 40px;
  204 + background-color: $u-content-color;
  205 + }
  206 + &__cursor {
  207 + position: absolute;
  208 + top: 50%;
  209 + left: 50%;
  210 + transform: translate(-50%,-50%);
  211 + width: $u-code-input-cursor-width;
  212 + height: $u-code-input-cursor-height;
  213 + animation: $u-code-input-cursor-animation-duration u-cursor-flicker infinite;
  214 + }
  215 + }
  216 +
  217 + &__input {
  218 + // 之所以需要input输入框,是因为有它才能唤起键盘
  219 + // 这里将它设置为两倍的屏幕宽度,再将左边的一半移出屏幕,为了不让用户看到输入的内容
  220 + position: absolute;
  221 + left: -750rpx;
  222 + width: 1500rpx;
  223 + top: 0;
  224 + background-color: transparent;
  225 + text-align: left;
  226 + }
  227 + }
  228 +
  229 + @keyframes u-cursor-flicker {
  230 + 0% {
  231 + opacity: 0;
  232 + }
  233 + 50% {
  234 + opacity: 1;
  235 + }
  236 + 100% {
  237 + opacity: 0;
  238 + }
  239 + }
  240 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-code/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 倒计时总秒数
  4 + seconds: {
  5 + type: [String, Number],
  6 + default: uni.$u.props.code.seconds
  7 + },
  8 + // 尚未开始时提示
  9 + startText: {
  10 + type: String,
  11 + default: uni.$u.props.code.startText
  12 + },
  13 + // 正在倒计时中的提示
  14 + changeText: {
  15 + type: String,
  16 + default: uni.$u.props.code.changeText
  17 + },
  18 + // 倒计时结束时的提示
  19 + endText: {
  20 + type: String,
  21 + default: uni.$u.props.code.endText
  22 + },
  23 + // 是否在H5刷新或各端返回再进入时继续倒计时
  24 + keepRunning: {
  25 + type: Boolean,
  26 + default: uni.$u.props.code.keepRunning
  27 + },
  28 + // 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
  29 + uniqueKey: {
  30 + type: String,
  31 + default: uni.$u.props.code.uniqueKey
  32 + }
  33 + }
  34 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-code/u-code.vue 0 → 100644
  1 +<template>
  2 + <view class="u-code">
  3 + <!-- 此组件功能由js完成,无需写html逻辑 -->
  4 + </view>
  5 +</template>
  6 +
  7 +<script>
  8 + import props from './props.js';
  9 + /**
  10 + * Code 验证码输入框
  11 + * @description 考虑到用户实际发送验证码的场景,可能是一个按钮,也可能是一段文字,提示语各有不同,所以本组件 不提供界面显示,只提供提示语,由用户将提示语嵌入到具体的场景
  12 + * @tutorial https://www.uviewui.com/components/code.html
  13 + * @property {String | Number} seconds 倒计时所需的秒数(默认 60 )
  14 + * @property {String} startText 开始前的提示语,见官网说明(默认 '获取验证码' )
  15 + * @property {String} changeText 倒计时期间的提示语,必须带有字母"x",见官网说明(默认 'X秒重新获取' )
  16 + * @property {String} endText 倒计结束的提示语,见官网说明(默认 '重新获取' )
  17 + * @property {Boolean} keepRunning 是否在H5刷新或各端返回再进入时继续倒计时( 默认false )
  18 + * @property {String} uniqueKey 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
  19 + *
  20 + * @event {Function} change 倒计时期间,每秒触发一次
  21 + * @event {Function} start 开始倒计时触发
  22 + * @event {Function} end 结束倒计时触发
  23 + * @example <u-code ref="uCode" @change="codeChange" seconds="20"></u-code>
  24 + */
  25 + export default {
  26 + name: "u-code",
  27 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  28 + data() {
  29 + return {
  30 + secNum: this.seconds,
  31 + timer: null,
  32 + canGetCode: true, // 是否可以执行验证码操作
  33 + }
  34 + },
  35 + mounted() {
  36 + this.checkKeepRunning()
  37 + },
  38 + watch: {
  39 + seconds: {
  40 + immediate: true,
  41 + handler(n) {
  42 + this.secNum = n
  43 + }
  44 + }
  45 + },
  46 + methods: {
  47 + checkKeepRunning() {
  48 + // 获取上一次退出页面(H5还包括刷新)时的时间戳,如果没有上次的保存,此值可能为空
  49 + let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$uCountDownTimestamp'))
  50 + if(!lastTimestamp) return this.changeEvent(this.startText)
  51 + // 当前秒的时间戳
  52 + let nowTimestamp = Math.floor((+ new Date()) / 1000)
  53 + // 判断当前的时间戳,是否小于上一次的本该按设定结束,却提前结束的时间戳
  54 + if(this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {
  55 + // 剩余尚未执行完的倒计秒数
  56 + this.secNum = lastTimestamp - nowTimestamp
  57 + // 清除本地保存的变量
  58 + uni.removeStorageSync(this.uniqueKey + '_$uCountDownTimestamp')
  59 + // 开始倒计时
  60 + this.start()
  61 + } else {
  62 + // 如果不存在需要继续上一次的倒计时,执行正常的逻辑
  63 + this.changeEvent(this.startText)
  64 + }
  65 + },
  66 + // 开始倒计时
  67 + start() {
  68 + // 防止快速点击获取验证码的按钮而导致内部产生多个定时器导致混乱
  69 + if(this.timer) {
  70 + clearInterval(this.timer)
  71 + this.timer = null
  72 + }
  73 + this.$emit('start')
  74 + this.canGetCode = false
  75 + // 这里放这句,是为了一开始时就提示,否则要等setInterval的1秒后才会有提示
  76 + this.changeEvent(this.changeText.replace(/x|X/, this.secNum))
  77 + this.setTimeToStorage()
  78 + this.timer = setInterval(() => {
  79 + if (--this.secNum) {
  80 + // 用当前倒计时的秒数替换提示字符串中的"x"字母
  81 + this.changeEvent(this.changeText.replace(/x|X/, this.secNum))
  82 + } else {
  83 + clearInterval(this.timer)
  84 + this.timer = null
  85 + this.changeEvent(this.endText)
  86 + this.secNum = this.seconds
  87 + this.$emit('end')
  88 + this.canGetCode = true
  89 + }
  90 + }, 1000)
  91 + },
  92 + // 重置,可以让用户再次获取验证码
  93 + reset() {
  94 + this.canGetCode = true
  95 + clearInterval(this.timer)
  96 + this.secNum = this.seconds
  97 + this.changeEvent(this.endText)
  98 + },
  99 + changeEvent(text) {
  100 + this.$emit('change', text)
  101 + },
  102 + // 保存时间戳,为了防止倒计时尚未结束,H5刷新或者各端的右上角返回上一页再进来
  103 + setTimeToStorage() {
  104 + if(!this.keepRunning || !this.timer) return
  105 + // 记录当前的时间戳,为了下次进入页面,如果还在倒计时内的话,继续倒计时
  106 + // 倒计时尚未结束,结果大于0;倒计时已经开始,就会小于初始值,如果等于初始值,说明没有开始倒计时,无需处理
  107 + if(this.secNum > 0 && this.secNum <= this.seconds) {
  108 + // 获取当前时间戳(+ new Date()为特殊写法),除以1000变成秒,再去除小数部分
  109 + let nowTimestamp = Math.floor((+ new Date()) / 1000)
  110 + // 将本该结束时候的时间戳保存起来 => 当前时间戳 + 剩余的秒数
  111 + uni.setStorage({
  112 + key: this.uniqueKey + '_$uCountDownTimestamp',
  113 + data: nowTimestamp + Number(this.secNum)
  114 + })
  115 + }
  116 + }
  117 + },
  118 + // 组件销毁的时候,清除定时器,否则定时器会继续存在,系统不会自动清除
  119 + beforeDestroy() {
  120 + this.setTimeToStorage()
  121 + clearTimeout(this.timer)
  122 + this.timer = null
  123 + }
  124 + }
  125 +</script>
  126 +
  127 +<style lang="scss" scoped>
  128 + @import "../../libs/css/components.scss";
  129 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-col/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 占父容器宽度的多少等分,总分为12份
  4 + span: {
  5 + type: [String, Number],
  6 + default: uni.$u.props.col.span
  7 + },
  8 + // 指定栅格左侧的间隔数(总12栏)
  9 + offset: {
  10 + type: [String, Number],
  11 + default: uni.$u.props.col.offset
  12 + },
  13 + // 水平排列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`)
  14 + justify: {
  15 + type: String,
  16 + default: uni.$u.props.col.justify
  17 + },
  18 + // 垂直对齐方式,可选值为top、center、bottom、stretch
  19 + align: {
  20 + type: String,
  21 + default: uni.$u.props.col.align
  22 + },
  23 + // 文字对齐方式
  24 + textAlign: {
  25 + type: String,
  26 + default: uni.$u.props.col.textAlign
  27 + }
  28 + }
  29 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-col/u-col.vue 0 → 100644
  1 +<template>
  2 + <view
  3 + class="u-col"
  4 + ref="u-col"
  5 + :class="[
  6 + 'u-col-' + span
  7 + ]"
  8 + :style="[colStyle]"
  9 + @tap="clickHandler"
  10 + >
  11 + <slot></slot>
  12 + </view>
  13 +</template>
  14 +
  15 +<script>
  16 + import props from './props.js';
  17 + /**
  18 + * CodeInput 栅格系统的列
  19 + * @description 该组件一般用于Layout 布局 通过基础的 12 分栏,迅速简便地创建布局
  20 + * @tutorial https://www.uviewui.com/components/Layout.html
  21 + * @property {String | Number} span 栅格占据的列数,总12等份 (默认 12 )
  22 + * @property {String | Number} offset 分栏左边偏移,计算方式与span相同 (默认 0 )
  23 + * @property {String} justify 水平排列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`) (默认 'start' )
  24 + * @property {String} align 垂直对齐方式,可选值为top、center、bottom、stretch (默认 'stretch' )
  25 + * @property {String} textAlign 文字水平对齐方式 (默认 'left' )
  26 + * @property {Object} customStyle 定义需要用到的外部样式
  27 + * @event {Function} click col被点击,会阻止事件冒泡到row
  28 + * @example <u-col span="3" offset="3" > <view class="demo-layout bg-purple"></view> </u-col>
  29 + */
  30 + export default {
  31 + name: 'u-col',
  32 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  33 + data() {
  34 + return {
  35 + width: 0,
  36 + parentData: {
  37 + gutter: 0
  38 + },
  39 + gridNum: 12
  40 + }
  41 + },
  42 + computed: {
  43 + uJustify() {
  44 + if (this.justify == 'end' || this.justify == 'start') return 'flex-' + this.justify
  45 + else if (this.justify == 'around' || this.justify == 'between') return 'space-' + this.justify
  46 + else return this.justify
  47 + },
  48 + uAlignItem() {
  49 + if (this.align == 'top') return 'flex-start'
  50 + if (this.align == 'bottom') return 'flex-end'
  51 + else return this.align
  52 + },
  53 + colStyle() {
  54 + const style = {
  55 + // 这里写成"padding: 0 10px"的形式是因为nvue的需要
  56 + paddingLeft: uni.$u.addUnit(uni.$u.getPx(this.parentData.gutter)/2),
  57 + paddingRight: uni.$u.addUnit(uni.$u.getPx(this.parentData.gutter)/2),
  58 + alignItems: this.uAlignItem,
  59 + justifyContent: this.uJustify,
  60 + textAlign: this.textAlign,
  61 + // #ifndef APP-NVUE
  62 + // 在非nvue上,使用百分比形式
  63 + flex: `0 0 ${100 / this.gridNum * this.span}%`,
  64 + marginLeft: 100 / 12 * this.offset + '%',
  65 + // #endif
  66 + // #ifdef APP-NVUE
  67 + // 在nvue上,由于无法使用百分比单位,这里需要获取父组件的宽度,再计算得出该有对应的百分比尺寸
  68 + width: uni.$u.addUnit(Math.floor(this.width / this.gridNum * Number(this.span))),
  69 + marginLeft: uni.$u.addUnit(Math.floor(this.width / this.gridNum * Number(this.offset))),
  70 + // #endif
  71 + }
  72 + return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
  73 + }
  74 + },
  75 + mounted() {
  76 + this.init()
  77 + },
  78 + methods: {
  79 + async init() {
  80 + // 支付宝小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环引用
  81 + this.updateParentData()
  82 + this.width = await this.parent.getComponentWidth()
  83 + },
  84 + updateParentData() {
  85 + this.getParentData('u-row')
  86 + },
  87 + clickHandler(e) {
  88 + this.$emit('click');
  89 + }
  90 + },
  91 + }
  92 +</script>
  93 +
  94 +<style lang="scss" scoped>
  95 + @import "../../libs/css/components.scss";
  96 +
  97 + .u-col {
  98 + padding: 0;
  99 + /* #ifndef APP-NVUE */
  100 + box-sizing:border-box;
  101 + /* #endif */
  102 + /* #ifdef MP */
  103 + display: block;
  104 + /* #endif */
  105 + }
  106 +
  107 + // nvue下百分比无效
  108 + /* #ifndef APP-NVUE */
  109 + .u-col-0 {
  110 + width: 0;
  111 + }
  112 +
  113 + .u-col-1 {
  114 + width: calc(100%/12);
  115 + }
  116 +
  117 + .u-col-2 {
  118 + width: calc(100%/12 * 2);
  119 + }
  120 +
  121 + .u-col-3 {
  122 + width: calc(100%/12 * 3);
  123 + }
  124 +
  125 + .u-col-4 {
  126 + width: calc(100%/12 * 4);
  127 + }
  128 +
  129 + .u-col-5 {
  130 + width: calc(100%/12 * 5);
  131 + }
  132 +
  133 + .u-col-6 {
  134 + width: calc(100%/12 * 6);
  135 + }
  136 +
  137 + .u-col-7 {
  138 + width: calc(100%/12 * 7);
  139 + }
  140 +
  141 + .u-col-8 {
  142 + width: calc(100%/12 * 8);
  143 + }
  144 +
  145 + .u-col-9 {
  146 + width: calc(100%/12 * 9);
  147 + }
  148 +
  149 + .u-col-10 {
  150 + width: calc(100%/12 * 10);
  151 + }
  152 +
  153 + .u-col-11 {
  154 + width: calc(100%/12 * 11);
  155 + }
  156 +
  157 + .u-col-12 {
  158 + width: calc(100%/12 * 12);
  159 + }
  160 +
  161 + /* #endif */
  162 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-collapse-item/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 标题
  4 + title: {
  5 + type: String,
  6 + default: uni.$u.props.collapseItem.title
  7 + },
  8 + // 标题右侧内容
  9 + value: {
  10 + type: String,
  11 + default: uni.$u.props.collapseItem.value
  12 + },
  13 + // 标题下方的描述信息
  14 + label: {
  15 + type: String,
  16 + default: uni.$u.props.collapseItem.label
  17 + },
  18 + // 是否禁用折叠面板
  19 + disabled: {
  20 + type: Boolean,
  21 + default: uni.$u.props.collapseItem.disabled
  22 + },
  23 + // 是否展示右侧箭头并开启点击反馈
  24 + isLink: {
  25 + type: Boolean,
  26 + default: uni.$u.props.collapseItem.isLink
  27 + },
  28 + // 是否开启点击反馈
  29 + clickable: {
  30 + type: Boolean,
  31 + default: uni.$u.props.collapseItem.clickable
  32 + },
  33 + // 是否显示内边框
  34 + border: {
  35 + type: Boolean,
  36 + default: uni.$u.props.collapseItem.border
  37 + },
  38 + // 标题的对齐方式
  39 + align: {
  40 + type: String,
  41 + default: uni.$u.props.collapseItem.align
  42 + },
  43 + // 唯一标识符
  44 + name: {
  45 + type: [String, Number],
  46 + default: uni.$u.props.collapseItem.name
  47 + },
  48 + // 标题左侧图片,可为绝对路径的图片或内置图标
  49 + icon: {
  50 + type: String,
  51 + default: uni.$u.props.collapseItem.icon
  52 + },
  53 + // 面板展开收起的过渡时间,单位ms
  54 + duration: {
  55 + type: Number,
  56 + default: uni.$u.props.collapseItem.duration
  57 + }
  58 + }
  59 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-collapse-item/u-collapse-item.vue 0 → 100644
  1 +<template>
  2 + <view class="u-collapse-item">
  3 + <u-cell
  4 + :title="title"
  5 + :value="value"
  6 + :label="label"
  7 + :icon="icon"
  8 + :isLink="isLink"
  9 + :clickable="clickable"
  10 + :border="parentData.border && showBorder"
  11 + @click="clickHandler"
  12 + :arrowDirection="expanded ? 'up' : 'down'"
  13 + :disabled="disabled"
  14 + >
  15 + <!-- #ifndef MP-WEIXIN -->
  16 + <!-- 微信小程序不支持,因为微信中不支持 <slot name="title" slot="title" />的写法 -->
  17 + <template slot="title">
  18 + <slot name="title"></slot>
  19 + </template>
  20 + <template slot="icon">
  21 + <slot name="icon"></slot>
  22 + </template>
  23 + <template slot="value">
  24 + <slot name="value"></slot>
  25 + </template>
  26 + <template slot="right-icon">
  27 + <slot name="right-icon"></slot>
  28 + </template>
  29 + <!-- #endif -->
  30 + </u-cell>
  31 + <view
  32 + class="u-collapse-item__content"
  33 + :animation="animationData"
  34 + ref="animation"
  35 + >
  36 + <view
  37 + class="u-collapse-item__content__text content-class"
  38 + :id="elId"
  39 + :ref="elId"
  40 + ><slot /></view>
  41 + </view>
  42 + <u-line v-if="parentData.border"></u-line>
  43 + </view>
  44 +</template>
  45 +
  46 +<script>
  47 + import props from './props.js';
  48 + // #ifdef APP-NVUE
  49 + const animation = uni.requireNativePlugin('animation')
  50 + const dom = uni.requireNativePlugin('dom')
  51 + // #endif
  52 + /**
  53 + * collapseItem 折叠面板Item
  54 + * @description 通过折叠面板收纳内容区域(搭配u-collapse使用)
  55 + * @tutorial https://www.uviewui.com/components/collapse.html
  56 + * @property {String} title 标题
  57 + * @property {String} value 标题右侧内容
  58 + * @property {String} label 标题下方的描述信息
  59 + * @property {Boolean} disbled 是否禁用折叠面板 ( 默认 false )
  60 + * @property {Boolean} isLink 是否展示右侧箭头并开启点击反馈 ( 默认 true )
  61 + * @property {Boolean} clickable 是否开启点击反馈 ( 默认 true )
  62 + * @property {Boolean} border 是否显示内边框 ( 默认 true )
  63 + * @property {String} align 标题的对齐方式 ( 默认 'left' )
  64 + * @property {String | Number} name 唯一标识符
  65 + * @property {String} icon 标题左侧图片,可为绝对路径的图片或内置图标
  66 + * @event {Function} change 某个item被打开或者收起时触发
  67 + * @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item>
  68 + */
  69 + export default {
  70 + name: "u-collapse-item",
  71 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  72 + data() {
  73 + return {
  74 + elId: uni.$u.guid(),
  75 + // uni.createAnimation的导出数据
  76 + animationData: {},
  77 + // 是否展开状态
  78 + expanded: false,
  79 + // 根据expanded确定是否显示border,为了控制展开时,cell的下划线更好的显示效果,进行一定时间的延时
  80 + showBorder: false,
  81 + // 是否动画中,如果是则不允许继续触发点击
  82 + animating: false,
  83 + // 父组件u-collapse的参数
  84 + parentData: {
  85 + accordion: false,
  86 + border: false
  87 + }
  88 + };
  89 + },
  90 + watch: {
  91 + expanded(n) {
  92 + clearTimeout(this.timer)
  93 + this.timer = null
  94 + // 这里根据expanded的值来进行一定的延时,是为了cell的下划线更好的显示效果
  95 + this.timer = setTimeout(() => {
  96 + this.showBorder = n
  97 + }, n ? 10 : 290)
  98 + }
  99 + },
  100 + mounted() {
  101 + this.init()
  102 + },
  103 + methods: {
  104 + // 异步获取内容,或者动态修改了内容时,需要重新初始化
  105 + init() {
  106 + // 初始化数据
  107 + this.updateParentData()
  108 + if (!this.parent) {
  109 + return uni.$u.error('u-collapse-item必须要搭配u-collapse组件使用')
  110 + }
  111 + const {
  112 + value,
  113 + accordion,
  114 + children = []
  115 + } = this.parent
  116 +
  117 + if (accordion) {
  118 + if (uni.$u.test.array(value)) {
  119 + return uni.$u.error('手风琴模式下,u-collapse组件的value参数不能为数组')
  120 + }
  121 + this.expanded = this.name == value
  122 + } else {
  123 + if (!uni.$u.test.array(value) && value !== null) {
  124 + return uni.$u.error('非手风琴模式下,u-collapse组件的value参数必须为数组')
  125 + }
  126 + this.expanded = (value || []).some(item => item == this.name)
  127 + }
  128 + // 设置组件的展开或收起状态
  129 + this.$nextTick(function() {
  130 + this.setContentAnimate()
  131 + })
  132 + },
  133 + updateParentData() {
  134 + // 此方法在mixin中
  135 + this.getParentData('u-collapse')
  136 + },
  137 + async setContentAnimate() {
  138 + // 每次面板打开或者收起时,都查询元素尺寸
  139 + // 好处是,父组件从服务端获取内容后,变更折叠面板后可以获得最新的高度
  140 + const rect = await this.queryRect()
  141 + const height = this.expanded ? rect.height : 0
  142 + this.animating = true
  143 + // #ifdef APP-NVUE
  144 + const ref = this.$refs['animation'].ref
  145 + animation.transition(ref, {
  146 + styles: {
  147 + height: height + 'px'
  148 + },
  149 + duration: this.duration,
  150 + // 必须设置为true,否则会到面板收起或展开时,页面其他元素不会随之调整它们的布局
  151 + needLayout: true,
  152 + timingFunction: 'ease-in-out',
  153 + }, () => {
  154 + this.animating = false
  155 + })
  156 + // #endif
  157 +
  158 + // #ifndef APP-NVUE
  159 + const animation = uni.createAnimation({
  160 + timingFunction: 'ease-in-out',
  161 + });
  162 + animation
  163 + .height(height)
  164 + .step({
  165 + duration: this.duration,
  166 + })
  167 + .step()
  168 + // 导出动画数据给面板的animationData值
  169 + this.animationData = animation.export()
  170 + // 标识动画结束
  171 + uni.$u.sleep(this.duration).then(() => {
  172 + this.animating = false
  173 + })
  174 + // #endif
  175 + },
  176 + // 点击collapsehead头部
  177 + clickHandler() {
  178 + if (this.disabled && this.animating) return
  179 + // 设置本组件为相反的状态
  180 + this.parent && this.parent.onChange(this)
  181 + },
  182 + // 查询内容高度
  183 + queryRect() {
  184 + // #ifndef APP-NVUE
  185 + // $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://www.uviewui.com/js/getRect.html
  186 + // 组件内部一般用this.$uGetRect,对外的为uni.$u.getRect,二者功能一致,名称不同
  187 + return new Promise(resolve => {
  188 + this.$uGetRect(`#${this.elId}`).then(size => {
  189 + resolve(size)
  190 + })
  191 + })
  192 + // #endif
  193 +
  194 + // #ifdef APP-NVUE
  195 + // nvue下,使用dom模块查询元素高度
  196 + // 返回一个promise,让调用此方法的主体能使用then回调
  197 + return new Promise(resolve => {
  198 + dom.getComponentRect(this.$refs[this.elId], res => {
  199 + resolve(res.size)
  200 + })
  201 + })
  202 + // #endif
  203 + }
  204 + },
  205 + };
  206 +</script>
  207 +
  208 +<style lang="scss" scoped>
  209 + @import "../../libs/css/components.scss";
  210 +
  211 + .u-collapse-item {
  212 +
  213 + &__content {
  214 + overflow: hidden;
  215 + height: 0;
  216 +
  217 + &__text {
  218 + padding: 12px 15px;
  219 + color: $u-content-color;
  220 + font-size: 14px;
  221 + line-height: 18px;
  222 + }
  223 + }
  224 + }
  225 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-collapse/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 当前展开面板的name,非手风琴模式:[<string | number>],手风琴模式:string | number
  4 + value: {
  5 + type: [String, Number, Array, null],
  6 + default: uni.$u.props.collapse.value
  7 + },
  8 + // 是否手风琴模式
  9 + accordion: {
  10 + type: Boolean,
  11 + default: uni.$u.props.collapse.accordion
  12 + },
  13 + // 是否显示外边框
  14 + border: {
  15 + type: Boolean,
  16 + default: uni.$u.props.collapse.border
  17 + }
  18 + }
  19 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-collapse/u-collapse.vue 0 → 100644
  1 +<template>
  2 + <view class="u-collapse">
  3 + <u-line v-if="border"></u-line>
  4 + <slot />
  5 + </view>
  6 +</template>
  7 +
  8 +<script>
  9 + import props from './props.js';
  10 + /**
  11 + * collapse 折叠面板
  12 + * @description 通过折叠面板收纳内容区域
  13 + * @tutorial https://www.uviewui.com/components/collapse.html
  14 + * @property {String | Number | Array} value 当前展开面板的name,非手风琴模式:[<string | number>],手风琴模式:string | number
  15 + * @property {Boolean} accordion 是否手风琴模式( 默认 false )
  16 + * @property {Boolean} border 是否显示外边框 ( 默认 true )
  17 + * @event {Function} change 当前激活面板展开时触发(如果是手风琴模式,参数activeNames类型为String,否则为Array)
  18 + * @example <u-collapse></u-collapse>
  19 + */
  20 + export default {
  21 + name: "u-collapse",
  22 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  23 + watch: {
  24 + needInit() {
  25 + this.init()
  26 + }
  27 + },
  28 + created() {
  29 + this.children = []
  30 + },
  31 + computed: {
  32 + needInit() {
  33 + // 通过computed,同时监听accordion和value值的变化
  34 + // 再通过watch去执行init()方法,进行再一次的初始化
  35 + return [this.accordion, this.value]
  36 + }
  37 + },
  38 + watch: {
  39 + // 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件
  40 + parentData() {
  41 + if (this.children.length) {
  42 + this.children.map(child => {
  43 + // 判断子组件(u-checkbox)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
  44 + typeof(child.updateParentData) === 'function' && child.updateParentData()
  45 + })
  46 + }
  47 + },
  48 + },
  49 + methods: {
  50 + // 重新初始化一次内部的所有子元素
  51 + init() {
  52 + this.children.map(child => {
  53 + child.init()
  54 + })
  55 + },
  56 + /**
  57 + * collapse-item被点击时触发,由collapse统一处理各子组件的状态
  58 + * @param {Object} target 被操作的面板的实例
  59 + */
  60 + onChange(target) {
  61 + let changeArr = []
  62 + this.children.map((child, index) => {
  63 + // 如果是手风琴模式,将其他的折叠面板收起来
  64 + if (this.accordion) {
  65 + child.expanded = child === target ? !target.expanded : false
  66 + child.setContentAnimate()
  67 + } else {
  68 + if(child === target) {
  69 + child.expanded = !child.expanded
  70 + child.setContentAnimate()
  71 + }
  72 + }
  73 + // 拼接change事件中,数组元素的状态
  74 + changeArr.push({
  75 + // 如果没有定义name属性,则默认返回组件的index索引
  76 + name: child.name || index,
  77 + status: child.expanded ? 'open' : 'close'
  78 + })
  79 + })
  80 +
  81 + this.$emit('change', changeArr)
  82 + this.$emit(target.expanded ? 'open' : 'close', target.name)
  83 + }
  84 + }
  85 + }
  86 +</script>
  87 +
  88 +<style lang="scss" scoped>
  89 + @import "../../libs/css/components.scss";
  90 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-column-notice/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 显示的内容,字符串
  4 + text: {
  5 + type: [Array],
  6 + default: uni.$u.props.columnNotice.text
  7 + },
  8 + // 是否显示左侧的音量图标
  9 + icon: {
  10 + type: String,
  11 + default: uni.$u.props.columnNotice.icon
  12 + },
  13 + // 通告模式,link-显示右箭头,closable-显示右侧关闭图标
  14 + mode: {
  15 + type: String,
  16 + default: uni.$u.props.columnNotice.mode
  17 + },
  18 + // 文字颜色,各图标也会使用文字颜色
  19 + color: {
  20 + type: String,
  21 + default: uni.$u.props.columnNotice.color
  22 + },
  23 + // 背景颜色
  24 + bgColor: {
  25 + type: String,
  26 + default: uni.$u.props.columnNotice.bgColor
  27 + },
  28 + // 字体大小,单位px
  29 + fontSize: {
  30 + type: [String, Number],
  31 + default: uni.$u.props.columnNotice.fontSize
  32 + },
  33 + // 水平滚动时的滚动速度,即每秒滚动多少px(px),这有利于控制文字无论多少时,都能有一个恒定的速度
  34 + speed: {
  35 + type: [String, Number],
  36 + default: uni.$u.props.columnNotice.speed
  37 + },
  38 + // direction = row时,是否使用步进形式滚动
  39 + step: {
  40 + type: Boolean,
  41 + default: uni.$u.props.columnNotice.step
  42 + },
  43 + // 滚动一个周期的时间长,单位ms
  44 + duration: {
  45 + type: [String, Number],
  46 + default: uni.$u.props.columnNotice.duration
  47 + },
  48 + // 是否禁止用手滑动切换
  49 + // 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序
  50 + disableTouch: {
  51 + type: Boolean,
  52 + default: uni.$u.props.columnNotice.disableTouch
  53 + }
  54 + }
  55 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-column-notice/u-column-notice.vue 0 → 100644
  1 +<template>
  2 + <view
  3 + class="u-notice"
  4 + @tap="clickHandler"
  5 + >
  6 + <slot name="icon">
  7 + <view
  8 + class="u-notice__left-icon"
  9 + v-if="icon"
  10 + >
  11 + <u-icon
  12 + :name="icon"
  13 + :color="color"
  14 + size="19"
  15 + ></u-icon>
  16 + </view>
  17 + </slot>
  18 + <swiper
  19 + :disable-touch="disableTouch"
  20 + :vertical="step ? false : true"
  21 + circular
  22 + :interval="duration"
  23 + :autoplay="true"
  24 + class="u-notice__swiper"
  25 + @change="noticeChange"
  26 + >
  27 + <swiper-item
  28 + v-for="(item, index) in text"
  29 + :key="index"
  30 + class="u-notice__swiper__item"
  31 + >
  32 + <text
  33 + class="u-notice__swiper__item__text u-line-1"
  34 + :style="[textStyle]"
  35 + >{{ item }}</text>
  36 + </swiper-item>
  37 + </swiper>
  38 + <view
  39 + class="u-notice__right-icon"
  40 + v-if="['link', 'closable'].includes(mode)"
  41 + >
  42 + <u-icon
  43 + v-if="mode === 'link'"
  44 + name="arrow-right"
  45 + :size="17"
  46 + :color="color"
  47 + ></u-icon>
  48 + <u-icon
  49 + v-if="mode === 'closable'"
  50 + name="close"
  51 + :size="16"
  52 + :color="color"
  53 + @click="close"
  54 + ></u-icon>
  55 + </view>
  56 + </view>
  57 +</template>
  58 +
  59 +<script>
  60 + import props from './props.js';
  61 + /**
  62 + * ColumnNotice 滚动通知中的垂直滚动 内部组件
  63 + * @description 该组件用于滚动通告场景,是其中的垂直滚动方式
  64 + * @tutorial https://www.uviewui.com/components/noticeBar.html
  65 + * @property {Array} text 显示的内容,字符串
  66 + * @property {String} icon 是否显示左侧的音量图标 ( 默认 'volume' )
  67 + * @property {String} mode 通告模式,link-显示右箭头,closable-显示右侧关闭图标
  68 + * @property {String} color 文字颜色,各图标也会使用文字颜色 ( 默认 '#f9ae3d' )
  69 + * @property {String} bgColor 背景颜色 ( 默认 '#fdf6ec' )
  70 + * @property {String | Number} fontSize 字体大小,单位px ( 默认 14 )
  71 + * @property {String | Number} speed 水平滚动时的滚动速度,即每秒滚动多少px(rpx),这有利于控制文字无论多少时,都能有一个恒定的速度 ( 默认 80 )
  72 + * @property {Boolean} step direction = row时,是否使用步进形式滚动 ( 默认 false )
  73 + * @property {String | Number} duration 滚动一个周期的时间长,单位ms ( 默认 1500 )
  74 + * @property {Boolean} disableTouch 是否禁止用手滑动切换 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序 ( 默认 true )
  75 + * @example
  76 + */
  77 + export default {
  78 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  79 + watch: {
  80 + text: {
  81 + immediate: true,
  82 + handler(newValue, oldValue) {
  83 + if(!uni.$u.test.array(newValue)) {
  84 + uni.$u.error('noticebar组件direction为column时,要求text参数为数组形式')
  85 + }
  86 + }
  87 + }
  88 + },
  89 + computed: {
  90 + // 文字内容的样式
  91 + textStyle() {
  92 + let style = {}
  93 + style.color = this.color
  94 + style.fontSize = uni.$u.addUnit(this.fontSize)
  95 + return style
  96 + },
  97 + // 垂直或者水平滚动
  98 + vertical() {
  99 + if (this.mode == 'horizontal') return false
  100 + else return true
  101 + },
  102 + },
  103 + data() {
  104 + return {
  105 + index:0
  106 + }
  107 + },
  108 + methods: {
  109 + noticeChange(e){
  110 + this.index = e.detail.current
  111 + },
  112 + // 点击通告栏
  113 + clickHandler() {
  114 + this.$emit('click', this.index)
  115 + },
  116 + // 点击关闭按钮
  117 + close() {
  118 + this.$emit('close')
  119 + }
  120 + }
  121 + };
  122 +</script>
  123 +
  124 +<style lang="scss" scoped>
  125 + @import "../../libs/css/components.scss";
  126 +
  127 + .u-notice {
  128 + @include flex;
  129 + align-items: center;
  130 + justify-content: space-between;
  131 +
  132 + &__left-icon {
  133 + align-items: center;
  134 + margin-right: 5px;
  135 + }
  136 +
  137 + &__right-icon {
  138 + margin-left: 5px;
  139 + align-items: center;
  140 + }
  141 +
  142 + &__swiper {
  143 + height: 16px;
  144 + @include flex;
  145 + align-items: center;
  146 + flex: 1;
  147 +
  148 + &__item {
  149 + @include flex;
  150 + align-items: center;
  151 + overflow: hidden;
  152 +
  153 + &__text {
  154 + font-size: 14px;
  155 + color: $u-warning;
  156 + }
  157 + }
  158 + }
  159 + }
  160 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-count-down/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 倒计时时长,单位ms
  4 + time: {
  5 + type: [String, Number],
  6 + default: uni.$u.props.countDown.time
  7 + },
  8 + // 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒
  9 + format: {
  10 + type: String,
  11 + default: uni.$u.props.countDown.format
  12 + },
  13 + // 是否自动开始倒计时
  14 + autoStart: {
  15 + type: Boolean,
  16 + default: uni.$u.props.countDown.autoStart
  17 + },
  18 + // 是否展示毫秒倒计时
  19 + millisecond: {
  20 + type: Boolean,
  21 + default: uni.$u.props.countDown.millisecond
  22 + }
  23 + }
  24 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-count-down/u-count-down.vue 0 → 100644
  1 +<template>
  2 + <view class="u-count-down">
  3 + <slot>
  4 + <text class="u-count-down__text">{{ formattedTime }}</text>
  5 + </slot>
  6 + </view>
  7 +</template>
  8 +
  9 +<script>
  10 + import props from './props.js';
  11 + import {
  12 + isSameSecond,
  13 + parseFormat,
  14 + parseTimeData
  15 + } from './utils';
  16 + /**
  17 + * u-count-down 倒计时
  18 + * @description 该组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。
  19 + * @tutorial https://uviewui.com/components/countDown.html
  20 + * @property {String | Number} time 倒计时时长,单位ms (默认 0 )
  21 + * @property {String} format 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒 (默认 'HH:mm:ss' )
  22 + * @property {Boolean} autoStart 是否自动开始倒计时 (默认 true )
  23 + * @property {Boolean} millisecond 是否展示毫秒倒计时 (默认 false )
  24 + * @event {Function} finish 倒计时结束时触发
  25 + * @event {Function} change 倒计时变化时触发
  26 + * @event {Function} start 开始倒计时
  27 + * @event {Function} pause 暂停倒计时
  28 + * @event {Function} reset 重设倒计时,若 auto-start 为 true,重设后会自动开始倒计时
  29 + * @example <u-count-down :time="time"></u-count-down>
  30 + */
  31 + export default {
  32 + name: 'u-count-down',
  33 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  34 + data() {
  35 + return {
  36 + timer: null,
  37 + // 各单位(天,时,分等)剩余时间
  38 + timeData: parseTimeData(0),
  39 + // 格式化后的时间,如"03:23:21"
  40 + formattedTime: '0',
  41 + // 倒计时是否正在进行中
  42 + runing: false,
  43 + endTime: 0, // 结束的毫秒时间戳
  44 + remainTime: 0, // 剩余的毫秒时间
  45 + }
  46 + },
  47 + watch: {
  48 + time(n) {
  49 + this.reset()
  50 + }
  51 + },
  52 + mounted() {
  53 + this.init()
  54 + },
  55 + methods: {
  56 + init() {
  57 + this.reset()
  58 + },
  59 + // 开始倒计时
  60 + start() {
  61 + if (this.runing) return
  62 + // 标识为进行中
  63 + this.runing = true
  64 + // 结束时间戳 = 此刻时间戳 + 剩余的时间
  65 + this.endTime = Date.now() + this.remainTime
  66 + this.toTick()
  67 + },
  68 + // 根据是否展示毫秒,执行不同操作函数
  69 + toTick() {
  70 + if (this.millisecond) {
  71 + this.microTick()
  72 + } else {
  73 + this.macroTick()
  74 + }
  75 + },
  76 + macroTick() {
  77 + this.clearTimeout()
  78 + // 每隔一定时间,更新一遍定时器的值
  79 + // 同时此定时器的作用也能带来毫秒级的更新
  80 + this.timer = setTimeout(() => {
  81 + // 获取剩余时间
  82 + const remain = this.getRemainTime()
  83 + // 重设剩余时间
  84 + if (!isSameSecond(remain, this.remainTime) || remain === 0) {
  85 + this.setRemainTime(remain)
  86 + }
  87 + // 如果剩余时间不为0,则继续检查更新倒计时
  88 + if (this.remainTime !== 0) {
  89 + this.macroTick()
  90 + }
  91 + }, 30)
  92 + },
  93 + microTick() {
  94 + this.clearTimeout()
  95 + this.timer = setTimeout(() => {
  96 + this.setRemainTime(this.getRemainTime())
  97 + if (this.remainTime !== 0) {
  98 + this.microTick()
  99 + }
  100 + }, 50)
  101 + },
  102 + // 获取剩余的时间
  103 + getRemainTime() {
  104 + // 取最大值,防止出现小于0的剩余时间值
  105 + return Math.max(this.endTime - Date.now(), 0)
  106 + },
  107 + // 设置剩余的时间
  108 + setRemainTime(remain) {
  109 + this.remainTime = remain
  110 + // 根据剩余的毫秒时间,得出该有天,小时,分钟等的值,返回一个对象
  111 + const timeData = parseTimeData(remain)
  112 + this.$emit('change', timeData)
  113 + // 得出格式化后的时间
  114 + this.formattedTime = parseFormat(this.format, timeData)
  115 + // 如果时间已到,停止倒计时
  116 + if (remain <= 0) {
  117 + this.pause()
  118 + this.$emit('finish')
  119 + }
  120 + },
  121 + // 重置倒计时
  122 + reset() {
  123 + this.pause()
  124 + this.remainTime = this.time
  125 + this.setRemainTime(this.remainTime)
  126 + if (this.autoStart) {
  127 + this.start()
  128 + }
  129 + },
  130 + // 暂停倒计时
  131 + pause() {
  132 + this.runing = false;
  133 + this.clearTimeout()
  134 + },
  135 + // 清空定时器
  136 + clearTimeout() {
  137 + clearTimeout(this.timer)
  138 + this.timer = null
  139 + }
  140 + },
  141 + beforeDestroy() {
  142 + this.clearTimeout()
  143 + }
  144 + }
  145 +</script>
  146 +
  147 +<style
  148 + lang="scss"
  149 + scoped
  150 +>
  151 + @import "../../libs/css/components.scss";
  152 + $u-count-down-text-color:$u-content-color !default;
  153 + $u-count-down-text-font-size:15px !default;
  154 + $u-count-down-text-line-height:22px !default;
  155 +
  156 + .u-count-down {
  157 + &__text {
  158 + color: $u-count-down-text-color;
  159 + font-size: $u-count-down-text-font-size;
  160 + line-height: $u-count-down-text-line-height;
  161 + }
  162 + }
  163 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-count-down/utils.js 0 → 100644
  1 +// 补0,如1 -> 01
  2 +function padZero(num, targetLength = 2) {
  3 + let str = `${num}`
  4 + while (str.length < targetLength) {
  5 + str = `0${str}`
  6 + }
  7 + return str
  8 +}
  9 +const SECOND = 1000
  10 +const MINUTE = 60 * SECOND
  11 +const HOUR = 60 * MINUTE
  12 +const DAY = 24 * HOUR
  13 +export function parseTimeData(time) {
  14 + const days = Math.floor(time / DAY)
  15 + const hours = Math.floor((time % DAY) / HOUR)
  16 + const minutes = Math.floor((time % HOUR) / MINUTE)
  17 + const seconds = Math.floor((time % MINUTE) / SECOND)
  18 + const milliseconds = Math.floor(time % SECOND)
  19 + return {
  20 + days,
  21 + hours,
  22 + minutes,
  23 + seconds,
  24 + milliseconds
  25 + }
  26 +}
  27 +export function parseFormat(format, timeData) {
  28 + let {
  29 + days,
  30 + hours,
  31 + minutes,
  32 + seconds,
  33 + milliseconds
  34 + } = timeData
  35 + // 如果格式化字符串中不存在DD(天),则将天的时间转为小时中去
  36 + if (format.indexOf('DD') === -1) {
  37 + hours += days * 24
  38 + } else {
  39 + // 对天补0
  40 + format = format.replace('DD', padZero(days))
  41 + }
  42 + // 其他同理于DD的格式化处理方式
  43 + if (format.indexOf('HH') === -1) {
  44 + minutes += hours * 60
  45 + } else {
  46 + format = format.replace('HH', padZero(hours))
  47 + }
  48 + if (format.indexOf('mm') === -1) {
  49 + seconds += minutes * 60
  50 + } else {
  51 + format = format.replace('mm', padZero(minutes))
  52 + }
  53 + if (format.indexOf('ss') === -1) {
  54 + milliseconds += seconds * 1000
  55 + } else {
  56 + format = format.replace('ss', padZero(seconds))
  57 + }
  58 + return format.replace('SSS', padZero(milliseconds, 3))
  59 +}
  60 +export function isSameSecond(time1, time2) {
  61 + return Math.floor(time1 / 1000) === Math.floor(time2 / 1000)
  62 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-count-to/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 开始的数值,默认从0增长到某一个数
  4 + startVal: {
  5 + type: [String, Number],
  6 + default: uni.$u.props.countTo.startVal
  7 + },
  8 + // 要滚动的目标数值,必须
  9 + endVal: {
  10 + type: [String, Number],
  11 + default: uni.$u.props.countTo.endVal
  12 + },
  13 + // 滚动到目标数值的动画持续时间,单位为毫秒(ms)
  14 + duration: {
  15 + type: [String, Number],
  16 + default: uni.$u.props.countTo.duration
  17 + },
  18 + // 设置数值后是否自动开始滚动
  19 + autoplay: {
  20 + type: Boolean,
  21 + default: uni.$u.props.countTo.autoplay
  22 + },
  23 + // 要显示的小数位数
  24 + decimals: {
  25 + type: [String, Number],
  26 + default: uni.$u.props.countTo.decimals
  27 + },
  28 + // 是否在即将到达目标数值的时候,使用缓慢滚动的效果
  29 + useEasing: {
  30 + type: Boolean,
  31 + default: uni.$u.props.countTo.useEasing
  32 + },
  33 + // 十进制分割
  34 + decimal: {
  35 + type: [String, Number],
  36 + default: uni.$u.props.countTo.decimal
  37 + },
  38 + // 字体颜色
  39 + color: {
  40 + type: String,
  41 + default: uni.$u.props.countTo.color
  42 + },
  43 + // 字体大小
  44 + fontSize: {
  45 + type: [String, Number],
  46 + default: uni.$u.props.countTo.fontSize
  47 + },
  48 + // 是否加粗字体
  49 + bold: {
  50 + type: Boolean,
  51 + default: uni.$u.props.countTo.bold
  52 + },
  53 + // 千位分隔符,类似金额的分割(¥23,321.05中的",")
  54 + separator: {
  55 + type: String,
  56 + default: uni.$u.props.countTo.separator
  57 + }
  58 + }
  59 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-count-to/u-count-to.vue 0 → 100644
  1 +<template>
  2 + <text
  3 + class="u-count-num"
  4 + :style="{
  5 + fontSize: $u.addUnit(fontSize),
  6 + fontWeight: bold ? 'bold' : 'normal',
  7 + color: color
  8 + }"
  9 + >{{ displayValue }}</text>
  10 +</template>
  11 +
  12 +<script>
  13 + import props from './props.js';
  14 +/**
  15 + * countTo 数字滚动
  16 + * @description 该组件一般用于需要滚动数字到某一个值的场景,目标要求是一个递增的值。
  17 + * @tutorial https://www.uviewui.com/components/countTo.html
  18 + * @property {String | Number} startVal 开始的数值,默认从0增长到某一个数(默认 0 )
  19 + * @property {String | Number} endVal 要滚动的目标数值,必须 (默认 0 )
  20 + * @property {String | Number} duration 滚动到目标数值的动画持续时间,单位为毫秒(ms) (默认 2000 )
  21 + * @property {Boolean} autoplay 设置数值后是否自动开始滚动 (默认 true )
  22 + * @property {String | Number} decimals 要显示的小数位数,见官网说明(默认 0 )
  23 + * @property {Boolean} useEasing 滚动结束时,是否缓动结尾,见官网说明(默认 true )
  24 + * @property {String} decimal 十进制分割 ( 默认 "." )
  25 + * @property {String} color 字体颜色( 默认 '#606266' )
  26 + * @property {String | Number} fontSize 字体大小,单位px( 默认 22 )
  27 + * @property {Boolean} bold 字体是否加粗(默认 false )
  28 + * @property {String} separator 千位分隔符,见官网说明
  29 + * @event {Function} end 数值滚动到目标值时触发
  30 + * @example <u-count-to ref="uCountTo" :end-val="endVal" :autoplay="autoplay"></u-count-to>
  31 + */
  32 +export default {
  33 + name: 'u-count-to',
  34 + data() {
  35 + return {
  36 + localStartVal: this.startVal,
  37 + displayValue: this.formatNumber(this.startVal),
  38 + printVal: null,
  39 + paused: false, // 是否暂停
  40 + localDuration: Number(this.duration),
  41 + startTime: null, // 开始的时间
  42 + timestamp: null, // 时间戳
  43 + remaining: null, // 停留的时间
  44 + rAF: null,
  45 + lastTime: 0 // 上一次的时间
  46 + };
  47 + },
  48 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  49 + computed: {
  50 + countDown() {
  51 + return this.startVal > this.endVal;
  52 + }
  53 + },
  54 + watch: {
  55 + startVal() {
  56 + this.autoplay && this.start();
  57 + },
  58 + endVal() {
  59 + this.autoplay && this.start();
  60 + }
  61 + },
  62 + mounted() {
  63 + this.autoplay && this.start();
  64 + },
  65 + methods: {
  66 + easingFn(t, b, c, d) {
  67 + return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;
  68 + },
  69 + requestAnimationFrame(callback) {
  70 + const currTime = new Date().getTime();
  71 + // 为了使setTimteout的尽可能的接近每秒60帧的效果
  72 + const timeToCall = Math.max(0, 16 - (currTime - this.lastTime));
  73 + const id = setTimeout(() => {
  74 + callback(currTime + timeToCall);
  75 + }, timeToCall);
  76 + this.lastTime = currTime + timeToCall;
  77 + return id;
  78 + },
  79 + cancelAnimationFrame(id) {
  80 + clearTimeout(id);
  81 + },
  82 + // 开始滚动数字
  83 + start() {
  84 + this.localStartVal = this.startVal;
  85 + this.startTime = null;
  86 + this.localDuration = this.duration;
  87 + this.paused = false;
  88 + this.rAF = this.requestAnimationFrame(this.count);
  89 + },
  90 + // 暂定状态,重新再开始滚动;或者滚动状态下,暂停
  91 + reStart() {
  92 + if (this.paused) {
  93 + this.resume();
  94 + this.paused = false;
  95 + } else {
  96 + this.stop();
  97 + this.paused = true;
  98 + }
  99 + },
  100 + // 暂停
  101 + stop() {
  102 + this.cancelAnimationFrame(this.rAF);
  103 + },
  104 + // 重新开始(暂停的情况下)
  105 + resume() {
  106 + if (!this.remaining) return
  107 + this.startTime = 0;
  108 + this.localDuration = this.remaining;
  109 + this.localStartVal = this.printVal;
  110 + this.requestAnimationFrame(this.count);
  111 + },
  112 + // 重置
  113 + reset() {
  114 + this.startTime = null;
  115 + this.cancelAnimationFrame(this.rAF);
  116 + this.displayValue = this.formatNumber(this.startVal);
  117 + },
  118 + count(timestamp) {
  119 + if (!this.startTime) this.startTime = timestamp;
  120 + this.timestamp = timestamp;
  121 + const progress = timestamp - this.startTime;
  122 + this.remaining = this.localDuration - progress;
  123 + if (this.useEasing) {
  124 + if (this.countDown) {
  125 + this.printVal = this.localStartVal - this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration);
  126 + } else {
  127 + this.printVal = this.easingFn(progress, this.localStartVal, this.endVal - this.localStartVal, this.localDuration);
  128 + }
  129 + } else {
  130 + if (this.countDown) {
  131 + this.printVal = this.localStartVal - (this.localStartVal - this.endVal) * (progress / this.localDuration);
  132 + } else {
  133 + this.printVal = this.localStartVal + (this.endVal - this.localStartVal) * (progress / this.localDuration);
  134 + }
  135 + }
  136 + if (this.countDown) {
  137 + this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal;
  138 + } else {
  139 + this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal;
  140 + }
  141 + this.displayValue = this.formatNumber(this.printVal) || 0;
  142 + if (progress < this.localDuration) {
  143 + this.rAF = this.requestAnimationFrame(this.count);
  144 + } else {
  145 + this.$emit('end');
  146 + }
  147 + },
  148 + // 判断是否数字
  149 + isNumber(val) {
  150 + return !isNaN(parseFloat(val));
  151 + },
  152 + formatNumber(num) {
  153 + // 将num转为Number类型,因为其值可能为字符串数值,调用toFixed会报错
  154 + num = Number(num);
  155 + num = num.toFixed(Number(this.decimals));
  156 + num += '';
  157 + const x = num.split('.');
  158 + let x1 = x[0];
  159 + const x2 = x.length > 1 ? this.decimal + x[1] : '';
  160 + const rgx = /(\d+)(\d{3})/;
  161 + if (this.separator && !this.isNumber(this.separator)) {
  162 + while (rgx.test(x1)) {
  163 + x1 = x1.replace(rgx, '$1' + this.separator + '$2');
  164 + }
  165 + }
  166 + return x1 + x2;
  167 + },
  168 + destroyed() {
  169 + this.cancelAnimationFrame(this.rAF);
  170 + }
  171 + }
  172 +};
  173 +</script>
  174 +
  175 +<style lang="scss" scoped>
  176 +@import "../../libs/css/components.scss";
  177 +
  178 +.u-count-num {
  179 + /* #ifndef APP-NVUE */
  180 + display: inline-flex;
  181 + /* #endif */
  182 + text-align: center;
  183 +}
  184 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-datetime-picker/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 是否打开组件
  4 + show: {
  5 + type: Boolean,
  6 + default: uni.$u.props.datetimePicker.show
  7 + },
  8 + // 是否展示顶部的操作栏
  9 + showToolbar: {
  10 + type: Boolean,
  11 + default: uni.$u.props.datetimePicker.showToolbar
  12 + },
  13 + // 绑定值
  14 + value: {
  15 + type: [String, Number],
  16 + default: uni.$u.props.datetimePicker.value
  17 + },
  18 + // 顶部标题
  19 + title: {
  20 + type: String,
  21 + default: uni.$u.props.datetimePicker.title
  22 + },
  23 + // 展示格式,mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择
  24 + mode: {
  25 + type: String,
  26 + default: uni.$u.props.datetimePicker.mode
  27 + },
  28 + // 可选的最大时间
  29 + maxDate: {
  30 + type: Number,
  31 + // 最大默认值为后10年
  32 + default: uni.$u.props.datetimePicker.maxDate
  33 + },
  34 + // 可选的最小时间
  35 + minDate: {
  36 + type: Number,
  37 + // 最小默认值为前10年
  38 + default: uni.$u.props.datetimePicker.minDate
  39 + },
  40 + // 可选的最小小时,仅mode=time有效
  41 + minHour: {
  42 + type: Number,
  43 + default: uni.$u.props.datetimePicker.minHour
  44 + },
  45 + // 可选的最大小时,仅mode=time有效
  46 + maxHour: {
  47 + type: Number,
  48 + default: uni.$u.props.datetimePicker.maxHour
  49 + },
  50 + // 可选的最小分钟,仅mode=time有效
  51 + minMinute: {
  52 + type: Number,
  53 + default: uni.$u.props.datetimePicker.minMinute
  54 + },
  55 + // 可选的最大分钟,仅mode=time有效
  56 + maxMinute: {
  57 + type: Number,
  58 + default: uni.$u.props.datetimePicker.maxMinute
  59 + },
  60 + // 选项过滤函数
  61 + filter: {
  62 + type: [Function, null],
  63 + default: uni.$u.props.datetimePicker.filter
  64 + },
  65 + // 选项格式化函数
  66 + formatter: {
  67 + type: [Function, null],
  68 + default: uni.$u.props.datetimePicker.formatter
  69 + },
  70 + // 是否显示加载中状态
  71 + loading: {
  72 + type: Boolean,
  73 + default: uni.$u.props.datetimePicker.loading
  74 + },
  75 + // 各列中,单个选项的高度
  76 + itemHeight: {
  77 + type: [String, Number],
  78 + default: uni.$u.props.datetimePicker.itemHeight
  79 + },
  80 + // 取消按钮的文字
  81 + cancelText: {
  82 + type: String,
  83 + default: uni.$u.props.datetimePicker.cancelText
  84 + },
  85 + // 确认按钮的文字
  86 + confirmText: {
  87 + type: String,
  88 + default: uni.$u.props.datetimePicker.confirmText
  89 + },
  90 + // 取消按钮的颜色
  91 + cancelColor: {
  92 + type: String,
  93 + default: uni.$u.props.datetimePicker.cancelColor
  94 + },
  95 + // 确认按钮的颜色
  96 + confirmColor: {
  97 + type: String,
  98 + default: uni.$u.props.datetimePicker.confirmColor
  99 + },
  100 + // 每列中可见选项的数量
  101 + visibleItemCount: {
  102 + type: [String, Number],
  103 + default: uni.$u.props.datetimePicker.visibleItemCount
  104 + },
  105 + // 是否允许点击遮罩关闭选择器
  106 + closeOnClickOverlay: {
  107 + type: Boolean,
  108 + default: uni.$u.props.datetimePicker.closeOnClickOverlay
  109 + },
  110 + // 各列的默认索引
  111 + defaultIndex: {
  112 + type: Array,
  113 + default: uni.$u.props.datetimePicker.defaultIndex
  114 + }
  115 + }
  116 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-datetime-picker/u-datetime-picker.vue 0 → 100644
  1 +<template>
  2 + <u-picker
  3 + ref="picker"
  4 + :show="show"
  5 + :closeOnClickOverlay="closeOnClickOverlay"
  6 + :columns="columns"
  7 + :title="title"
  8 + :itemHeight="itemHeight"
  9 + :showToolbar="showToolbar"
  10 + :visibleItemCount="visibleItemCount"
  11 + :defaultIndex="innerDefaultIndex"
  12 + :cancelText="cancelText"
  13 + :confirmText="confirmText"
  14 + :cancelColor="cancelColor"
  15 + :confirmColor="confirmColor"
  16 + @close="close"
  17 + @cancel="cancel"
  18 + @confirm="confirm"
  19 + @change="change"
  20 + >
  21 + </u-picker>
  22 +</template>
  23 +
  24 +<script>
  25 + function times(n, iteratee) {
  26 + let index = -1
  27 + const result = Array(n < 0 ? 0 : n)
  28 + while (++index < n) {
  29 + result[index] = iteratee(index)
  30 + }
  31 + return result
  32 + }
  33 + import props from './props.js';
  34 + import dayjs from '../../libs/util/dayjs.js';
  35 + /**
  36 + * DatetimePicker 时间日期选择器
  37 + * @description 此选择器用于时间日期
  38 + * @tutorial https://www.uviewui.com/components/datetimePicker.html
  39 + * @property {Boolean} show 用于控制选择器的弹出与收起 ( 默认 false )
  40 + * @property {Boolean} showToolbar 是否显示顶部的操作栏 ( 默认 true )
  41 + * @property {String | Number} value 绑定值
  42 + * @property {String} title 顶部标题
  43 + * @property {String} mode 展示格式 mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择 ( 默认 ‘datetime )
  44 + * @property {Number} maxDate 可选的最大时间 默认值为后10年
  45 + * @property {Number} minDate 可选的最小时间 默认值为前10年
  46 + * @property {Number} minHour 可选的最小小时,仅mode=time有效 ( 默认 0 )
  47 + * @property {Number} maxHour 可选的最大小时,仅mode=time有效 ( 默认 23 )
  48 + * @property {Number} minMinute 可选的最小分钟,仅mode=time有效 ( 默认 0 )
  49 + * @property {Number} maxMinute 可选的最大分钟,仅mode=time有效 ( 默认 59 )
  50 + * @property {Function} filter 选项过滤函数
  51 + * @property {Function} formatter 选项格式化函数
  52 + * @property {Boolean} loading 是否显示加载中状态 ( 默认 false )
  53 + * @property {String | Number} itemHeight 各列中,单个选项的高度 ( 默认 44 )
  54 + * @property {String} cancelText 取消按钮的文字 ( 默认 '取消' )
  55 + * @property {String} confirmText 确认按钮的文字 ( 默认 '确认' )
  56 + * @property {String} cancelColor 取消按钮的颜色 ( 默认 '#909193' )
  57 + * @property {String} confirmColor 确认按钮的颜色 ( 默认 '#3c9cff' )
  58 + * @property {String | Number} visibleItemCount 每列中可见选项的数量 ( 默认 5 )
  59 + * @property {Boolean} closeOnClickOverlay 是否允许点击遮罩关闭选择器 ( 默认 false )
  60 + * @property {Array} defaultIndex 各列的默认索引
  61 + * @event {Function} close 关闭选择器时触发
  62 + * @event {Function} confirm 点击确定按钮,返回当前选择的值
  63 + * @event {Function} change 当选择值变化时触发
  64 + * @event {Function} cancel 点击取消按钮
  65 + * @example <u-datetime-picker :show="show" :value="value1" mode="datetime" ></u-datetime-picker>
  66 + */
  67 + export default {
  68 + name: 'datetime-picker',
  69 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  70 + data() {
  71 + return {
  72 + columns: [],
  73 + innerDefaultIndex: [],
  74 + innerFormatter: (type, value) => value
  75 + }
  76 + },
  77 + watch: {
  78 + show(newValue, oldValue) {
  79 + if (newValue) {
  80 + this.updateColumnValue(this.innerValue)
  81 + }
  82 + },
  83 + propsChange() {
  84 + this.init()
  85 + }
  86 + },
  87 + computed: {
  88 + // 如果以下这些变量发生了变化,意味着需要重新初始化各列的值
  89 + propsChange() {
  90 + return [this.mode, this.maxDate, this.minDate, this.minHour, this.maxHour, this.minMinute, this.maxMinute, this.filter, ]
  91 + }
  92 + },
  93 + mounted() {
  94 + this.init()
  95 + },
  96 + methods: {
  97 + init() {
  98 + this.innerValue = this.correctValue(this.value)
  99 + this.updateColumnValue(this.innerValue)
  100 + },
  101 + // 在微信小程序中,不支持将函数当做props参数,故只能通过ref形式调用
  102 + setFormatter(e) {
  103 + this.innerFormatter = e
  104 + },
  105 + // 关闭选择器
  106 + close() {
  107 + if (this.closeOnClickOverlay) {
  108 + this.$emit('close')
  109 + }
  110 + },
  111 + // 点击工具栏的取消按钮
  112 + cancel() {
  113 + this.$emit('cancel')
  114 + },
  115 + // 点击工具栏的确定按钮
  116 + confirm() {
  117 + this.$emit('confirm', {
  118 + value: this.innerValue,
  119 + mode: this.mode
  120 + })
  121 + this.$emit('input', this.innerValue)
  122 + },
  123 + //用正则截取输出值,当出现多组数字时,抛出错误
  124 + intercept(e,type){
  125 + let judge = e.match(/\d+/g)
  126 + //判断是否掺杂数字
  127 + if(judge.length>1){
  128 + uni.$u.error("请勿在过滤或格式化函数时添加数字")
  129 + return 0
  130 + }else if(type&&judge[0].length==4){//判断是否是年份
  131 + return judge[0]
  132 + }else if(judge[0].length>2){
  133 + uni.$u.error("请勿在过滤或格式化函数时添加数字")
  134 + return 0
  135 + }else{
  136 + return judge[0]
  137 + }
  138 + },
  139 + // 列发生变化时触发
  140 + change(e) {
  141 + const { indexs, values } = e
  142 + let selectValue = ''
  143 + if(this.mode === 'time') {
  144 + // 根据value各列索引,从各列数组中,取出当前时间的选中值
  145 + selectValue = `${this.intercept(values[0][indexs[0]])}:${this.intercept(values[1][indexs[1]])}`
  146 + } else {
  147 + // 将选择的值转为数值,比如'03'转为数值的3,'2019'转为数值的2019
  148 + const year = parseInt(this.intercept(values[0][indexs[0]],'year'))
  149 + const month = parseInt(this.intercept(values[1][indexs[1]]))
  150 + let date = parseInt(values[2] ? this.intercept(values[2][indexs[2]]) : 1)
  151 + let hour = 0, minute = 0
  152 + // 此月份的最大天数
  153 + const maxDate = dayjs(`${year}-${month}`).daysInMonth()
  154 + // year-month模式下,date不会出现在列中,设置为1,为了符合后边需要减1的需求
  155 + if (this.mode === 'year-month') {
  156 + date = 1
  157 + }
  158 + // 不允许超过maxDate值
  159 + date = Math.min(maxDate, date)
  160 + if (this.mode === 'datetime') {
  161 + hour = parseInt(this.intercept(values[3][indexs[3]]))
  162 + minute = parseInt(this.intercept(values[4][indexs[4]]))
  163 + }
  164 + // 转为时间模式
  165 + selectValue = Number(new Date(year, month - 1, date, hour, minute))
  166 + }
  167 + // 取出准确的合法值,防止超越边界的情况
  168 + selectValue = this.correctValue(selectValue)
  169 + this.innerValue = selectValue
  170 + this.updateColumnValue(selectValue)
  171 + // 发出change时间,value为当前选中的时间戳
  172 + this.$emit('change', {
  173 + value: selectValue,
  174 + // #ifndef MP-WEIXIN
  175 + // 微信小程序不能传递this实例,会因为循环引用而报错
  176 + picker: this.$refs.picker,
  177 + // #endif
  178 + mode: this.mode
  179 + })
  180 + },
  181 + // 更新各列的值,进行补0、格式化等操作
  182 + updateColumnValue(value) {
  183 + this.innerValue = value
  184 + this.updateColumns()
  185 + this.updateIndexs(value)
  186 + },
  187 + // 更新索引
  188 + updateIndexs(value) {
  189 + let values = []
  190 + const formatter = this.formatter || this.innerFormatter
  191 + const padZero = uni.$u.padZero
  192 + if (this.mode === 'time') {
  193 + // 将time模式的时间用:分隔成数组
  194 + const timeArr = value.split(':')
  195 + // 使用formatter格式化方法进行管道处理
  196 + values = [formatter('hour', timeArr[0]), formatter('minute', timeArr[1])]
  197 + } else {
  198 + const date = new Date(value)
  199 + values = [
  200 + formatter('year', `${dayjs(value).year()}`),
  201 + // 月份补0
  202 + formatter('month', padZero(dayjs(value).month() + 1))
  203 + ]
  204 + if (this.mode === 'date') {
  205 + // date模式,需要添加天列
  206 + values.push(formatter('day', padZero(dayjs(value).date())))
  207 + }
  208 + if (this.mode === 'datetime') {
  209 + // 数组的push方法,可以写入多个参数
  210 + values.push(formatter('day', padZero(dayjs(value).date())), formatter('hour', padZero(dayjs(value).hour())), formatter('minute', padZero(dayjs(value).minute())))
  211 + }
  212 + }
  213 +
  214 + // 根据当前各列的所有值,从各列默认值中找到默认值在各列中的索引
  215 + const indexs = this.columns.map((column, index) => {
  216 + // 通过取大值,可以保证不会出现找不到索引的-1情况
  217 + return Math.max(0, column.findIndex(item => item === values[index]))
  218 + })
  219 + this.innerDefaultIndex = indexs
  220 + },
  221 + // 更新各列的值
  222 + updateColumns() {
  223 + const formatter = this.formatter || this.innerFormatter
  224 + // 获取各列的值,并且map后,对各列的具体值进行补0操作
  225 + const results = this.getOriginColumns().map((column) => column.values.map((value) => formatter(column.type, value)))
  226 + this.columns = results
  227 + },
  228 + getOriginColumns() {
  229 + // 生成各列的值
  230 + const results = this.getRanges().map(({ type, range }) => {
  231 + let values = times(range[1] - range[0] + 1, (index) => {
  232 + let value = range[0] + index
  233 + value = type === 'year' ? `${value}` : uni.$u.padZero(value)
  234 + return value
  235 + })
  236 + // 进行过滤
  237 + if (this.filter) {
  238 + values = this.filter(type, values)
  239 + }
  240 + return { type, values }
  241 + })
  242 + return results
  243 + },
  244 + // 通过最大值和最小值生成数组
  245 + generateArray(start, end) {
  246 + return Array.from(new Array(end + 1).keys()).slice(start)
  247 + },
  248 + // 得出合法的时间
  249 + correctValue(value) {
  250 + const isDateMode = this.mode !== 'time'
  251 + if (isDateMode && !uni.$u.test.date(value)) {
  252 + // 如果是日期类型,但是又没有设置合法的当前时间的话,使用最小时间为当前时间
  253 + value = this.minDate
  254 + } else if (!isDateMode && !value) {
  255 + // 如果是时间类型,而又没有默认值的话,就用最小时间
  256 + value = `${uni.$u.padZero(this.minHour)}:${uni.$u.padZero(this.minMinute)}`
  257 + }
  258 + // 时间类型
  259 + if (!isDateMode) {
  260 + if (String(value).indexOf(':') === -1) return uni.$u.error('时间错误,请传递如12:24的格式')
  261 + let [hour, minute] = value.split(':')
  262 + // 对时间补零,同时控制在最小值和最大值之间
  263 + hour = uni.$u.padZero(uni.$u.range(this.minHour, this.maxHour, Number(hour)))
  264 + minute = uni.$u.padZero(uni.$u.range(this.minMinute, this.maxMinute, Number(minute)))
  265 + return `${ hour }:${ minute }`
  266 + } else {
  267 + // 如果是日期格式,控制在最小日期和最大日期之间
  268 + value = dayjs(value).isBefore(dayjs(this.minDate)) ? this.minDate : value
  269 + value = dayjs(value).isAfter(dayjs(this.maxDate)) ? this.maxDate : value
  270 + return value
  271 + }
  272 + },
  273 + // 获取每列的最大和最小值
  274 + getRanges() {
  275 + if (this.mode === 'time') {
  276 + return [
  277 + {
  278 + type: 'hour',
  279 + range: [this.minHour, this.maxHour],
  280 + },
  281 + {
  282 + type: 'minute',
  283 + range: [this.minMinute, this.maxMinute],
  284 + },
  285 + ];
  286 + }
  287 + const { maxYear, maxDate, maxMonth, maxHour, maxMinute, } = this.getBoundary('max', this.innerValue);
  288 + const { minYear, minDate, minMonth, minHour, minMinute, } = this.getBoundary('min', this.innerValue);
  289 + const result = [
  290 + {
  291 + type: 'year',
  292 + range: [minYear, maxYear],
  293 + },
  294 + {
  295 + type: 'month',
  296 + range: [minMonth, maxMonth],
  297 + },
  298 + {
  299 + type: 'day',
  300 + range: [minDate, maxDate],
  301 + },
  302 + {
  303 + type: 'hour',
  304 + range: [minHour, maxHour],
  305 + },
  306 + {
  307 + type: 'minute',
  308 + range: [minMinute, maxMinute],
  309 + },
  310 + ];
  311 + if (this.mode === 'date')
  312 + result.splice(3, 2);
  313 + if (this.mode === 'year-month')
  314 + result.splice(2, 3);
  315 + return result;
  316 + },
  317 + // 根据minDate、maxDate、minHour、maxHour等边界值,判断各列的开始和结束边界值
  318 + getBoundary(type, innerValue) {
  319 + const value = new Date(innerValue)
  320 + const boundary = new Date(this[`${type}Date`])
  321 + const year = dayjs(boundary).year()
  322 + let month = 1
  323 + let date = 1
  324 + let hour = 0
  325 + let minute = 0
  326 + if (type === 'max') {
  327 + month = 12
  328 + // 月份的天数
  329 + date = dayjs(value).daysInMonth()
  330 + hour = 23
  331 + minute = 59
  332 + }
  333 + // 获取边界值,逻辑是:当年达到了边界值(最大或最小年),就检查月允许的最大和最小值,以此类推
  334 + if (dayjs(value).year() === year) {
  335 + month = dayjs(boundary).month() + 1
  336 + if (dayjs(value).month() + 1 === month) {
  337 + date = dayjs(boundary).date()
  338 + if (dayjs(value).date() === date) {
  339 + hour = dayjs(boundary).hour()
  340 + if (dayjs(value).hour() === hour) {
  341 + minute = dayjs(boundary).minute()
  342 + }
  343 + }
  344 + }
  345 + }
  346 + return {
  347 + [`${type}Year`]: year,
  348 + [`${type}Month`]: month,
  349 + [`${type}Date`]: date,
  350 + [`${type}Hour`]: hour,
  351 + [`${type}Minute`]: minute
  352 + }
  353 + },
  354 + },
  355 + }
  356 +</script>
  357 +
  358 +<style lang="scss" scoped>
  359 + @import '../../libs/css/components.scss';
  360 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-divider/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 是否虚线
  4 + dashed: {
  5 + type: Boolean,
  6 + default: uni.$u.props.divider.dashed
  7 + },
  8 + // 是否细线
  9 + hairline: {
  10 + type: Boolean,
  11 + default: uni.$u.props.divider.hairline
  12 + },
  13 + // 是否以点替代文字,优先于text字段起作用
  14 + dot: {
  15 + type: Boolean,
  16 + default: uni.$u.props.divider.dot
  17 + },
  18 + // 内容文本的位置,left-左边,center-中间,right-右边
  19 + textPosition: {
  20 + type: String,
  21 + default: uni.$u.props.divider.textPosition
  22 + },
  23 + // 文本内容
  24 + text: {
  25 + type: [String, Number],
  26 + default: uni.$u.props.divider.text
  27 + },
  28 + // 文本大小
  29 + textSize: {
  30 + type: [String, Number],
  31 + default: uni.$u.props.divider.textSize
  32 + },
  33 + // 文本颜色
  34 + textColor: {
  35 + type: String,
  36 + default: uni.$u.props.divider.textColor
  37 + },
  38 + // 线条颜色
  39 + lineColor: {
  40 + type: String,
  41 + default: uni.$u.props.divider.lineColor
  42 + }
  43 + }
  44 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-divider/u-divider.vue 0 → 100644
  1 +<template>
  2 + <view
  3 + class="u-divider"
  4 + :style="[$u.addStyle(customStyle)]"
  5 + @tap="click"
  6 + >
  7 + <u-line
  8 + :color="lineColor"
  9 + :customStyle="leftLineStyle"
  10 + :hairline="hairline"
  11 + :dashed="dashed"
  12 + ></u-line>
  13 + <text
  14 + v-if="dot"
  15 + class="u-divider__dot"
  16 + >●</text>
  17 + <text
  18 + v-else-if="text"
  19 + class="u-divider__text"
  20 + :style="[textStyle]"
  21 + >{{text}}</text>
  22 + <u-line
  23 + :color="lineColor"
  24 + :customStyle="rightLineStyle"
  25 + :hairline="hairline"
  26 + :dashed="dashed"
  27 + ></u-line>
  28 + </view>
  29 +</template>
  30 +
  31 +<script>
  32 + import props from './props.js';
  33 + /**
  34 + * divider 分割线
  35 + * @description 区隔内容的分割线,一般用于页面底部"没有更多"的提示。
  36 + * @tutorial https://www.uviewui.com/components/divider.html
  37 + * @property {Boolean} dashed 是否虚线 (默认 false )
  38 + * @property {Boolean} hairline 是否细线 (默认 true )
  39 + * @property {Boolean} dot 是否以点替代文字,优先于text字段起作用 (默认 false )
  40 + * @property {String} textPosition 内容文本的位置,left-左边,center-中间,right-右边 (默认 'center' )
  41 + * @property {String | Number} text 文本内容
  42 + * @property {String | Number} textSize 文本大小 (默认 14)
  43 + * @property {String} textColor 文本颜色 (默认 '#909399' )
  44 + * @property {String} lineColor 线条颜色 (默认 '#dcdfe6' )
  45 + * @property {Object} customStyle 定义需要用到的外部样式
  46 + *
  47 + * @event {Function} click divider组件被点击时触发
  48 + * @example <u-divider :color="color">锦瑟无端五十弦</u-divider>
  49 + */
  50 + export default {
  51 + name:'u-divider',
  52 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  53 + computed: {
  54 + textStyle() {
  55 + const style = {}
  56 + style.fontSize = uni.$u.addUnit(this.textSize)
  57 + style.color = this.textColor
  58 + return style
  59 + },
  60 + // 左边线条的的样式
  61 + leftLineStyle() {
  62 + const style = {}
  63 + // 如果是在左边,设置左边的宽度为固定值
  64 + if (this.textPosition === 'left') {
  65 + style.width = '80rpx'
  66 + } else {
  67 + style.flex = 1
  68 + }
  69 + return style
  70 + },
  71 + // 右边线条的的样式
  72 + rightLineStyle() {
  73 + const style = {}
  74 + // 如果是在右边,设置右边的宽度为固定值
  75 + if (this.textPosition === 'right') {
  76 + style.width = '80rpx'
  77 + } else {
  78 + style.flex = 1
  79 + }
  80 + return style
  81 + }
  82 + },
  83 + methods: {
  84 + // divider组件被点击时触发
  85 + click() {
  86 + this.$emit('click');
  87 + }
  88 + }
  89 + }
  90 +</script>
  91 +
  92 +<style lang="scss" scoped>
  93 + @import '../../libs/css/components.scss';
  94 + $u-divider-margin:15px 0 !default;
  95 + $u-divider-text-margin:0 15px !default;
  96 + $u-divider-dot-font-size:12px !default;
  97 + $u-divider-dot-margin:0 12px !default;
  98 + $u-divider-dot-color: #c0c4cc !default;
  99 +
  100 + .u-divider {
  101 + @include flex;
  102 + flex-direction: row;
  103 + align-items: center;
  104 + margin: $u-divider-margin;
  105 +
  106 + &__text {
  107 + margin: $u-divider-text-margin;
  108 + }
  109 +
  110 + &__dot {
  111 + font-size: $u-divider-dot-font-size;
  112 + margin: $u-divider-dot-margin;
  113 + color: $u-divider-dot-color;
  114 + }
  115 + }
  116 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-dropdown-item/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 当前选中项的value值
  4 + value: {
  5 + type: [Number, String, Array],
  6 + default: ''
  7 + },
  8 + // 菜单项标题
  9 + title: {
  10 + type: [String, Number],
  11 + default: ''
  12 + },
  13 + // 选项数据,如果传入了默认slot,此参数无效
  14 + options: {
  15 + type: Array,
  16 + default() {
  17 + return []
  18 + }
  19 + },
  20 + // 是否禁用此菜单项
  21 + disabled: {
  22 + type: Boolean,
  23 + default: false
  24 + },
  25 + // 下拉弹窗的高度
  26 + height: {
  27 + type: [Number, String],
  28 + default: 'auto'
  29 + },
  30 + // 点击遮罩是否可以收起弹窗
  31 + closeOnClickOverlay: {
  32 + type: Boolean,
  33 + default: true
  34 + }
  35 + }
  36 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-dropdown-item/u-dropdown-item.vue 0 → 100644
  1 +<template>
  2 + <view class="u-drawdown-item">
  3 + <u-overlay
  4 + customStyle="top: 126px"
  5 + :show="show"
  6 + :closeOnClickOverlay="closeOnClickOverlay"
  7 + @click="overlayClick"
  8 + ></u-overlay>
  9 + <view
  10 + class="u-drawdown-item__content"
  11 + :style="[style]"
  12 + :animation="animationData"
  13 + ref="animation"
  14 + >
  15 + <slot />
  16 + </view>
  17 + </view>
  18 +</template>
  19 +
  20 +<script>
  21 + // #ifdef APP-NVUE
  22 + const animation = uni.requireNativePlugin('animation')
  23 + const dom = uni.requireNativePlugin('dom')
  24 + // #endif
  25 + import props from './props.js';
  26 + /**
  27 + * Drawdownitem
  28 + * @description
  29 + * @tutorial url
  30 + * @property {String}
  31 + * @event {Function}
  32 + * @example
  33 + */
  34 + export default {
  35 + name: 'u-drawdown-item',
  36 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  37 + data() {
  38 + return {
  39 + show: false,
  40 + top: '126px',
  41 + // uni.createAnimation的导出数据
  42 + animationData: {},
  43 + }
  44 + },
  45 + mounted() {
  46 + this.init()
  47 + },
  48 + watch: {
  49 + // 发生变化时,需要去更新父组件对应的值
  50 + dataChange(newValue, oldValue) {
  51 + this.updateParentData()
  52 + }
  53 + },
  54 + computed: {
  55 + // 监听对应变量的变化
  56 + dataChange() {
  57 + return [this.title, this.disabled]
  58 + },
  59 + style() {
  60 + const style = {
  61 + zIndex: 10071,
  62 + position: 'fixed',
  63 + display: 'flex',
  64 + left: 0,
  65 + right: 0
  66 + }
  67 + style.top = uni.$u.addUnit(this.top)
  68 + return style
  69 + }
  70 + },
  71 + methods: {
  72 + init() {
  73 + this.updateParentData()
  74 + },
  75 + // 更新父组件所需的数据
  76 + updateParentData() {
  77 + // 获取父组件u-dropdown
  78 + this.getParentData('u-dropdown')
  79 + if (!this.parent) uni.$u.error('u-dropdown-item必须配合u-dropdown使用')
  80 + // 查找父组件menuList数组中对应的标题数据
  81 + const menuIndex = this.parent.menuList.findIndex(item => item.title === this.title)
  82 + const menuContent = {
  83 + title: this.title,
  84 + disabled: this.disabled
  85 + }
  86 + if (menuIndex >= 0) {
  87 + // 如果能找到,则直接修改
  88 + this.parent.menuList[menuIndex] = menuContent;
  89 + } else {
  90 + // 如果无法找到,则为第一次添加,直接push即可
  91 + this.parent.menuList.push(menuContent);
  92 + }
  93 + },
  94 + async setContentAnimate(height) {
  95 + this.animating = true
  96 + // #ifdef APP-NVUE
  97 + const ref = this.$refs['animation'].ref
  98 + animation.transition(ref, {
  99 + styles: {
  100 + height: uni.$u.addUnit(height)
  101 + },
  102 + duration: this.duration,
  103 + timingFunction: 'ease-in-out',
  104 + }, () => {
  105 + this.animating = false
  106 + })
  107 + // #endif
  108 +
  109 + // #ifndef APP-NVUE
  110 + const animation = uni.createAnimation({
  111 + timingFunction: 'ease-in-out',
  112 + });
  113 + animation
  114 + .height(height)
  115 + .step({
  116 + duration: this.duration,
  117 + })
  118 + .step()
  119 + // 导出动画数据给面板的animationData值
  120 + this.animationData = animation.export()
  121 + // 标识动画结束
  122 + uni.$u.sleep(this.duration).then(() => {
  123 + this.animating = false
  124 + })
  125 + // #endif
  126 + },
  127 + overlayClick() {
  128 + this.show = false
  129 + this.setContentAnimate(0)
  130 + }
  131 + },
  132 + }
  133 +</script>
  134 +
  135 +<style lang="scss" scoped>
  136 + @import '../../libs/css/components.scss';
  137 +
  138 + .u-drawdown-item {
  139 +
  140 + &__content {
  141 + background-color: #FFFFFF;
  142 + overflow: hidden;
  143 + height: 0;
  144 + }
  145 + }
  146 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-dropdown/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 标题选中时的样式
  4 + activeStyle: {
  5 + type: [String, Object],
  6 + default: () => ({
  7 + color: '#2979ff',
  8 + fontSize: '14px'
  9 + })
  10 + },
  11 + // 标题未选中时的样式
  12 + inactiveStyle: {
  13 + type: [String, Object],
  14 + default: () => ({
  15 + color: '#606266',
  16 + fontSize: '14px'
  17 + })
  18 + },
  19 + // 点击遮罩是否关闭菜单
  20 + closeOnClickMask: {
  21 + type: Boolean,
  22 + default: true
  23 + },
  24 + // 点击当前激活项标题是否关闭菜单
  25 + closeOnClickSelf: {
  26 + type: Boolean,
  27 + default: true
  28 + },
  29 + // 过渡时间
  30 + duration: {
  31 + type: [Number, String],
  32 + default: 300
  33 + },
  34 + // 标题菜单的高度
  35 + height: {
  36 + type: [Number, String],
  37 + default: 40
  38 + },
  39 + // 是否显示下边框
  40 + borderBottom: {
  41 + type: Boolean,
  42 + default: false
  43 + },
  44 + // 标题的字体大小
  45 + titleSize: {
  46 + type: [Number, String],
  47 + default: 14
  48 + },
  49 + // 下拉出来的内容部分的圆角值
  50 + borderRadius: {
  51 + type: [Number, String],
  52 + default: 0
  53 + },
  54 + // 菜单右侧的icon图标
  55 + menuIcon: {
  56 + type: String,
  57 + default: 'arrow-down'
  58 + },
  59 + // 菜单右侧图标的大小
  60 + menuIconSize: {
  61 + type: [Number, String],
  62 + default: 14
  63 + }
  64 + }
  65 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-dropdown/u-dropdown.vue 0 → 100644
  1 +<template>
  2 + <view class="u-drawdown">
  3 + <view
  4 + class="u-dropdown__menu"
  5 + :style="{
  6 + height: $u.addUnit(height)
  7 + }"
  8 + ref="u-dropdown__menu"
  9 + >
  10 + <view
  11 + class="u-dropdown__menu__item"
  12 + v-for="(item, index) in menuList"
  13 + :key="index"
  14 + @tap.stop="clickHandler(item, index)"
  15 + >
  16 + <view class="u-dropdown__menu__item__content">
  17 + <text
  18 + class="u-dropdown__menu__item__content__text"
  19 + :style="[index === current ? activeStyle : inactiveStyle]"
  20 + >{{item.title}}</text>
  21 + <view
  22 + class="u-dropdown__menu__item__content__arrow"
  23 + :class="[index === current && 'u-dropdown__menu__item__content__arrow--rotate']"
  24 + >
  25 + <u-icon
  26 + :name="menuIcon"
  27 + :size="$u.addUnit(menuIconSize)"
  28 + ></u-icon>
  29 + </view>
  30 + </view>
  31 + </view>
  32 + </view>
  33 + <view class="u-dropdown__content">
  34 + <slot />
  35 + </view>
  36 + </view>
  37 +</template>
  38 +
  39 +<script>
  40 + import props from './props.js';
  41 + /**
  42 + * Dropdown
  43 + * @description
  44 + * @tutorial url
  45 + * @property {String}
  46 + * @event {Function}
  47 + * @example
  48 + */
  49 + export default {
  50 + name: 'u-dropdown',
  51 + mixins: [uni.$u.mixin, props],
  52 + data() {
  53 + return {
  54 + // 菜单数组
  55 + menuList: [],
  56 + current: 0
  57 + }
  58 + },
  59 + computed: {
  60 +
  61 + },
  62 + created() {
  63 + // 引用所有子组件(u-dropdown-item)的this,不能在data中声明变量,否则在微信小程序会造成循环引用而报错
  64 + this.children = [];
  65 + },
  66 + methods: {
  67 + clickHandler(item, index) {
  68 + this.children.map(child => {
  69 + if(child.title === item.title) {
  70 + // this.queryRect('u-dropdown__menu').then(size => {
  71 + child.$emit('click')
  72 + child.setContentAnimate(child.show ? 0 : 300)
  73 + child.show = !child.show
  74 + // })
  75 + } else {
  76 + child.show = false
  77 + child.setContentAnimate(0)
  78 + }
  79 + })
  80 + },
  81 + // 获取标签的尺寸位置
  82 + queryRect(el) {
  83 + // #ifndef APP-NVUE
  84 + // $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://www.uviewui.com/js/getRect.html
  85 + // 组件内部一般用this.$uGetRect,对外的为this.$u.getRect,二者功能一致,名称不同
  86 + return new Promise(resolve => {
  87 + this.$uGetRect(`.${el}`).then(size => {
  88 + resolve(size)
  89 + })
  90 + })
  91 + // #endif
  92 +
  93 + // #ifdef APP-NVUE
  94 + // nvue下,使用dom模块查询元素高度
  95 + // 返回一个promise,让调用此方法的主体能使用then回调
  96 + return new Promise(resolve => {
  97 + dom.getComponentRect(this.$refs[el], res => {
  98 + resolve(res.size)
  99 + })
  100 + })
  101 + // #endif
  102 + },
  103 + },
  104 + }
  105 +</script>
  106 +
  107 +<style lang="scss">
  108 + @import '../../libs/css/components.scss';
  109 +
  110 + .u-dropdown {
  111 +
  112 + &__menu {
  113 + @include flex;
  114 +
  115 + &__item {
  116 + flex: 1;
  117 + @include flex;
  118 + justify-content: center;
  119 +
  120 + &__content {
  121 + @include flex;
  122 + align-items: center;
  123 + }
  124 + }
  125 + }
  126 + }
  127 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-empty/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 内置图标名称,或图片路径,建议绝对路径
  4 + icon: {
  5 + type: String,
  6 + default: uni.$u.props.empty.icon
  7 + },
  8 + // 提示文字
  9 + text: {
  10 + type: String,
  11 + default: uni.$u.props.empty.text
  12 + },
  13 + // 文字颜色
  14 + textColor: {
  15 + type: String,
  16 + default: uni.$u.props.empty.textColor
  17 + },
  18 + // 文字大小
  19 + textSize: {
  20 + type: [String, Number],
  21 + default: uni.$u.props.empty.textSize
  22 + },
  23 + // 图标的颜色
  24 + iconColor: {
  25 + type: String,
  26 + default: uni.$u.props.empty.iconColor
  27 + },
  28 + // 图标的大小
  29 + iconSize: {
  30 + type: [String, Number],
  31 + default: uni.$u.props.empty.iconSize
  32 + },
  33 + // 选择预置的图标类型
  34 + mode: {
  35 + type: String,
  36 + default: uni.$u.props.empty.mode
  37 + },
  38 + // 图标宽度,单位px
  39 + width: {
  40 + type: [String, Number],
  41 + default: uni.$u.props.empty.width
  42 + },
  43 + // 图标高度,单位px
  44 + height: {
  45 + type: [String, Number],
  46 + default: uni.$u.props.empty.height
  47 + },
  48 + // 是否显示组件
  49 + show: {
  50 + type: Boolean,
  51 + default: uni.$u.props.empty.show
  52 + },
  53 + // 组件距离上一个元素之间的距离,默认px单位
  54 + marginTop: {
  55 + type: [String, Number],
  56 + default: uni.$u.props.empty.marginTop
  57 + }
  58 + }
  59 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-empty/u-empty.vue 0 → 100644
  1 +<template>
  2 + <view
  3 + class="u-empty"
  4 + :style="[emptyStyle]"
  5 + v-if="show"
  6 + >
  7 + <u-icon
  8 + v-if="!isSrc"
  9 + :name="mode === 'message' ? 'chat' : `empty-${mode}`"
  10 + :size="iconSize"
  11 + :color="iconColor"
  12 + margin-top="14"
  13 + ></u-icon>
  14 + <image
  15 + v-else
  16 + :style="{
  17 + width: $u.addUnit(width),
  18 + height: $u.addUnit(height),
  19 + }"
  20 + :src="icon"
  21 + mode="widthFix"
  22 + ></image>
  23 + <text
  24 + class="u-empty__text"
  25 + :style="[textStyle]"
  26 + >{{text ? text : icons[mode]}}</text>
  27 + <view class="u-empty__wrap" v-if="$slots.default || $slots.$default">
  28 + <slot />
  29 + </view>
  30 + </view>
  31 +</template>
  32 +
  33 +<script>
  34 + import props from './props.js';
  35 +
  36 + /**
  37 + * empty 内容为空
  38 + * @description 该组件用于需要加载内容,但是加载的第一页数据就为空,提示一个"没有内容"的场景, 我们精心挑选了十几个场景的图标,方便您使用。
  39 + * @tutorial https://www.uviewui.com/components/empty.html
  40 + * @property {String} icon 内置图标名称,或图片路径,建议绝对路径
  41 + * @property {String} text 提示文字
  42 + * @property {String} textColor 文字颜色 (默认 '#c0c4cc' )
  43 + * @property {String | Number} textSize 文字大小 (默认 14 )
  44 + * @property {String} iconColor 图标的颜色 (默认 '#c0c4cc' )
  45 + * @property {String | Number} iconSize 图标的大小 (默认 90 )
  46 + * @property {String} mode 选择预置的图标类型 (默认 'data' )
  47 + * @property {String | Number} width 图标宽度,单位px (默认 160 )
  48 + * @property {String | Number} height 图标高度,单位px (默认 160 )
  49 + * @property {Boolean} show 是否显示组件 (默认 true )
  50 + * @property {String | Number} marginTop 组件距离上一个元素之间的距离,默认px单位 (默认 0 )
  51 + * @property {Object} customStyle 定义需要用到的外部样式
  52 + *
  53 + * @event {Function} click 点击组件时触发
  54 + * @event {Function} close 点击关闭按钮时触发
  55 + * @example <u-empty text="所谓伊人,在水一方" mode="list"></u-empty>
  56 + */
  57 + export default {
  58 + name: "u-empty",
  59 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  60 + data() {
  61 + return {
  62 + icons: {
  63 + car: '购物车为空',
  64 + page: '页面不存在',
  65 + search: '没有搜索结果',
  66 + address: '没有收货地址',
  67 + wifi: '没有WiFi',
  68 + order: '订单为空',
  69 + coupon: '没有优惠券',
  70 + favor: '暂无收藏',
  71 + permission: '无权限',
  72 + history: '无历史记录',
  73 + news: '无新闻列表',
  74 + message: '消息列表为空',
  75 + list: '列表为空',
  76 + data: '数据为空',
  77 + comment: '暂无评论',
  78 + }
  79 + }
  80 + },
  81 + computed: {
  82 + // 组件样式
  83 + emptyStyle() {
  84 + const style = {}
  85 + style.marginTop = uni.$u.addUnit(this.marginTop)
  86 + // 合并customStyle样式,此参数通过mixin中的props传递
  87 + return uni.$u.deepMerge(uni.$u.addStyle(this.customStyle), style)
  88 + },
  89 + // 文本样式
  90 + textStyle() {
  91 + const style = {}
  92 + style.color = this.textColor
  93 + style.fontSize = uni.$u.addUnit(this.textSize)
  94 + return style
  95 + },
  96 + // 判断icon是否图片路径
  97 + isSrc() {
  98 + return this.icon.indexOf('/') >= 0
  99 + }
  100 + }
  101 + }
  102 +</script>
  103 +
  104 +<style lang="scss" scoped>
  105 + @import '../../libs/css/components.scss';
  106 + $u-empty-text-margin-top:20rpx !default;
  107 + $u-empty-slot-margin-top:20rpx !default;
  108 +
  109 + .u-empty {
  110 + @include flex;
  111 + flex-direction: column;
  112 + justify-content: center;
  113 + align-items: center;
  114 +
  115 + &__text {
  116 + @include flex;
  117 + justify-content: center;
  118 + align-items: center;
  119 + margin-top: $u-empty-text-margin-top;
  120 + }
  121 + }
  122 + .u-slot-wrap {
  123 + @include flex;
  124 + justify-content: center;
  125 + align-items: center;
  126 + margin-top:$u-empty-slot-margin-top;
  127 + }
  128 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-form-item/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // input的label提示语
  4 + label: {
  5 + type: String,
  6 + default: uni.$u.props.formItem.label
  7 + },
  8 + // 绑定的值
  9 + prop: {
  10 + type: String,
  11 + default: uni.$u.props.formItem.prop
  12 + },
  13 + // 是否显示表单域的下划线边框
  14 + borderBottom: {
  15 + type: [String, Boolean],
  16 + default: uni.$u.props.formItem.borderBottom
  17 + },
  18 + // label的宽度,单位px
  19 + labelWidth: {
  20 + type: [String, Number],
  21 + default: uni.$u.props.formItem.labelWidth
  22 + },
  23 + // 右侧图标
  24 + rightIcon: {
  25 + type: String,
  26 + default: uni.$u.props.formItem.rightIcon
  27 + },
  28 + // 左侧图标
  29 + leftIcon: {
  30 + type: String,
  31 + default: uni.$u.props.formItem.leftIcon
  32 + },
  33 + // 是否显示左边的必填星号,只作显示用,具体校验必填的逻辑,请在rules中配置
  34 + required: {
  35 + type: Boolean,
  36 + default: uni.$u.props.formItem.required
  37 + },
  38 + leftIconStyle: {
  39 + type: [String, Object],
  40 + default: uni.$u.props.formItem.leftIconStyle,
  41 + }
  42 + }
  43 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-form-item/u-form-item.vue 0 → 100644
  1 +<template>
  2 + <view class="u-form-item">
  3 + <view
  4 + class="u-form-item__body"
  5 + @tap="clickHandler"
  6 + :style="[$u.addStyle(customStyle), {
  7 + flexDirection: parentData.labelPosition === 'left' ? 'row' : 'column'
  8 + }]"
  9 + >
  10 + <!-- 微信小程序中,将一个参数设置空字符串,结果会变成字符串"true" -->
  11 + <slot name="label">
  12 + <!-- {{required}} -->
  13 + <view
  14 + class="u-form-item__body__left"
  15 + v-if="required || leftIcon || label"
  16 + :style="{
  17 + width: $u.addUnit(labelWidth || parentData.labelWidth),
  18 + marginBottom: parentData.labelPosition === 'left' ? 0 : '5px',
  19 + }"
  20 + >
  21 + <!-- 为了块对齐 -->
  22 + <view class="u-form-item__body__left__content">
  23 + <!-- nvue不支持伪元素before -->
  24 + <text
  25 + v-if="required"
  26 + class="u-form-item__body__left__content__required"
  27 + >*</text>
  28 + <view
  29 + class="u-form-item__body__left__content__icon"
  30 + v-if="leftIcon"
  31 + >
  32 + <u-icon
  33 + :name="leftIcon"
  34 + :custom-style="leftIconStyle"
  35 + ></u-icon>
  36 + </view>
  37 + <text
  38 + class="u-form-item__body__left__content__label"
  39 + :style="[parentData.labelStyle, {
  40 + justifyContent: parentData.labelAlign === 'left' ? 'flex-start' : parentData.labelAlign === 'center' ? 'center' : 'flex-end'
  41 + }]"
  42 + >{{ label }}</text>
  43 + </view>
  44 + </view>
  45 + </slot>
  46 + <view class="u-form-item__body__right">
  47 + <view class="u-form-item__body__right__content">
  48 + <view class="u-form-item__body__right__content__slot">
  49 + <slot />
  50 + </view>
  51 + <view
  52 + class="item__body__right__content__icon"
  53 + v-if="$slots.right"
  54 + >
  55 + <slot name="right" />
  56 + </view>
  57 + </view>
  58 + </view>
  59 + </view>
  60 + <slot name="error">
  61 + <text
  62 + v-if="!!message && parentData.errorType === 'message'"
  63 + class="u-form-item__body__right__message"
  64 + :style="{
  65 + marginLeft: $u.addUnit(parentData.labelPosition === 'top' ? 0 : (labelWidth || parentData.labelWidth))
  66 + }"
  67 + >{{ message }}</text>
  68 + </slot>
  69 + <u-line
  70 + v-if="borderBottom"
  71 + :color="message && parentData.errorType === 'border-bottom' ? $u.color.error : propsLine.color"
  72 + :customStyle="`margin-top: ${message && parentData.errorType === 'message' ? '5px' : 0}`"
  73 + ></u-line>
  74 + </view>
  75 +</template>
  76 +
  77 +<script>
  78 + import props from './props.js';
  79 + /**
  80 + * Form 表单
  81 + * @description 此组件一般用于表单场景,可以配置Input输入框,Select弹出框,进行表单验证等。
  82 + * @tutorial https://www.uviewui.com/components/form.html
  83 + * @property {String} label input的label提示语
  84 + * @property {String} prop 绑定的值
  85 + * @property {String | Boolean} borderBottom 是否显示表单域的下划线边框
  86 + * @property {String | Number} labelWidth label的宽度,单位px
  87 + * @property {String} rightIcon 右侧图标
  88 + * @property {String} leftIcon 左侧图标
  89 + * @property {String | Object} leftIconStyle 左侧图标的样式
  90 + * @property {Boolean} required 是否显示左边的必填星号,只作显示用,具体校验必填的逻辑,请在rules中配置 (默认 false )
  91 + *
  92 + * @example <u-form-item label="姓名" prop="userInfo.name" borderBottom ref="item1"></u-form-item>
  93 + */
  94 + export default {
  95 + name: 'u-form-item',
  96 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  97 + data() {
  98 + return {
  99 + // 错误提示语
  100 + message: '',
  101 + parentData: {
  102 + // 提示文本的位置
  103 + labelPosition: 'left',
  104 + // 提示文本对齐方式
  105 + labelAlign: 'left',
  106 + // 提示文本的样式
  107 + labelStyle: {},
  108 + // 提示文本的宽度
  109 + labelWidth: 45,
  110 + // 错误提示方式
  111 + errorType: 'message'
  112 + }
  113 + }
  114 + },
  115 + // 组件创建完成时,将当前实例保存到u-form中
  116 + computed: {
  117 + propsLine() {
  118 + return uni.$u.props.line
  119 + }
  120 + },
  121 + mounted() {
  122 + this.init()
  123 + },
  124 + methods: {
  125 + init() {
  126 + // 父组件的实例
  127 + this.updateParentData()
  128 + if (!this.parent) {
  129 + uni.$u.error('u-form-item需要结合u-form组件使用')
  130 + }
  131 + },
  132 + // 获取父组件的参数
  133 + updateParentData() {
  134 + // 此方法写在mixin中
  135 + this.getParentData('u-form');
  136 + },
  137 + // 移除u-form-item的校验结果
  138 + clearValidate() {
  139 + this.message = null
  140 + },
  141 + // 清空当前的组件的校验结果,并重置为初始值
  142 + resetField() {
  143 + // 找到原始值
  144 + const value = uni.$u.getProperty(this.parent.originalModel, this.prop)
  145 + // 将u-form的model的prop属性链还原原始值
  146 + uni.$u.setProperty(this.parent.model, this.prop, value)
  147 + // 移除校验结果
  148 + this.message = null
  149 + },
  150 + // 点击组件
  151 + clickHandler() {
  152 + this.$emit('click')
  153 + }
  154 + },
  155 + }
  156 +</script>
  157 +
  158 +<style lang="scss" scoped>
  159 + @import "../../libs/css/components.scss";
  160 +
  161 + .u-form-item {
  162 + @include flex(column);
  163 + font-size: 14px;
  164 + color: $u-main-color;
  165 +
  166 + &__body {
  167 + @include flex;
  168 + padding: 10px 0;
  169 +
  170 + &__left {
  171 + @include flex;
  172 + align-items: center;
  173 +
  174 + &__content {
  175 + position: relative;
  176 + @include flex;
  177 + align-items: center;
  178 + padding-right: 10rpx;
  179 + flex: 1;
  180 +
  181 + &__icon {
  182 + margin-right: 8rpx;
  183 + }
  184 +
  185 + &__required {
  186 + position: absolute;
  187 + left: -9px;
  188 + color: $u-error;
  189 + line-height: 20px;
  190 + font-size: 20px;
  191 + top: 3px;
  192 + }
  193 +
  194 + &__label {
  195 + @include flex;
  196 + align-items: center;
  197 + flex: 1;
  198 + color: $u-main-color;
  199 + font-size: 15px;
  200 + }
  201 + }
  202 + }
  203 +
  204 + &__right {
  205 + flex: 1;
  206 +
  207 + &__content {
  208 + @include flex;
  209 + align-items: center;
  210 + flex: 1;
  211 +
  212 + &__slot {
  213 + flex: 1;
  214 + /* #ifndef MP */
  215 + @include flex;
  216 + align-items: center;
  217 + /* #endif */
  218 + }
  219 +
  220 + &__icon {
  221 + margin-left: 10rpx;
  222 + color: $u-light-color;
  223 + font-size: 30rpx;
  224 + }
  225 + }
  226 +
  227 + &__message {
  228 + font-size: 12px;
  229 + line-height: 12px;
  230 + color: $u-error;
  231 + }
  232 + }
  233 + }
  234 + }
  235 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-form/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 当前form的需要验证字段的集合
  4 + model: {
  5 + type: Object,
  6 + default: uni.$u.props.form.model
  7 + },
  8 + // 验证规则
  9 + rules: {
  10 + type: [Object, Function, Array],
  11 + default: uni.$u.props.form.rules
  12 + },
  13 + // 有错误时的提示方式,message-提示信息,toast-进行toast提示
  14 + // border-bottom-下边框呈现红色,none-无提示
  15 + errorType: {
  16 + type: String,
  17 + default: uni.$u.props.form.errorType
  18 + },
  19 + // 是否显示表单域的下划线边框
  20 + borderBottom: {
  21 + type: Boolean,
  22 + default: uni.$u.props.form.borderBottom
  23 + },
  24 + // label的位置,left-左边,top-上边
  25 + labelPosition: {
  26 + type: String,
  27 + default: uni.$u.props.form.labelPosition
  28 + },
  29 + // label的宽度,单位px
  30 + labelWidth: {
  31 + type: [String, Number],
  32 + default: uni.$u.props.form.labelWidth
  33 + },
  34 + // lable字体的对齐方式
  35 + labelAlign: {
  36 + type: String,
  37 + default: uni.$u.props.form.labelAlign
  38 + },
  39 + // lable的样式,对象形式
  40 + labelStyle: {
  41 + type: Object,
  42 + default: uni.$u.props.form.labelStyle
  43 + }
  44 + }
  45 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-form/u-form.vue 0 → 100644
  1 +<template>
  2 + <view class="u-form">
  3 + <slot />
  4 + </view>
  5 +</template>
  6 +
  7 +<script>
  8 + import props from "./props.js";
  9 + import Schema from "../../libs/util/async-validator";
  10 + // 去除警告信息
  11 + Schema.warning = function() {};
  12 + /**
  13 + * Form 表单
  14 + * @description 此组件一般用于表单场景,可以配置Input输入框,Select弹出框,进行表单验证等。
  15 + * @tutorial https://www.uviewui.com/components/form.html
  16 + * @property {Object} model 当前form的需要验证字段的集合
  17 + * @property {Object | Function | Array} rules 验证规则
  18 + * @property {String} errorType 错误的提示方式,见上方说明 ( 默认 message )
  19 + * @property {Boolean} borderBottom 是否显示表单域的下划线边框 ( 默认 true )
  20 + * @property {String} labelPosition 表单域提示文字的位置,left-左侧,top-上方 ( 默认 'left' )
  21 + * @property {String | Number} labelWidth 提示文字的宽度,单位px ( 默认 45 )
  22 + * @property {String} labelAlign lable字体的对齐方式 ( 默认 ‘left' )
  23 + * @property {Object} labelStyle lable的样式,对象形式
  24 + * @example <u--formlabelPosition="left" :model="model1" :rules="rules" ref="form1"></u--form>
  25 + */
  26 + export default {
  27 + name: "u-form",
  28 + mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  29 + provide() {
  30 + return {
  31 + uForm: this,
  32 + };
  33 + },
  34 + data() {
  35 + return {
  36 + formRules: {},
  37 + // 规则校验器
  38 + validator: {},
  39 + // 原始的model快照,用于resetFields方法重置表单时使用
  40 + originalModel: null,
  41 + };
  42 + },
  43 + watch: {
  44 + // 监听规则的变化
  45 + rules: {
  46 + immediate: true,
  47 + handler(n) {
  48 + this.setRules(n);
  49 + },
  50 + },
  51 + // 监听属性的变化,通知子组件u-form-item重新获取信息
  52 + propsChange(n) {
  53 + if (this.children?.length) {
  54 + this.children.map((child) => {
  55 + // 判断子组件(u-form-item)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
  56 + typeof child.updateParentData == "function" &&
  57 + child.updateParentData();
  58 + });
  59 + }
  60 + },
  61 + // 监听model的初始值作为重置表单的快照
  62 + model: {
  63 + immediate: true,
  64 + handler(n) {
  65 + if (!this.originalModel) {
  66 + this.originalModel = uni.$u.deepClone(n);
  67 + }
  68 + },
  69 + },
  70 + },
  71 + computed: {
  72 + propsChange() {
  73 + return [
  74 + this.errorType,
  75 + this.borderBottom,
  76 + this.labelPosition,
  77 + this.labelWidth,
  78 + this.labelAlign,
  79 + this.labelStyle,
  80 + ];
  81 + },
  82 + },
  83 + created() {
  84 + // 存储当前form下的所有u-form-item的实例
  85 + // 不能定义在data中,否则微信小程序会造成循环引用而报错
  86 + this.children = [];
  87 + },
  88 + methods: {
  89 + // 手动设置校验的规则,如果规则中有函数的话,微信小程序中会过滤掉,所以只能手动调用设置规则
  90 + setRules(rules) {
  91 + // 判断是否有规则
  92 + if (Object.keys(rules).length === 0) return;
  93 + if (process.env.NODE_ENV === 'development' && Object.keys(this.model).length === 0) {
  94 + uni.$u.error('设置rules,model必须设置!如果已经设置,请刷新页面。');
  95 + return;
  96 + };
  97 + this.formRules = rules;
  98 + // 重新将规则赋予Validator
  99 + this.validator = new Schema(rules);
  100 + },
  101 + // 清空所有u-form-item组件的内容,本质上是调用了u-form-item组件中的resetField()方法
  102 + resetFields() {
  103 + this.resetModel();
  104 + },
  105 + // 重置model为初始值的快照
  106 + resetModel(obj) {
  107 + // 历遍所有u-form-item,根据其prop属性,还原model的原始快照
  108 + this.children.map((child) => {
  109 + const prop = child?.prop;
  110 + const value = uni.$u.getProperty(this.originalModel, prop);
  111 + uni.$u.setProperty(this.model, prop, value);
  112 + });
  113 + },
  114 + // 清空校验结果
  115 + clearValidate(props) {
  116 + props = [].concat(props);
  117 + this.children.map((child) => {
  118 + // 如果u-form-item的prop在props数组中,则清除对应的校验结果信息
  119 + if (props[0] === undefined || props.includes(child.prop)) {
  120 + child.message = null;
  121 + }
  122 + });
  123 + },
  124 + // 对部分表单字段进行校验
  125 + async validateField(value, callback, event = null) {
  126 + // $nextTick是必须的,否则model的变更,可能会延后于此方法的执行
  127 + this.$nextTick(() => {
  128 + // 校验错误信息,返回给回调方法,用于存放所有form-item的错误信息
  129 + const errorsRes = [];
  130 + // 如果为字符串,转为数组
  131 + value = [].concat(value);
  132 + // 历遍children所有子form-item
  133 + this.children.map((child) => {
  134 + // 用于存放form-item的错误信息
  135 + const childErrors = [];
  136 + if (value.includes(child.prop)) {
  137 + // 获取对应的属性,通过类似'a.b.c'的形式
  138 + const propertyVal = uni.$u.getProperty(
  139 + this.model,
  140 + child.prop
  141 + );
  142 + // 属性链数组
  143 + const propertyChain = child.prop.split(".");
  144 + const propertyName =
  145 + propertyChain[propertyChain.length - 1];
  146 +
  147 + const rule = this.formRules[child.prop];
  148 + // 如果不存在对应的规则,直接返回,否则校验器会报错
  149 + if (!rule) return;
  150 + // rule规则可为数组形式,也可为对象形式,此处拼接成为数组
  151 + const rules = [].concat(rule);
  152 +
  153 + // 对rules数组进行校验
  154 + for (let i = 0; i < rules.length; i++) {
  155 + const ruleItem = rules[i];
  156 + // 将u-form-item的触发器转为数组形式
  157 + const trigger = [].concat(ruleItem?.trigger);
  158 + // 如果是有传入触发事件,但是此form-item却没有配置此触发器的话,不执行校验操作
  159 + if (event && !trigger.includes(event)) continue;
  160 + // 实例化校验对象,传入构造规则
  161 + const validator = new Schema({
  162 + [propertyName]: ruleItem,
  163 + });
  164 + validator.validate({
  165 + [propertyName]: propertyVal,
  166 + },
  167 + (errors, fields) => {
  168 + if (uni.$u.test.array(errors)) {
  169 + errorsRes.push(...errors);
  170 + childErrors.push(...errors);
  171 + }
  172 + child.message =
  173 + childErrors[0]?.message ?? null;
  174 + }
  175 + );
  176 + }
  177 + }
  178 + });
  179 + // 执行回调函数
  180 + typeof callback === "function" && callback(errorsRes);
  181 + });
  182 + },
  183 + // 校验全部数据
  184 + validate(callback) {
  185 + // 开发环境才提示,生产环境不会提示
  186 + if (process.env.NODE_ENV === 'development' && Object.keys(this.formRules).length === 0) {
  187 + uni.$u.error('未设置rules,请看文档说明!如果已经设置,请刷新页面。');
  188 + return;
  189 + }
  190 + return new Promise((resolve, reject) => {
  191 + // $nextTick是必须的,否则model的变更,可能会延后于validate方法
  192 + this.$nextTick(() => {
  193 + // 获取所有form-item的prop,交给validateField方法进行校验
  194 + const formItemProps = this.children.map(
  195 + (item) => item.prop
  196 + );
  197 + this.validateField(formItemProps, (errors) => {
  198 + if(errors.length) {
  199 + // 如果错误提示方式为toast,则进行提示
  200 + this.errorType === 'toast' && uni.$u.toast(errors[0].message)
  201 + reject(errors)
  202 + } else {
  203 + resolve(true)
  204 + }
  205 + });
  206 + });
  207 + });
  208 + },
  209 + },
  210 + };
  211 +</script>
  212 +
  213 +<style lang="scss" scoped>
  214 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-gap/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 背景颜色(默认transparent)
  4 + bgColor: {
  5 + type: String,
  6 + default: uni.$u.props.gap.bgColor
  7 + },
  8 + // 分割槽高度,单位px(默认30)
  9 + height: {
  10 + type: [String, Number],
  11 + default: uni.$u.props.gap.height
  12 + },
  13 + // 与上一个组件的距离
  14 + marginTop: {
  15 + type: [String, Number],
  16 + default: uni.$u.props.gap.marginTop
  17 + },
  18 + // 与下一个组件的距离
  19 + marginBottom: {
  20 + type: [String, Number],
  21 + default: uni.$u.props.gap.marginBottom
  22 + }
  23 + }
  24 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-gap/u-gap.vue 0 → 100644
  1 +<template>
  2 + <view class="u-gap" :style="[gapStyle]"></view>
  3 +</template>
  4 +
  5 +<script>
  6 + import props from './props.js';
  7 + /**
  8 + * gap 间隔槽
  9 + * @description 该组件一般用于内容块之间的用一个灰色块隔开的场景,方便用户风格统一,减少工作量
  10 + * @tutorial https://www.uviewui.com/components/gap.html
  11 + * @property {String} bgColor 背景颜色 (默认 'transparent' )
  12 + * @property {String | Number} height 分割槽高度,单位px (默认 20 )
  13 + * @property {String | Number} marginTop 与前一个组件的距离,单位px( 默认 0 )
  14 + * @property {String | Number} marginBottom 与后一个组件的距离,单位px (默认 0 )
  15 + * @property {Object} customStyle 定义需要用到的外部样式
  16 + *
  17 + * @example <u-gap height="80" bg-color="#bbb"></u-gap>
  18 + */
  19 + export default {
  20 + name: "u-gap",
  21 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  22 + computed: {
  23 + gapStyle() {
  24 + const style = {
  25 + backgroundColor: this.bgColor,
  26 + height: uni.$u.addUnit(this.height),
  27 + marginTop: uni.$u.addUnit(this.marginTop),
  28 + marginBottom: uni.$u.addUnit(this.marginBottom),
  29 + }
  30 + return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
  31 + }
  32 + }
  33 + };
  34 +</script>
  35 +
  36 +<style lang="scss" scoped>
  37 + @import "../../libs/css/components.scss";
  38 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-grid-item/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 宫格的name
  4 + name: {
  5 + type: [String, Number, null],
  6 + default: uni.$u.props.gridItem.name
  7 + },
  8 + // 背景颜色
  9 + bgColor: {
  10 + type: String,
  11 + default: uni.$u.props.gridItem.bgColor
  12 + }
  13 + }
  14 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-grid-item/u-grid-item.vue 0 → 100644
  1 +<template>
  2 + <!-- #ifndef APP-NVUE -->
  3 + <view
  4 + class="u-grid-item"
  5 + hover-class="u-grid-item--hover-class"
  6 + :hover-stay-time="200"
  7 + @tap="clickHandler"
  8 + :class="classes"
  9 + :style="[itemStyle]"
  10 + >
  11 + <slot />
  12 + </view>
  13 + <!-- #endif -->
  14 + <!-- #ifdef APP-NVUE -->
  15 + <view
  16 + class="u-grid-item"
  17 + :hover-stay-time="200"
  18 + @tap="clickHandler"
  19 + :class="classes"
  20 + :style="[itemStyle]"
  21 + >
  22 + <slot />
  23 + </view>
  24 + <!-- #endif -->
  25 +</template>
  26 +
  27 +<script>
  28 + import props from './props.js';
  29 + /**
  30 + * gridItem 提示
  31 + * @description 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。搭配u-grid使用
  32 + * @tutorial https://www.uviewui.com/components/grid.html
  33 + * @property {String | Number} name 宫格的name ( 默认 null )
  34 + * @property {String} bgColor 宫格的背景颜色 (默认 'transparent' )
  35 + * @property {Object} customStyle 自定义样式,对象形式
  36 + * @event {Function} click 点击宫格触发
  37 + * @example <u-grid-item></u-grid-item>
  38 + */
  39 + export default {
  40 + name: "u-grid-item",
  41 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  42 + data() {
  43 + return {
  44 + parentData: {
  45 + col: 3, // 父组件划分的宫格数
  46 + border: true, // 是否显示边框,根据父组件决定
  47 + },
  48 + // #ifdef APP-NVUE
  49 + width: 0, // nvue下才这么计算,vue下放到computed中,否则会因为延时造成闪烁
  50 + // #endif
  51 + classes: [], // 类名集合,用于判断是否显示右边和下边框
  52 + };
  53 + },
  54 + mounted() {
  55 + this.init()
  56 + },
  57 + computed: {
  58 + // #ifndef APP-NVUE
  59 + // vue下放到computed中,否则会因为延时造成闪烁
  60 + width() {
  61 + return 100 / Number(this.parentData.col) + '%'
  62 + },
  63 + // #endif
  64 + itemStyle() {
  65 + const style = {
  66 + background: this.bgColor,
  67 + width: this.width
  68 + }
  69 + return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
  70 + }
  71 + },
  72 + methods: {
  73 + init() {
  74 + // 用于在父组件u-grid的children中被添加入子组件时,
  75 + // 重新计算item的边框
  76 + uni.$on('$uGridItem', () => {
  77 + this.gridItemClasses()
  78 + })
  79 + // 父组件的实例
  80 + this.updateParentData()
  81 + // #ifdef APP-NVUE
  82 + // 获取元素该有的长度,nvue下要延时才准确
  83 + this.$nextTick(function(){
  84 + this.getItemWidth()
  85 + })
  86 + // #endif
  87 + // 发出事件,通知所有的grid-item都重新计算自己的边框
  88 + uni.$emit('$uGridItem')
  89 + this.gridItemClasses()
  90 + },
  91 + // 获取父组件的参数
  92 + updateParentData() {
  93 + // 此方法写在mixin中
  94 + this.getParentData('u-grid');
  95 + },
  96 + clickHandler() {
  97 + let name = this.name
  98 + // 如果没有设置name属性,历遍父组件的children数组,判断当前的元素是否和本实例this相等,找出当前组件的索引
  99 + const children = this.parent?.children
  100 + if(children && this.name === null) {
  101 + name = children.findIndex(child => child === this)
  102 + }
  103 + // 调用父组件方法,发出事件
  104 + this.parent && this.parent.childClick(name)
  105 + this.$emit('click', name)
  106 + },
  107 + async getItemWidth() {
  108 + // 如果是nvue,不能使用百分比,只能使用固定宽度
  109 + let width = 0
  110 + if(this.parent) {
  111 + // 获取父组件宽度后,除以栅格数,得出每个item的宽度
  112 + const parentWidth = await this.getParentWidth()
  113 + width = parentWidth / Number(this.parentData.col) + 'px'
  114 + }
  115 + this.width = width
  116 + },
  117 + // 获取父元素的尺寸
  118 + getParentWidth() {
  119 + // #ifdef APP-NVUE
  120 + // 返回一个promise,让调用者可以用await同步获取
  121 + const dom = uni.requireNativePlugin('dom')
  122 + return new Promise(resolve => {
  123 + // 调用父组件的ref
  124 + dom.getComponentRect(this.parent.$refs['u-grid'], res => {
  125 + resolve(res.size.width)
  126 + })
  127 + })
  128 + // #endif
  129 + },
  130 + gridItemClasses() {
  131 + if(this.parentData.border) {
  132 + const classes = []
  133 + this.parent.children.map((child, index) =>{
  134 + if(this === child) {
  135 + const len = this.parent.children.length
  136 + // 贴近右边屏幕边沿的child,并且最后一个(比如只有横向2个的时候),无需右边框
  137 + if((index + 1) % this.parentData.col !== 0 && index + 1 !== len) {
  138 + classes.push('u-border-right')
  139 + }
  140 + // 总的宫格数量对列数取余的值
  141 + // 如果取余后,值为0,则意味着要将最后一排的宫格,都不需要下边框
  142 + const lessNum = len % this.parentData.col === 0 ? this.parentData.col : len % this.parentData.col
  143 + // 最下面的一排child,无需下边框
  144 + if(index < len - lessNum) {
  145 + classes.push('u-border-bottom')
  146 + }
  147 + }
  148 + })
  149 + // 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
  150 + // #ifdef MP-ALIPAY || MP-TOUTIAO
  151 + classes = classes.join(' ')
  152 + // #endif
  153 + this.classes = classes
  154 + }
  155 + }
  156 + },
  157 + beforeDestroy() {
  158 + // 移除事件监听,释放性能
  159 + uni.$off('$uGridItem')
  160 + }
  161 + };
  162 +</script>
  163 +
  164 +<style lang="scss" scoped>
  165 + @import "../../libs/css/components.scss";
  166 + $u-grid-item-hover-class-opcatiy:.5 !default;
  167 + $u-grid-item-margin-top:1rpx !default;
  168 + $u-grid-item-border-right-width:0.5px !default;
  169 + $u-grid-item-border-bottom-width:0.5px !default;
  170 + $u-grid-item-border-right-color:$u-border-color !default;
  171 + $u-grid-item-border-bottom-color:$u-border-color !default;
  172 + .u-grid-item {
  173 + align-items: center;
  174 + justify-content: center;
  175 + position: relative;
  176 + flex-direction: column;
  177 + /* #ifndef APP-NVUE */
  178 + box-sizing: border-box;
  179 + display: flex;
  180 + /* #endif */
  181 +
  182 + /* #ifdef MP */
  183 + position: relative;
  184 + float: left;
  185 + /* #endif */
  186 +
  187 + /* #ifdef MP-WEIXIN */
  188 + margin-top:$u-grid-item-margin-top;
  189 + /* #endif */
  190 +
  191 + &--hover-class {
  192 + opacity:$u-grid-item-hover-class-opcatiy;
  193 + }
  194 + }
  195 +
  196 + /* #ifdef APP-NVUE */
  197 + // 由于nvue不支持组件内引入app.vue中再引入的样式,所以需要写在这里
  198 + .u-border-right {
  199 + border-right-width:$u-grid-item-border-right-width;
  200 + border-color: $u-grid-item-border-right-color;
  201 + }
  202 +
  203 + .u-border-bottom {
  204 + border-bottom-width:$u-grid-item-border-bottom-width;
  205 + border-color:$u-grid-item-border-bottom-color;
  206 + }
  207 +
  208 + /* #endif */
  209 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-grid/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 分成几列
  4 + col: {
  5 + type: [String, Number],
  6 + default: uni.$u.props.grid.col
  7 + },
  8 + // 是否显示边框
  9 + border: {
  10 + type: Boolean,
  11 + default: uni.$u.props.grid.border
  12 + },
  13 + // 宫格对齐方式,表现为数量少的时候,靠左,居中,还是靠右
  14 + align: {
  15 + type: String,
  16 + default: uni.$u.props.grid.align
  17 + }
  18 + }
  19 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-grid/u-grid.vue 0 → 100644
  1 +<template>
  2 + <view
  3 + class="u-grid"
  4 + ref='u-grid'
  5 + :style="[gridStyle]"
  6 + >
  7 + <slot />
  8 + </view>
  9 +</template>
  10 +
  11 +<script>
  12 + import props from './props.js';
  13 + /**
  14 + * grid 宫格布局
  15 + * @description 宫格组件一般用于同时展示多个同类项目的场景,可以给宫格的项目设置徽标组件(badge),或者图标等,也可以扩展为左右滑动的轮播形式。
  16 + * @tutorial https://www.uviewui.com/components/grid.html
  17 + * @property {String | Number} col 宫格的列数(默认 3 )
  18 + * @property {Boolean} border 是否显示宫格的边框(默认 false )
  19 + * @property {String} align 宫格对齐方式,表现为数量少的时候,靠左,居中,还是靠右 (默认 'left' )
  20 + * @property {Object} customStyle 定义需要用到的外部样式
  21 + * @event {Function} click 点击宫格触发
  22 + * @example <u-grid :col="3" @click="click"></u-grid>
  23 + */
  24 + export default {
  25 + name: 'u-grid',
  26 + mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  27 + data() {
  28 + return {
  29 + index: 0,
  30 + width: 0
  31 + }
  32 + },
  33 + watch: {
  34 + // 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件
  35 + parentData() {
  36 + if (this.children.length) {
  37 + this.children.map(child => {
  38 + // 判断子组件(u-radio)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
  39 + typeof(child.updateParentData) == 'function' && child.updateParentData();
  40 + })
  41 + }
  42 + },
  43 + },
  44 + created() {
  45 + // 如果将children定义在data中,在微信小程序会造成循环引用而报错
  46 + this.children = []
  47 + },
  48 + computed: {
  49 + // 计算父组件的值是否发生变化
  50 + parentData() {
  51 + return [this.hoverClass, this.col, this.size, this.border];
  52 + },
  53 + // 宫格对齐方式
  54 + gridStyle() {
  55 + let style = {};
  56 + switch (this.align) {
  57 + case 'left':
  58 + style.justifyContent = 'flex-start';
  59 + break;
  60 + case 'center':
  61 + style.justifyContent = 'center';
  62 + break;
  63 + case 'right':
  64 + style.justifyContent = 'flex-end';
  65 + break;
  66 + default:
  67 + style.justifyContent = 'flex-start';
  68 + };
  69 + return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle));
  70 + }
  71 + },
  72 + methods: {
  73 + // 此方法由u-grid-item触发,用于在u-grid发出事件
  74 + childClick(name) {
  75 + this.$emit('click', name)
  76 + }
  77 + }
  78 + };
  79 +</script>
  80 +
  81 +<style lang="scss" scoped>
  82 + @import "../../libs/css/components.scss";
  83 + $u-grid-width:100% !default;
  84 + .u-grid {
  85 + /* #ifdef MP */
  86 + width: $u-grid-width;
  87 + position: relative;
  88 + box-sizing: border-box;
  89 + overflow: hidden;
  90 + display: block;
  91 + /* #endif */
  92 + justify-content: center;
  93 + @include flex;
  94 + flex-wrap: wrap;
  95 + align-items: center;
  96 + }
  97 +</style>
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-icon/icons.js 0 → 100644
  1 +export default {
  2 + 'uicon-level': '\ue693',
  3 + 'uicon-column-line': '\ue68e',
  4 + 'uicon-checkbox-mark': '\ue807',
  5 + 'uicon-folder': '\ue7f5',
  6 + 'uicon-movie': '\ue7f6',
  7 + 'uicon-star-fill': '\ue669',
  8 + 'uicon-star': '\ue65f',
  9 + 'uicon-phone-fill': '\ue64f',
  10 + 'uicon-phone': '\ue622',
  11 + 'uicon-apple-fill': '\ue881',
  12 + 'uicon-chrome-circle-fill': '\ue885',
  13 + 'uicon-backspace': '\ue67b',
  14 + 'uicon-attach': '\ue632',
  15 + 'uicon-cut': '\ue948',
  16 + 'uicon-empty-car': '\ue602',
  17 + 'uicon-empty-coupon': '\ue682',
  18 + 'uicon-empty-address': '\ue646',
  19 + 'uicon-empty-favor': '\ue67c',
  20 + 'uicon-empty-permission': '\ue686',
  21 + 'uicon-empty-news': '\ue687',
  22 + 'uicon-empty-search': '\ue664',
  23 + 'uicon-github-circle-fill': '\ue887',
  24 + 'uicon-rmb': '\ue608',
  25 + 'uicon-person-delete-fill': '\ue66a',
  26 + 'uicon-reload': '\ue788',
  27 + 'uicon-order': '\ue68f',
  28 + 'uicon-server-man': '\ue6bc',
  29 + 'uicon-search': '\ue62a',
  30 + 'uicon-fingerprint': '\ue955',
  31 + 'uicon-more-dot-fill': '\ue630',
  32 + 'uicon-scan': '\ue662',
  33 + 'uicon-share-square': '\ue60b',
  34 + 'uicon-map': '\ue61d',
  35 + 'uicon-map-fill': '\ue64e',
  36 + 'uicon-tags': '\ue629',
  37 + 'uicon-tags-fill': '\ue651',
  38 + 'uicon-bookmark-fill': '\ue63b',
  39 + 'uicon-bookmark': '\ue60a',
  40 + 'uicon-eye': '\ue613',
  41 + 'uicon-eye-fill': '\ue641',
  42 + 'uicon-mic': '\ue64a',
  43 + 'uicon-mic-off': '\ue649',
  44 + 'uicon-calendar': '\ue66e',
  45 + 'uicon-calendar-fill': '\ue634',
  46 + 'uicon-trash': '\ue623',
  47 + 'uicon-trash-fill': '\ue658',
  48 + 'uicon-play-left': '\ue66d',
  49 + 'uicon-play-right': '\ue610',
  50 + 'uicon-minus': '\ue618',
  51 + 'uicon-plus': '\ue62d',
  52 + 'uicon-info': '\ue653',
  53 + 'uicon-info-circle': '\ue7d2',
  54 + 'uicon-info-circle-fill': '\ue64b',
  55 + 'uicon-question': '\ue715',
  56 + 'uicon-error': '\ue6d3',
  57 + 'uicon-close': '\ue685',
  58 + 'uicon-checkmark': '\ue6a8',
  59 + 'uicon-android-circle-fill': '\ue67e',
  60 + 'uicon-android-fill': '\ue67d',
  61 + 'uicon-ie': '\ue87b',
  62 + 'uicon-IE-circle-fill': '\ue889',
  63 + 'uicon-google': '\ue87a',
  64 + 'uicon-google-circle-fill': '\ue88a',
  65 + 'uicon-setting-fill': '\ue872',
  66 + 'uicon-setting': '\ue61f',
  67 + 'uicon-minus-square-fill': '\ue855',
  68 + 'uicon-plus-square-fill': '\ue856',
  69 + 'uicon-heart': '\ue7df',
  70 + 'uicon-heart-fill': '\ue851',
  71 + 'uicon-camera': '\ue7d7',
  72 + 'uicon-camera-fill': '\ue870',
  73 + 'uicon-more-circle': '\ue63e',
  74 + 'uicon-more-circle-fill': '\ue645',
  75 + 'uicon-chat': '\ue620',
  76 + 'uicon-chat-fill': '\ue61e',
  77 + 'uicon-bag-fill': '\ue617',
  78 + 'uicon-bag': '\ue619',
  79 + 'uicon-error-circle-fill': '\ue62c',
  80 + 'uicon-error-circle': '\ue624',
  81 + 'uicon-close-circle': '\ue63f',
  82 + 'uicon-close-circle-fill': '\ue637',
  83 + 'uicon-checkmark-circle': '\ue63d',
  84 + 'uicon-checkmark-circle-fill': '\ue635',
  85 + 'uicon-question-circle-fill': '\ue666',
  86 + 'uicon-question-circle': '\ue625',
  87 + 'uicon-share': '\ue631',
  88 + 'uicon-share-fill': '\ue65e',
  89 + 'uicon-shopping-cart': '\ue621',
  90 + 'uicon-shopping-cart-fill': '\ue65d',
  91 + 'uicon-bell': '\ue609',
  92 + 'uicon-bell-fill': '\ue640',
  93 + 'uicon-list': '\ue650',
  94 + 'uicon-list-dot': '\ue616',
  95 + 'uicon-zhihu': '\ue6ba',
  96 + 'uicon-zhihu-circle-fill': '\ue709',
  97 + 'uicon-zhifubao': '\ue6b9',
  98 + 'uicon-zhifubao-circle-fill': '\ue6b8',
  99 + 'uicon-weixin-circle-fill': '\ue6b1',
  100 + 'uicon-weixin-fill': '\ue6b2',
  101 + 'uicon-twitter-circle-fill': '\ue6ab',
  102 + 'uicon-twitter': '\ue6aa',
  103 + 'uicon-taobao-circle-fill': '\ue6a7',
  104 + 'uicon-taobao': '\ue6a6',
  105 + 'uicon-weibo-circle-fill': '\ue6a5',
  106 + 'uicon-weibo': '\ue6a4',
  107 + 'uicon-qq-fill': '\ue6a1',
  108 + 'uicon-qq-circle-fill': '\ue6a0',
  109 + 'uicon-moments-circel-fill': '\ue69a',
  110 + 'uicon-moments': '\ue69b',
  111 + 'uicon-qzone': '\ue695',
  112 + 'uicon-qzone-circle-fill': '\ue696',
  113 + 'uicon-baidu-circle-fill': '\ue680',
  114 + 'uicon-baidu': '\ue681',
  115 + 'uicon-facebook-circle-fill': '\ue68a',
  116 + 'uicon-facebook': '\ue689',
  117 + 'uicon-car': '\ue60c',
  118 + 'uicon-car-fill': '\ue636',
  119 + 'uicon-warning-fill': '\ue64d',
  120 + 'uicon-warning': '\ue694',
  121 + 'uicon-clock-fill': '\ue638',
  122 + 'uicon-clock': '\ue60f',
  123 + 'uicon-edit-pen': '\ue612',
  124 + 'uicon-edit-pen-fill': '\ue66b',
  125 + 'uicon-email': '\ue611',
  126 + 'uicon-email-fill': '\ue642',
  127 + 'uicon-minus-circle': '\ue61b',
  128 + 'uicon-minus-circle-fill': '\ue652',
  129 + 'uicon-plus-circle': '\ue62e',
  130 + 'uicon-plus-circle-fill': '\ue661',
  131 + 'uicon-file-text': '\ue663',
  132 + 'uicon-file-text-fill': '\ue665',
  133 + 'uicon-pushpin': '\ue7e3',
  134 + 'uicon-pushpin-fill': '\ue86e',
  135 + 'uicon-grid': '\ue673',
  136 + 'uicon-grid-fill': '\ue678',
  137 + 'uicon-play-circle': '\ue647',
  138 + 'uicon-play-circle-fill': '\ue655',
  139 + 'uicon-pause-circle-fill': '\ue654',
  140 + 'uicon-pause': '\ue8fa',
  141 + 'uicon-pause-circle': '\ue643',
  142 + 'uicon-eye-off': '\ue648',
  143 + 'uicon-eye-off-outline': '\ue62b',
  144 + 'uicon-gift-fill': '\ue65c',
  145 + 'uicon-gift': '\ue65b',
  146 + 'uicon-rmb-circle-fill': '\ue657',
  147 + 'uicon-rmb-circle': '\ue677',
  148 + 'uicon-kefu-ermai': '\ue656',
  149 + 'uicon-server-fill': '\ue751',
  150 + 'uicon-coupon-fill': '\ue8c4',
  151 + 'uicon-coupon': '\ue8ae',
  152 + 'uicon-integral': '\ue704',
  153 + 'uicon-integral-fill': '\ue703',
  154 + 'uicon-home-fill': '\ue964',
  155 + 'uicon-home': '\ue965',
  156 + 'uicon-hourglass-half-fill': '\ue966',
  157 + 'uicon-hourglass': '\ue967',
  158 + 'uicon-account': '\ue628',
  159 + 'uicon-plus-people-fill': '\ue626',
  160 + 'uicon-minus-people-fill': '\ue615',
  161 + 'uicon-account-fill': '\ue614',
  162 + 'uicon-thumb-down-fill': '\ue726',
  163 + 'uicon-thumb-down': '\ue727',
  164 + 'uicon-thumb-up': '\ue733',
  165 + 'uicon-thumb-up-fill': '\ue72f',
  166 + 'uicon-lock-fill': '\ue979',
  167 + 'uicon-lock-open': '\ue973',
  168 + 'uicon-lock-opened-fill': '\ue974',
  169 + 'uicon-lock': '\ue97a',
  170 + 'uicon-red-packet-fill': '\ue690',
  171 + 'uicon-photo-fill': '\ue98b',
  172 + 'uicon-photo': '\ue98d',
  173 + 'uicon-volume-off-fill': '\ue659',
  174 + 'uicon-volume-off': '\ue644',
  175 + 'uicon-volume-fill': '\ue670',
  176 + 'uicon-volume': '\ue633',
  177 + 'uicon-red-packet': '\ue691',
  178 + 'uicon-download': '\ue63c',
  179 + 'uicon-arrow-up-fill': '\ue6b0',
  180 + 'uicon-arrow-down-fill': '\ue600',
  181 + 'uicon-play-left-fill': '\ue675',
  182 + 'uicon-play-right-fill': '\ue676',
  183 + 'uicon-rewind-left-fill': '\ue679',
  184 + 'uicon-rewind-right-fill': '\ue67a',
  185 + 'uicon-arrow-downward': '\ue604',
  186 + 'uicon-arrow-leftward': '\ue601',
  187 + 'uicon-arrow-rightward': '\ue603',
  188 + 'uicon-arrow-upward': '\ue607',
  189 + 'uicon-arrow-down': '\ue60d',
  190 + 'uicon-arrow-right': '\ue605',
  191 + 'uicon-arrow-left': '\ue60e',
  192 + 'uicon-arrow-up': '\ue606',
  193 + 'uicon-skip-back-left': '\ue674',
  194 + 'uicon-skip-forward-right': '\ue672',
  195 + 'uicon-rewind-right': '\ue66f',
  196 + 'uicon-rewind-left': '\ue671',
  197 + 'uicon-arrow-right-double': '\ue68d',
  198 + 'uicon-arrow-left-double': '\ue68c',
  199 + 'uicon-wifi-off': '\ue668',
  200 + 'uicon-wifi': '\ue667',
  201 + 'uicon-empty-data': '\ue62f',
  202 + 'uicon-empty-history': '\ue684',
  203 + 'uicon-empty-list': '\ue68b',
  204 + 'uicon-empty-page': '\ue627',
  205 + 'uicon-empty-order': '\ue639',
  206 + 'uicon-man': '\ue697',
  207 + 'uicon-woman': '\ue69c',
  208 + 'uicon-man-add': '\ue61c',
  209 + 'uicon-man-add-fill': '\ue64c',
  210 + 'uicon-man-delete': '\ue61a',
  211 + 'uicon-man-delete-fill': '\ue66a',
  212 + 'uicon-zh': '\ue70a',
  213 + 'uicon-en': '\ue692'
  214 +}
... ...
yudao-ui-app/uni_modules/uview-ui/components/u-icon/props.js 0 → 100644
  1 +export default {
  2 + props: {
  3 + // 图标类名
  4 + name: {
  5 + type: String,
  6 + default: uni.$u.props.icon.name
  7 + },
  8 + // 图标颜色,可接受主题色
  9 + color: {
  10 + type: String,
  11 + default: uni.$u.props.icon.color
  12 + },
  13 + // 字体大小,单位px
  14 + size: {
  15 + type: [String, Number],
  16 + default: uni.$u.props.icon.size
  17 + },
  18 + // 是否显示粗体
  19 + bold: {
  20 + type: Boolean,
  21 + default: uni.$u.props.icon.bold
  22 + },
  23 + // 点击图标的时候传递事件出去的index(用于区分点击了哪一个)
  24 + index: {
  25 + type: [String, Number],
  26 + default: uni.$u.props.icon.index
  27 + },
  28 + // 触摸图标时的类名
  29 + hoverClass: {
  30 + type: String,
  31 + default: uni.$u.props.icon.hoverClass
  32 + },
  33 + // 自定义扩展前缀,方便用户扩展自己的图标库
  34 + customPrefix: {
  35 + type: String,
  36 + default: uni.$u.props.icon.customPrefix
  37 + },
  38 + // 图标右边或者下面的文字
  39 + label: {
  40 + type: [String, Number],
  41 + default: uni.$u.props.icon.label
  42 + },
  43 + // label的位置,只能右边或者下边
  44 + labelPos: {
  45 + type: String,
  46 + default: uni.$u.props.icon.labelPos
  47 + },
  48 + // label的大小
  49 + labelSize: {
  50 + type: [String, Number],
  51 + default: uni.$u.props.icon.labelSize
  52 + },
  53 + // label的颜色
  54 + labelColor: {
  55 + type: String,
  56 + default: uni.$u.props.icon.labelColor
  57 + },
  58 + // label与图标的距离
  59 + space: {
  60 + type: [String, Number],
  61 + default: uni.$u.props.icon.space
  62 + },
  63 + // 图片的mode
  64 + imgMode: {
  65 + type: String,
  66 + default: uni.$u.props.icon.imgMode
  67 + },
  68 + // 用于显示图片小图标时,图片的宽度
  69 + width: {
  70 + type: [String, Number],
  71 + default: uni.$u.props.icon.width
  72 + },
  73 + // 用于显示图片小图标时,图片的高度
  74 + height: {
  75 + type: [String, Number],
  76 + default: uni.$u.props.icon.height
  77 + },
  78 + // 用于解决某些情况下,让图标垂直居中的用途
  79 + top: {
  80 + type: [String, Number],
  81 + default: uni.$u.props.icon.top
  82 + },
  83 + // 是否阻止事件传播
  84 + stop: {
  85 + type: Boolean,
  86 + default: uni.$u.props.icon.stop
  87 + }
  88 + }
  89 +}
... ...