修改了niuapp的源码
This commit is contained in:
parent
c0824faff5
commit
485f80f6a9
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,6 +7,5 @@
|
||||||
|
|
||||||
# JavaScript
|
# JavaScript
|
||||||
node_modules/
|
node_modules/
|
||||||
uni_modules
|
|
||||||
unpackage
|
unpackage
|
||||||
|
|
||||||
|
|
100
manifest.json
100
manifest.json
|
@ -1,28 +1,28 @@
|
||||||
{
|
{
|
||||||
"name": "12123",
|
"name" : "12123",
|
||||||
"appid": "__UNI__099032D",
|
"appid" : "__UNI__099032D",
|
||||||
"description": "",
|
"description" : "",
|
||||||
"versionName": "1.0.0",
|
"versionName" : "1.0.0",
|
||||||
"versionCode": "100",
|
"versionCode" : "100",
|
||||||
"transformPx": false,
|
"transformPx" : false,
|
||||||
/* 5+App特有相关 */
|
/* 5+App特有相关 */
|
||||||
"app-plus": {
|
"app-plus" : {
|
||||||
"usingComponents": true,
|
"usingComponents" : true,
|
||||||
"nvueStyleCompiler": "uni-app",
|
"nvueStyleCompiler" : "uni-app",
|
||||||
"compilerVersion": 3,
|
"compilerVersion" : 3,
|
||||||
"splashscreen": {
|
"splashscreen" : {
|
||||||
"alwaysShowBeforeRender": true,
|
"alwaysShowBeforeRender" : true,
|
||||||
"waiting": false,
|
"waiting" : false,
|
||||||
"autoclose": true,
|
"autoclose" : true,
|
||||||
"delay": 0
|
"delay" : 0
|
||||||
},
|
},
|
||||||
/* 模块配置 */
|
/* 模块配置 */
|
||||||
"modules": {},
|
"modules" : {},
|
||||||
/* 应用发布信息 */
|
/* 应用发布信息 */
|
||||||
"distribute": {
|
"distribute" : {
|
||||||
/* android打包配置 */
|
/* android打包配置 */
|
||||||
"android": {
|
"android" : {
|
||||||
"permissions": [
|
"permissions" : [
|
||||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||||
|
@ -41,52 +41,52 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
/* ios打包配置 */
|
/* ios打包配置 */
|
||||||
"ios": {
|
"ios" : {
|
||||||
"dSYMs": false
|
"dSYMs" : false
|
||||||
},
|
},
|
||||||
/* SDK配置 */
|
/* SDK配置 */
|
||||||
"sdkConfigs": {
|
"sdkConfigs" : {
|
||||||
"ad": {}
|
"ad" : {}
|
||||||
},
|
},
|
||||||
"splashscreen": {
|
"splashscreen" : {
|
||||||
"androidStyle": "default",
|
"androidStyle" : "default",
|
||||||
"android": {
|
"android" : {
|
||||||
"xxhdpi": "static/qideng/pingbaoL.png",
|
"xxhdpi" : "static/qideng/pingbaoL.png",
|
||||||
"xhdpi": "static/qideng/pingbaoM.png",
|
"xhdpi" : "static/qideng/pingbaoM.png",
|
||||||
"hdpi": "static/qideng/pingbaoS.png"
|
"hdpi" : "static/qideng/pingbaoS.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"icons": {
|
"icons" : {
|
||||||
"android": {
|
"android" : {
|
||||||
"xxxhdpi": "static/qideng/Ll.png",
|
"xxxhdpi" : "static/qideng/Ll.png",
|
||||||
"xxhdpi": "static/qideng/Ll.png",
|
"xxhdpi" : "static/qideng/Ll.png",
|
||||||
"xhdpi": "static/qideng/Mm.png",
|
"xhdpi" : "static/qideng/Mm.png",
|
||||||
"hdpi": "static/qideng/Ss.png"
|
"hdpi" : "static/qideng/Ss.png"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/* 快应用特有相关 */
|
/* 快应用特有相关 */
|
||||||
"quickapp": {},
|
"quickapp" : {},
|
||||||
/* 小程序特有相关 */
|
/* 小程序特有相关 */
|
||||||
"mp-weixin": {
|
"mp-weixin" : {
|
||||||
"appid": "",
|
"appid" : "",
|
||||||
"setting": {
|
"setting" : {
|
||||||
"urlCheck": false
|
"urlCheck" : false
|
||||||
},
|
},
|
||||||
"usingComponents": true
|
"usingComponents" : true
|
||||||
},
|
},
|
||||||
"mp-alipay": {
|
"mp-alipay" : {
|
||||||
"usingComponents": true
|
"usingComponents" : true
|
||||||
},
|
},
|
||||||
"mp-baidu": {
|
"mp-baidu" : {
|
||||||
"usingComponents": true
|
"usingComponents" : true
|
||||||
},
|
},
|
||||||
"mp-toutiao": {
|
"mp-toutiao" : {
|
||||||
"usingComponents": true
|
"usingComponents" : true
|
||||||
},
|
},
|
||||||
"uniStatistics": {
|
"uniStatistics" : {
|
||||||
"enable": false
|
"enable" : false
|
||||||
},
|
},
|
||||||
"vueVersion": "3"
|
"vueVersion" : "3"
|
||||||
}
|
}
|
|
@ -1,15 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<view style="background-color: #2c66a9; width: 100%; height: 5vh" :style="{ backgroundPositionY: -44 + safeAreaInsets.top + 'px' }">
|
<view>
|
||||||
<!-- 自定义导航栏 -->
|
<!-- 自定义导航栏 -->
|
||||||
<view :style="{ paddingTop: safeAreaInsets.top + 'px' }" class="van-nav-bar">
|
<uni-nav-bar :fixed="true" shadow background-color="#2c66a9" color="#fff" @clickLeft="back" status-bar left-icon="back" left-text="返回" title="业务中心" />
|
||||||
<view class="van-nav-bar__content">
|
|
||||||
<view class="page-icon" @click="gotoBack">
|
|
||||||
<uni-icons color="#fff" type="back" size="26"></uni-icons>
|
|
||||||
<view>返回</view>
|
|
||||||
</view>
|
|
||||||
<view class="page-navbar">业务中心</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<view class="search">
|
<view class="search">
|
||||||
<uni-icons type="search" color="#959595" size="20" style="transform: translateY(0.05rem)"></uni-icons>
|
<uni-icons type="search" color="#959595" size="20" style="transform: translateY(0.05rem)"></uni-icons>
|
||||||
|
@ -28,12 +20,13 @@
|
||||||
<view class="card" v-for="(item, index) in item.content" style="width: 4rem">
|
<view class="card" v-for="(item, index) in item.content" style="width: 4rem">
|
||||||
<view class="icon">
|
<view class="icon">
|
||||||
<!-- <uni-icons type="image-filled" size="30" color="#3c9bff"></uni-icons> -->
|
<!-- <uni-icons type="image-filled" size="30" color="#3c9bff"></uni-icons> -->
|
||||||
<image :src="item.icon" style="width: 2.5rem; height: 2.5rem"></image>
|
<image :src="item.icon" :style="{ width: item.id == 50 ? '2rem' : '2.5rem', height: item.id == 50 ? '2em' : '2.5rem' }"></image>
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view
|
||||||
class="text"
|
class="text"
|
||||||
:style="{
|
:style="{
|
||||||
width: item.txt.length == 8 || item.txt.length == 7 || item.txt.length == 6 ? '3.6rem' : '',
|
width: item.txt.length == 8 || item.txt.length == 7 || item.txt.length == 6 ? '3.6rem' : '',
|
||||||
|
'margin-top': item.id == 50 ? '0.5rem' : '',
|
||||||
transform: item.txt.length == 8 || item.txt.length == 7 || item.txt.length == 6 ? 'translateX(4.5px)' : ''
|
transform: item.txt.length == 8 || item.txt.length == 7 || item.txt.length == 6 ? 'translateX(4.5px)' : ''
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
@ -47,7 +40,7 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
const { safeAreaInsets } = uni.getSystemInfoSync();
|
// const { safeAreaInsets } = uni.getSystemInfoSync();
|
||||||
const tags = ref([
|
const tags = ref([
|
||||||
{
|
{
|
||||||
text: '违法',
|
text: '违法',
|
||||||
|
@ -216,7 +209,7 @@ const functionList = ref([
|
||||||
{
|
{
|
||||||
txt: '事故快处模拟',
|
txt: '事故快处模拟',
|
||||||
icon: '../../../static/yewuzhongxin/4/4.png',
|
icon: '../../../static/yewuzhongxin/4/4.png',
|
||||||
id: 3
|
id: 50
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
txt: '事故视频快处',
|
txt: '事故视频快处',
|
||||||
|
@ -264,7 +257,7 @@ const functionList = ref([
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
// 返回上一级
|
// 返回上一级
|
||||||
const gotoBack = () => {
|
const back = () => {
|
||||||
uni.navigateBack({
|
uni.navigateBack({
|
||||||
delta: 1
|
delta: 1
|
||||||
});
|
});
|
||||||
|
@ -272,25 +265,6 @@ const gotoBack = () => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.van-nav-bar__content {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 4rem;
|
|
||||||
background-color: #2c66a9;
|
|
||||||
color: #fff;
|
|
||||||
letter-spacing: 1.5px;
|
|
||||||
position: relative;
|
|
||||||
.page-icon {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
.page-navbar {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.search {
|
.search {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
42
uni_modules/uni-icons/changelog.md
Normal file
42
uni_modules/uni-icons/changelog.md
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
## 2.0.10(2024-06-07)
|
||||||
|
- 优化 uni-app x 中,size 属性的类型
|
||||||
|
## 2.0.9(2024-01-12)
|
||||||
|
fix: 修复图标大小默认值错误的问题
|
||||||
|
## 2.0.8(2023-12-14)
|
||||||
|
- 修复 项目未使用 ts 情况下,打包报错的bug
|
||||||
|
## 2.0.7(2023-12-14)
|
||||||
|
- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug
|
||||||
|
## 2.0.6(2023-12-11)
|
||||||
|
- 优化 兼容老版本icon类型,如 top ,bottom 等
|
||||||
|
## 2.0.5(2023-12-11)
|
||||||
|
- 优化 兼容老版本icon类型,如 top ,bottom 等
|
||||||
|
## 2.0.4(2023-12-06)
|
||||||
|
- 优化 uni-app x 下示例项目图标排序
|
||||||
|
## 2.0.3(2023-12-06)
|
||||||
|
- 修复 nvue下引入组件报错的bug
|
||||||
|
## 2.0.2(2023-12-05)
|
||||||
|
-优化 size 属性支持单位
|
||||||
|
## 2.0.1(2023-12-05)
|
||||||
|
- 新增 uni-app x 支持定义图标
|
||||||
|
## 1.3.5(2022-01-24)
|
||||||
|
- 优化 size 属性可以传入不带单位的字符串数值
|
||||||
|
## 1.3.4(2022-01-24)
|
||||||
|
- 优化 size 支持其他单位
|
||||||
|
## 1.3.3(2022-01-17)
|
||||||
|
- 修复 nvue 有些图标不显示的bug,兼容老版本图标
|
||||||
|
## 1.3.2(2021-12-01)
|
||||||
|
- 优化 示例可复制图标名称
|
||||||
|
## 1.3.1(2021-11-23)
|
||||||
|
- 优化 兼容旧组件 type 值
|
||||||
|
## 1.3.0(2021-11-19)
|
||||||
|
- 新增 更多图标
|
||||||
|
- 优化 自定义图标使用方式
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
|
||||||
|
## 1.1.7(2021-11-08)
|
||||||
|
## 1.2.0(2021-07-30)
|
||||||
|
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 1.1.5(2021-05-12)
|
||||||
|
- 新增 组件示例地址
|
||||||
|
## 1.1.4(2021-02-05)
|
||||||
|
- 调整为uni_modules目录规范
|
91
uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
Normal file
91
uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<template>
|
||||||
|
<text class="uni-icons" :style="styleObj">
|
||||||
|
<slot>{{unicode}}</slot>
|
||||||
|
</text>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { fontData, IconsDataItem } from './uniicons_file'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icons 图标
|
||||||
|
* @description 用于展示 icon 图标
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
|
||||||
|
* @property {Number,String} size 图标大小
|
||||||
|
* @property {String} type 图标图案,参考示例
|
||||||
|
* @property {String} color 图标颜色
|
||||||
|
* @property {String} customPrefix 自定义图标
|
||||||
|
* @event {Function} click 点击 Icon 触发事件
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: "uni-icons",
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: '#333333'
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 16
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
unicode() : string {
|
||||||
|
let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type })
|
||||||
|
if (codes !== null) {
|
||||||
|
return codes.unicode
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
iconSize() : string {
|
||||||
|
const size = this.size
|
||||||
|
if (typeof size == 'string') {
|
||||||
|
const reg = /^[0-9]*$/g
|
||||||
|
return reg.test(size as string) ? '' + size + 'px' : '' + size;
|
||||||
|
// return '' + this.size
|
||||||
|
}
|
||||||
|
return this.getFontSize(size as number)
|
||||||
|
},
|
||||||
|
styleObj() : UTSJSONObject {
|
||||||
|
if (this.fontFamily !== '') {
|
||||||
|
return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily }
|
||||||
|
}
|
||||||
|
return { color: this.color, fontSize: this.iconSize }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() { },
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 字体大小
|
||||||
|
*/
|
||||||
|
getFontSize(size : number) : string {
|
||||||
|
return size + 'px';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
@font-face {
|
||||||
|
font-family: UniIconsFontFamily;
|
||||||
|
src: url('./uniicons.ttf');
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-icons {
|
||||||
|
font-family: UniIconsFontFamily;
|
||||||
|
font-size: 18px;
|
||||||
|
font-style: normal;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
</style>
|
110
uni_modules/uni-icons/components/uni-icons/uni-icons.vue
Normal file
110
uni_modules/uni-icons/components/uni-icons/uni-icons.vue
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
<template>
|
||||||
|
<!-- #ifdef APP-NVUE -->
|
||||||
|
<text :style="styleObj" class="uni-icons" @click="_onClick">{{unicode}}</text>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef APP-NVUE -->
|
||||||
|
<text :style="styleObj" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick">
|
||||||
|
<slot></slot>
|
||||||
|
</text>
|
||||||
|
<!-- #endif -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { fontData } from './uniicons_file_vue.js';
|
||||||
|
|
||||||
|
const getVal = (val) => {
|
||||||
|
const reg = /^[0-9]*$/g
|
||||||
|
return (typeof val === 'number' || reg.test(val)) ? val + 'px' : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
var domModule = weex.requireModule('dom');
|
||||||
|
import iconUrl from './uniicons.ttf'
|
||||||
|
domModule.addRule('fontFace', {
|
||||||
|
'fontFamily': "uniicons",
|
||||||
|
'src': "url('" + iconUrl + "')"
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icons 图标
|
||||||
|
* @description 用于展示 icons 图标
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
|
||||||
|
* @property {Number} size 图标大小
|
||||||
|
* @property {String} type 图标图案,参考示例
|
||||||
|
* @property {String} color 图标颜色
|
||||||
|
* @property {String} customPrefix 自定义图标
|
||||||
|
* @event {Function} click 点击 Icon 触发事件
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'UniIcons',
|
||||||
|
emits: ['click'],
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: '#333333'
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 16
|
||||||
|
},
|
||||||
|
customPrefix: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
icons: fontData
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
unicode() {
|
||||||
|
let code = this.icons.find(v => v.font_class === this.type)
|
||||||
|
if (code) {
|
||||||
|
return code.unicode
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
iconSize() {
|
||||||
|
return getVal(this.size)
|
||||||
|
},
|
||||||
|
styleObj() {
|
||||||
|
if (this.fontFamily !== '') {
|
||||||
|
return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`
|
||||||
|
}
|
||||||
|
return `color: ${this.color}; font-size: ${this.iconSize};`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
_onClick() {
|
||||||
|
this.$emit('click')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
@import './uniicons.css';
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: uniicons;
|
||||||
|
src: url('./uniicons.ttf');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
.uni-icons {
|
||||||
|
font-family: uniicons;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
664
uni_modules/uni-icons/components/uni-icons/uniicons.css
Normal file
664
uni_modules/uni-icons/components/uni-icons/uniicons.css
Normal file
|
@ -0,0 +1,664 @@
|
||||||
|
|
||||||
|
.uniui-cart-filled:before {
|
||||||
|
content: "\e6d0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-gift-filled:before {
|
||||||
|
content: "\e6c4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-color:before {
|
||||||
|
content: "\e6cf";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-wallet:before {
|
||||||
|
content: "\e6b1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-settings-filled:before {
|
||||||
|
content: "\e6ce";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-auth-filled:before {
|
||||||
|
content: "\e6cc";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-shop-filled:before {
|
||||||
|
content: "\e6cd";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-staff-filled:before {
|
||||||
|
content: "\e6cb";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-vip-filled:before {
|
||||||
|
content: "\e6c6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-plus-filled:before {
|
||||||
|
content: "\e6c7";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-folder-add-filled:before {
|
||||||
|
content: "\e6c8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-color-filled:before {
|
||||||
|
content: "\e6c9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-tune-filled:before {
|
||||||
|
content: "\e6ca";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-calendar-filled:before {
|
||||||
|
content: "\e6c0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-notification-filled:before {
|
||||||
|
content: "\e6c1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-wallet-filled:before {
|
||||||
|
content: "\e6c2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-medal-filled:before {
|
||||||
|
content: "\e6c3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-fire-filled:before {
|
||||||
|
content: "\e6c5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-refreshempty:before {
|
||||||
|
content: "\e6bf";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-location-filled:before {
|
||||||
|
content: "\e6af";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-person-filled:before {
|
||||||
|
content: "\e69d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-personadd-filled:before {
|
||||||
|
content: "\e698";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowthinleft:before {
|
||||||
|
content: "\e6d2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowthinup:before {
|
||||||
|
content: "\e6d3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowthindown:before {
|
||||||
|
content: "\e6d4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-back:before {
|
||||||
|
content: "\e6b9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-forward:before {
|
||||||
|
content: "\e6ba";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrow-right:before {
|
||||||
|
content: "\e6bb";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrow-left:before {
|
||||||
|
content: "\e6bc";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrow-up:before {
|
||||||
|
content: "\e6bd";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrow-down:before {
|
||||||
|
content: "\e6be";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowthinright:before {
|
||||||
|
content: "\e6d1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-down:before {
|
||||||
|
content: "\e6b8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-bottom:before {
|
||||||
|
content: "\e6b8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowright:before {
|
||||||
|
content: "\e6d5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-right:before {
|
||||||
|
content: "\e6b5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-up:before {
|
||||||
|
content: "\e6b6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-top:before {
|
||||||
|
content: "\e6b6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-left:before {
|
||||||
|
content: "\e6b7";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowup:before {
|
||||||
|
content: "\e6d6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-eye:before {
|
||||||
|
content: "\e651";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-eye-filled:before {
|
||||||
|
content: "\e66a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-eye-slash:before {
|
||||||
|
content: "\e6b3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-eye-slash-filled:before {
|
||||||
|
content: "\e6b4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-info-filled:before {
|
||||||
|
content: "\e649";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-reload:before {
|
||||||
|
content: "\e6b2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-micoff-filled:before {
|
||||||
|
content: "\e6b0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-map-pin-ellipse:before {
|
||||||
|
content: "\e6ac";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-map-pin:before {
|
||||||
|
content: "\e6ad";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-location:before {
|
||||||
|
content: "\e6ae";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-starhalf:before {
|
||||||
|
content: "\e683";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-star:before {
|
||||||
|
content: "\e688";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-star-filled:before {
|
||||||
|
content: "\e68f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-calendar:before {
|
||||||
|
content: "\e6a0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-fire:before {
|
||||||
|
content: "\e6a1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-medal:before {
|
||||||
|
content: "\e6a2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-font:before {
|
||||||
|
content: "\e6a3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-gift:before {
|
||||||
|
content: "\e6a4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-link:before {
|
||||||
|
content: "\e6a5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-notification:before {
|
||||||
|
content: "\e6a6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-staff:before {
|
||||||
|
content: "\e6a7";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-vip:before {
|
||||||
|
content: "\e6a8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-folder-add:before {
|
||||||
|
content: "\e6a9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-tune:before {
|
||||||
|
content: "\e6aa";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-auth:before {
|
||||||
|
content: "\e6ab";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-person:before {
|
||||||
|
content: "\e699";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-email-filled:before {
|
||||||
|
content: "\e69a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-phone-filled:before {
|
||||||
|
content: "\e69b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-phone:before {
|
||||||
|
content: "\e69c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-email:before {
|
||||||
|
content: "\e69e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-personadd:before {
|
||||||
|
content: "\e69f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chatboxes-filled:before {
|
||||||
|
content: "\e692";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-contact:before {
|
||||||
|
content: "\e693";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chatbubble-filled:before {
|
||||||
|
content: "\e694";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-contact-filled:before {
|
||||||
|
content: "\e695";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chatboxes:before {
|
||||||
|
content: "\e696";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chatbubble:before {
|
||||||
|
content: "\e697";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-upload-filled:before {
|
||||||
|
content: "\e68e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-upload:before {
|
||||||
|
content: "\e690";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-weixin:before {
|
||||||
|
content: "\e691";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-compose:before {
|
||||||
|
content: "\e67f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-qq:before {
|
||||||
|
content: "\e680";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-download-filled:before {
|
||||||
|
content: "\e681";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-pyq:before {
|
||||||
|
content: "\e682";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-sound:before {
|
||||||
|
content: "\e684";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-trash-filled:before {
|
||||||
|
content: "\e685";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-sound-filled:before {
|
||||||
|
content: "\e686";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-trash:before {
|
||||||
|
content: "\e687";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-videocam-filled:before {
|
||||||
|
content: "\e689";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-spinner-cycle:before {
|
||||||
|
content: "\e68a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-weibo:before {
|
||||||
|
content: "\e68b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-videocam:before {
|
||||||
|
content: "\e68c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-download:before {
|
||||||
|
content: "\e68d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-help:before {
|
||||||
|
content: "\e679";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-navigate-filled:before {
|
||||||
|
content: "\e67a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-plusempty:before {
|
||||||
|
content: "\e67b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-smallcircle:before {
|
||||||
|
content: "\e67c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-minus-filled:before {
|
||||||
|
content: "\e67d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-micoff:before {
|
||||||
|
content: "\e67e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-closeempty:before {
|
||||||
|
content: "\e66c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-clear:before {
|
||||||
|
content: "\e66d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-navigate:before {
|
||||||
|
content: "\e66e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-minus:before {
|
||||||
|
content: "\e66f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-image:before {
|
||||||
|
content: "\e670";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-mic:before {
|
||||||
|
content: "\e671";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-paperplane:before {
|
||||||
|
content: "\e672";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-close:before {
|
||||||
|
content: "\e673";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-help-filled:before {
|
||||||
|
content: "\e674";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-paperplane-filled:before {
|
||||||
|
content: "\e675";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-plus:before {
|
||||||
|
content: "\e676";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-mic-filled:before {
|
||||||
|
content: "\e677";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-image-filled:before {
|
||||||
|
content: "\e678";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-locked-filled:before {
|
||||||
|
content: "\e668";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-info:before {
|
||||||
|
content: "\e669";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-locked:before {
|
||||||
|
content: "\e66b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-camera-filled:before {
|
||||||
|
content: "\e658";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chat-filled:before {
|
||||||
|
content: "\e659";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-camera:before {
|
||||||
|
content: "\e65a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-circle:before {
|
||||||
|
content: "\e65b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-checkmarkempty:before {
|
||||||
|
content: "\e65c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chat:before {
|
||||||
|
content: "\e65d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-circle-filled:before {
|
||||||
|
content: "\e65e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-flag:before {
|
||||||
|
content: "\e65f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-flag-filled:before {
|
||||||
|
content: "\e660";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-gear-filled:before {
|
||||||
|
content: "\e661";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-home:before {
|
||||||
|
content: "\e662";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-home-filled:before {
|
||||||
|
content: "\e663";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-gear:before {
|
||||||
|
content: "\e664";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-smallcircle-filled:before {
|
||||||
|
content: "\e665";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-map-filled:before {
|
||||||
|
content: "\e666";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-map:before {
|
||||||
|
content: "\e667";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-refresh-filled:before {
|
||||||
|
content: "\e656";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-refresh:before {
|
||||||
|
content: "\e657";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-cloud-upload:before {
|
||||||
|
content: "\e645";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-cloud-download-filled:before {
|
||||||
|
content: "\e646";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-cloud-download:before {
|
||||||
|
content: "\e647";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-cloud-upload-filled:before {
|
||||||
|
content: "\e648";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-redo:before {
|
||||||
|
content: "\e64a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-images-filled:before {
|
||||||
|
content: "\e64b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-undo-filled:before {
|
||||||
|
content: "\e64c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-more:before {
|
||||||
|
content: "\e64d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-more-filled:before {
|
||||||
|
content: "\e64e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-undo:before {
|
||||||
|
content: "\e64f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-images:before {
|
||||||
|
content: "\e650";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-paperclip:before {
|
||||||
|
content: "\e652";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-settings:before {
|
||||||
|
content: "\e653";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-search:before {
|
||||||
|
content: "\e654";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-redo-filled:before {
|
||||||
|
content: "\e655";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-list:before {
|
||||||
|
content: "\e644";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-mail-open-filled:before {
|
||||||
|
content: "\e63a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-hand-down-filled:before {
|
||||||
|
content: "\e63c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-hand-down:before {
|
||||||
|
content: "\e63d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-hand-up-filled:before {
|
||||||
|
content: "\e63e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-hand-up:before {
|
||||||
|
content: "\e63f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-heart-filled:before {
|
||||||
|
content: "\e641";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-mail-open:before {
|
||||||
|
content: "\e643";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-heart:before {
|
||||||
|
content: "\e639";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-loop:before {
|
||||||
|
content: "\e633";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-pulldown:before {
|
||||||
|
content: "\e632";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-scan:before {
|
||||||
|
content: "\e62a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-bars:before {
|
||||||
|
content: "\e627";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-checkbox:before {
|
||||||
|
content: "\e62b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-checkbox-filled:before {
|
||||||
|
content: "\e62c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-shop:before {
|
||||||
|
content: "\e62f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-headphones:before {
|
||||||
|
content: "\e630";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-cart:before {
|
||||||
|
content: "\e631";
|
||||||
|
}
|
BIN
uni_modules/uni-icons/components/uni-icons/uniicons.ttf
Normal file
BIN
uni_modules/uni-icons/components/uni-icons/uniicons.ttf
Normal file
Binary file not shown.
664
uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
Normal file
664
uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
Normal file
|
@ -0,0 +1,664 @@
|
||||||
|
|
||||||
|
export type IconsData = {
|
||||||
|
id : string
|
||||||
|
name : string
|
||||||
|
font_family : string
|
||||||
|
css_prefix_text : string
|
||||||
|
description : string
|
||||||
|
glyphs : Array<IconsDataItem>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IconsDataItem = {
|
||||||
|
font_class : string
|
||||||
|
unicode : string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const fontData = [
|
||||||
|
{
|
||||||
|
"font_class": "arrow-down",
|
||||||
|
"unicode": "\ue6be"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "arrow-left",
|
||||||
|
"unicode": "\ue6bc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "arrow-right",
|
||||||
|
"unicode": "\ue6bb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "arrow-up",
|
||||||
|
"unicode": "\ue6bd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "auth",
|
||||||
|
"unicode": "\ue6ab"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "auth-filled",
|
||||||
|
"unicode": "\ue6cc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "back",
|
||||||
|
"unicode": "\ue6b9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "bars",
|
||||||
|
"unicode": "\ue627"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "calendar",
|
||||||
|
"unicode": "\ue6a0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "calendar-filled",
|
||||||
|
"unicode": "\ue6c0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "camera",
|
||||||
|
"unicode": "\ue65a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "camera-filled",
|
||||||
|
"unicode": "\ue658"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cart",
|
||||||
|
"unicode": "\ue631"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cart-filled",
|
||||||
|
"unicode": "\ue6d0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chat",
|
||||||
|
"unicode": "\ue65d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chat-filled",
|
||||||
|
"unicode": "\ue659"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chatboxes",
|
||||||
|
"unicode": "\ue696"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chatboxes-filled",
|
||||||
|
"unicode": "\ue692"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chatbubble",
|
||||||
|
"unicode": "\ue697"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chatbubble-filled",
|
||||||
|
"unicode": "\ue694"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "checkbox",
|
||||||
|
"unicode": "\ue62b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "checkbox-filled",
|
||||||
|
"unicode": "\ue62c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "checkmarkempty",
|
||||||
|
"unicode": "\ue65c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "circle",
|
||||||
|
"unicode": "\ue65b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "circle-filled",
|
||||||
|
"unicode": "\ue65e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "clear",
|
||||||
|
"unicode": "\ue66d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "close",
|
||||||
|
"unicode": "\ue673"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "closeempty",
|
||||||
|
"unicode": "\ue66c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cloud-download",
|
||||||
|
"unicode": "\ue647"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cloud-download-filled",
|
||||||
|
"unicode": "\ue646"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cloud-upload",
|
||||||
|
"unicode": "\ue645"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cloud-upload-filled",
|
||||||
|
"unicode": "\ue648"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "color",
|
||||||
|
"unicode": "\ue6cf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "color-filled",
|
||||||
|
"unicode": "\ue6c9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "compose",
|
||||||
|
"unicode": "\ue67f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "contact",
|
||||||
|
"unicode": "\ue693"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "contact-filled",
|
||||||
|
"unicode": "\ue695"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "down",
|
||||||
|
"unicode": "\ue6b8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "bottom",
|
||||||
|
"unicode": "\ue6b8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "download",
|
||||||
|
"unicode": "\ue68d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "download-filled",
|
||||||
|
"unicode": "\ue681"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "email",
|
||||||
|
"unicode": "\ue69e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "email-filled",
|
||||||
|
"unicode": "\ue69a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "eye",
|
||||||
|
"unicode": "\ue651"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "eye-filled",
|
||||||
|
"unicode": "\ue66a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "eye-slash",
|
||||||
|
"unicode": "\ue6b3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "eye-slash-filled",
|
||||||
|
"unicode": "\ue6b4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "fire",
|
||||||
|
"unicode": "\ue6a1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "fire-filled",
|
||||||
|
"unicode": "\ue6c5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "flag",
|
||||||
|
"unicode": "\ue65f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "flag-filled",
|
||||||
|
"unicode": "\ue660"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "folder-add",
|
||||||
|
"unicode": "\ue6a9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "folder-add-filled",
|
||||||
|
"unicode": "\ue6c8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "font",
|
||||||
|
"unicode": "\ue6a3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "forward",
|
||||||
|
"unicode": "\ue6ba"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "gear",
|
||||||
|
"unicode": "\ue664"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "gear-filled",
|
||||||
|
"unicode": "\ue661"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "gift",
|
||||||
|
"unicode": "\ue6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "gift-filled",
|
||||||
|
"unicode": "\ue6c4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "hand-down",
|
||||||
|
"unicode": "\ue63d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "hand-down-filled",
|
||||||
|
"unicode": "\ue63c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "hand-up",
|
||||||
|
"unicode": "\ue63f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "hand-up-filled",
|
||||||
|
"unicode": "\ue63e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "headphones",
|
||||||
|
"unicode": "\ue630"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "heart",
|
||||||
|
"unicode": "\ue639"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "heart-filled",
|
||||||
|
"unicode": "\ue641"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "help",
|
||||||
|
"unicode": "\ue679"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "help-filled",
|
||||||
|
"unicode": "\ue674"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "home",
|
||||||
|
"unicode": "\ue662"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "home-filled",
|
||||||
|
"unicode": "\ue663"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "image",
|
||||||
|
"unicode": "\ue670"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "image-filled",
|
||||||
|
"unicode": "\ue678"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "images",
|
||||||
|
"unicode": "\ue650"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "images-filled",
|
||||||
|
"unicode": "\ue64b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "info",
|
||||||
|
"unicode": "\ue669"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "info-filled",
|
||||||
|
"unicode": "\ue649"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "left",
|
||||||
|
"unicode": "\ue6b7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "link",
|
||||||
|
"unicode": "\ue6a5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "list",
|
||||||
|
"unicode": "\ue644"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "location",
|
||||||
|
"unicode": "\ue6ae"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "location-filled",
|
||||||
|
"unicode": "\ue6af"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "locked",
|
||||||
|
"unicode": "\ue66b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "locked-filled",
|
||||||
|
"unicode": "\ue668"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "loop",
|
||||||
|
"unicode": "\ue633"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "mail-open",
|
||||||
|
"unicode": "\ue643"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "mail-open-filled",
|
||||||
|
"unicode": "\ue63a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "map",
|
||||||
|
"unicode": "\ue667"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "map-filled",
|
||||||
|
"unicode": "\ue666"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "map-pin",
|
||||||
|
"unicode": "\ue6ad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "map-pin-ellipse",
|
||||||
|
"unicode": "\ue6ac"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "medal",
|
||||||
|
"unicode": "\ue6a2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "medal-filled",
|
||||||
|
"unicode": "\ue6c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "mic",
|
||||||
|
"unicode": "\ue671"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "mic-filled",
|
||||||
|
"unicode": "\ue677"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "micoff",
|
||||||
|
"unicode": "\ue67e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "micoff-filled",
|
||||||
|
"unicode": "\ue6b0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "minus",
|
||||||
|
"unicode": "\ue66f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "minus-filled",
|
||||||
|
"unicode": "\ue67d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "more",
|
||||||
|
"unicode": "\ue64d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "more-filled",
|
||||||
|
"unicode": "\ue64e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "navigate",
|
||||||
|
"unicode": "\ue66e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "navigate-filled",
|
||||||
|
"unicode": "\ue67a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "notification",
|
||||||
|
"unicode": "\ue6a6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "notification-filled",
|
||||||
|
"unicode": "\ue6c1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "paperclip",
|
||||||
|
"unicode": "\ue652"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "paperplane",
|
||||||
|
"unicode": "\ue672"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "paperplane-filled",
|
||||||
|
"unicode": "\ue675"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "person",
|
||||||
|
"unicode": "\ue699"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "person-filled",
|
||||||
|
"unicode": "\ue69d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "personadd",
|
||||||
|
"unicode": "\ue69f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "personadd-filled",
|
||||||
|
"unicode": "\ue698"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "personadd-filled-copy",
|
||||||
|
"unicode": "\ue6d1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "phone",
|
||||||
|
"unicode": "\ue69c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "phone-filled",
|
||||||
|
"unicode": "\ue69b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "plus",
|
||||||
|
"unicode": "\ue676"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "plus-filled",
|
||||||
|
"unicode": "\ue6c7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "plusempty",
|
||||||
|
"unicode": "\ue67b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "pulldown",
|
||||||
|
"unicode": "\ue632"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "pyq",
|
||||||
|
"unicode": "\ue682"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "qq",
|
||||||
|
"unicode": "\ue680"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "redo",
|
||||||
|
"unicode": "\ue64a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "redo-filled",
|
||||||
|
"unicode": "\ue655"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "refresh",
|
||||||
|
"unicode": "\ue657"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "refresh-filled",
|
||||||
|
"unicode": "\ue656"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "refreshempty",
|
||||||
|
"unicode": "\ue6bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "reload",
|
||||||
|
"unicode": "\ue6b2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "right",
|
||||||
|
"unicode": "\ue6b5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "scan",
|
||||||
|
"unicode": "\ue62a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "search",
|
||||||
|
"unicode": "\ue654"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "settings",
|
||||||
|
"unicode": "\ue653"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "settings-filled",
|
||||||
|
"unicode": "\ue6ce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "shop",
|
||||||
|
"unicode": "\ue62f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "shop-filled",
|
||||||
|
"unicode": "\ue6cd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "smallcircle",
|
||||||
|
"unicode": "\ue67c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "smallcircle-filled",
|
||||||
|
"unicode": "\ue665"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "sound",
|
||||||
|
"unicode": "\ue684"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "sound-filled",
|
||||||
|
"unicode": "\ue686"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "spinner-cycle",
|
||||||
|
"unicode": "\ue68a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "staff",
|
||||||
|
"unicode": "\ue6a7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "staff-filled",
|
||||||
|
"unicode": "\ue6cb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "star",
|
||||||
|
"unicode": "\ue688"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "star-filled",
|
||||||
|
"unicode": "\ue68f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "starhalf",
|
||||||
|
"unicode": "\ue683"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "trash",
|
||||||
|
"unicode": "\ue687"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "trash-filled",
|
||||||
|
"unicode": "\ue685"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "tune",
|
||||||
|
"unicode": "\ue6aa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "tune-filled",
|
||||||
|
"unicode": "\ue6ca"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "undo",
|
||||||
|
"unicode": "\ue64f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "undo-filled",
|
||||||
|
"unicode": "\ue64c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "up",
|
||||||
|
"unicode": "\ue6b6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "top",
|
||||||
|
"unicode": "\ue6b6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "upload",
|
||||||
|
"unicode": "\ue690"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "upload-filled",
|
||||||
|
"unicode": "\ue68e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "videocam",
|
||||||
|
"unicode": "\ue68c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "videocam-filled",
|
||||||
|
"unicode": "\ue689"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "vip",
|
||||||
|
"unicode": "\ue6a8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "vip-filled",
|
||||||
|
"unicode": "\ue6c6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "wallet",
|
||||||
|
"unicode": "\ue6b1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "wallet-filled",
|
||||||
|
"unicode": "\ue6c2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "weibo",
|
||||||
|
"unicode": "\ue68b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "weixin",
|
||||||
|
"unicode": "\ue691"
|
||||||
|
}
|
||||||
|
] as IconsDataItem[]
|
||||||
|
|
||||||
|
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
|
649
uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
Normal file
649
uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
Normal file
|
@ -0,0 +1,649 @@
|
||||||
|
|
||||||
|
export const fontData = [
|
||||||
|
{
|
||||||
|
"font_class": "arrow-down",
|
||||||
|
"unicode": "\ue6be"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "arrow-left",
|
||||||
|
"unicode": "\ue6bc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "arrow-right",
|
||||||
|
"unicode": "\ue6bb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "arrow-up",
|
||||||
|
"unicode": "\ue6bd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "auth",
|
||||||
|
"unicode": "\ue6ab"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "auth-filled",
|
||||||
|
"unicode": "\ue6cc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "back",
|
||||||
|
"unicode": "\ue6b9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "bars",
|
||||||
|
"unicode": "\ue627"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "calendar",
|
||||||
|
"unicode": "\ue6a0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "calendar-filled",
|
||||||
|
"unicode": "\ue6c0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "camera",
|
||||||
|
"unicode": "\ue65a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "camera-filled",
|
||||||
|
"unicode": "\ue658"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cart",
|
||||||
|
"unicode": "\ue631"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cart-filled",
|
||||||
|
"unicode": "\ue6d0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chat",
|
||||||
|
"unicode": "\ue65d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chat-filled",
|
||||||
|
"unicode": "\ue659"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chatboxes",
|
||||||
|
"unicode": "\ue696"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chatboxes-filled",
|
||||||
|
"unicode": "\ue692"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chatbubble",
|
||||||
|
"unicode": "\ue697"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "chatbubble-filled",
|
||||||
|
"unicode": "\ue694"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "checkbox",
|
||||||
|
"unicode": "\ue62b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "checkbox-filled",
|
||||||
|
"unicode": "\ue62c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "checkmarkempty",
|
||||||
|
"unicode": "\ue65c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "circle",
|
||||||
|
"unicode": "\ue65b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "circle-filled",
|
||||||
|
"unicode": "\ue65e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "clear",
|
||||||
|
"unicode": "\ue66d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "close",
|
||||||
|
"unicode": "\ue673"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "closeempty",
|
||||||
|
"unicode": "\ue66c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cloud-download",
|
||||||
|
"unicode": "\ue647"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cloud-download-filled",
|
||||||
|
"unicode": "\ue646"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cloud-upload",
|
||||||
|
"unicode": "\ue645"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "cloud-upload-filled",
|
||||||
|
"unicode": "\ue648"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "color",
|
||||||
|
"unicode": "\ue6cf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "color-filled",
|
||||||
|
"unicode": "\ue6c9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "compose",
|
||||||
|
"unicode": "\ue67f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "contact",
|
||||||
|
"unicode": "\ue693"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "contact-filled",
|
||||||
|
"unicode": "\ue695"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "down",
|
||||||
|
"unicode": "\ue6b8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "bottom",
|
||||||
|
"unicode": "\ue6b8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "download",
|
||||||
|
"unicode": "\ue68d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "download-filled",
|
||||||
|
"unicode": "\ue681"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "email",
|
||||||
|
"unicode": "\ue69e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "email-filled",
|
||||||
|
"unicode": "\ue69a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "eye",
|
||||||
|
"unicode": "\ue651"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "eye-filled",
|
||||||
|
"unicode": "\ue66a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "eye-slash",
|
||||||
|
"unicode": "\ue6b3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "eye-slash-filled",
|
||||||
|
"unicode": "\ue6b4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "fire",
|
||||||
|
"unicode": "\ue6a1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "fire-filled",
|
||||||
|
"unicode": "\ue6c5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "flag",
|
||||||
|
"unicode": "\ue65f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "flag-filled",
|
||||||
|
"unicode": "\ue660"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "folder-add",
|
||||||
|
"unicode": "\ue6a9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "folder-add-filled",
|
||||||
|
"unicode": "\ue6c8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "font",
|
||||||
|
"unicode": "\ue6a3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "forward",
|
||||||
|
"unicode": "\ue6ba"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "gear",
|
||||||
|
"unicode": "\ue664"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "gear-filled",
|
||||||
|
"unicode": "\ue661"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "gift",
|
||||||
|
"unicode": "\ue6a4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "gift-filled",
|
||||||
|
"unicode": "\ue6c4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "hand-down",
|
||||||
|
"unicode": "\ue63d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "hand-down-filled",
|
||||||
|
"unicode": "\ue63c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "hand-up",
|
||||||
|
"unicode": "\ue63f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "hand-up-filled",
|
||||||
|
"unicode": "\ue63e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "headphones",
|
||||||
|
"unicode": "\ue630"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "heart",
|
||||||
|
"unicode": "\ue639"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "heart-filled",
|
||||||
|
"unicode": "\ue641"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "help",
|
||||||
|
"unicode": "\ue679"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "help-filled",
|
||||||
|
"unicode": "\ue674"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "home",
|
||||||
|
"unicode": "\ue662"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "home-filled",
|
||||||
|
"unicode": "\ue663"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "image",
|
||||||
|
"unicode": "\ue670"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "image-filled",
|
||||||
|
"unicode": "\ue678"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "images",
|
||||||
|
"unicode": "\ue650"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "images-filled",
|
||||||
|
"unicode": "\ue64b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "info",
|
||||||
|
"unicode": "\ue669"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "info-filled",
|
||||||
|
"unicode": "\ue649"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "left",
|
||||||
|
"unicode": "\ue6b7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "link",
|
||||||
|
"unicode": "\ue6a5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "list",
|
||||||
|
"unicode": "\ue644"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "location",
|
||||||
|
"unicode": "\ue6ae"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "location-filled",
|
||||||
|
"unicode": "\ue6af"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "locked",
|
||||||
|
"unicode": "\ue66b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "locked-filled",
|
||||||
|
"unicode": "\ue668"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "loop",
|
||||||
|
"unicode": "\ue633"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "mail-open",
|
||||||
|
"unicode": "\ue643"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "mail-open-filled",
|
||||||
|
"unicode": "\ue63a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "map",
|
||||||
|
"unicode": "\ue667"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "map-filled",
|
||||||
|
"unicode": "\ue666"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "map-pin",
|
||||||
|
"unicode": "\ue6ad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "map-pin-ellipse",
|
||||||
|
"unicode": "\ue6ac"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "medal",
|
||||||
|
"unicode": "\ue6a2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "medal-filled",
|
||||||
|
"unicode": "\ue6c3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "mic",
|
||||||
|
"unicode": "\ue671"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "mic-filled",
|
||||||
|
"unicode": "\ue677"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "micoff",
|
||||||
|
"unicode": "\ue67e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "micoff-filled",
|
||||||
|
"unicode": "\ue6b0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "minus",
|
||||||
|
"unicode": "\ue66f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "minus-filled",
|
||||||
|
"unicode": "\ue67d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "more",
|
||||||
|
"unicode": "\ue64d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "more-filled",
|
||||||
|
"unicode": "\ue64e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "navigate",
|
||||||
|
"unicode": "\ue66e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "navigate-filled",
|
||||||
|
"unicode": "\ue67a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "notification",
|
||||||
|
"unicode": "\ue6a6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "notification-filled",
|
||||||
|
"unicode": "\ue6c1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "paperclip",
|
||||||
|
"unicode": "\ue652"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "paperplane",
|
||||||
|
"unicode": "\ue672"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "paperplane-filled",
|
||||||
|
"unicode": "\ue675"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "person",
|
||||||
|
"unicode": "\ue699"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "person-filled",
|
||||||
|
"unicode": "\ue69d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "personadd",
|
||||||
|
"unicode": "\ue69f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "personadd-filled",
|
||||||
|
"unicode": "\ue698"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "personadd-filled-copy",
|
||||||
|
"unicode": "\ue6d1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "phone",
|
||||||
|
"unicode": "\ue69c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "phone-filled",
|
||||||
|
"unicode": "\ue69b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "plus",
|
||||||
|
"unicode": "\ue676"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "plus-filled",
|
||||||
|
"unicode": "\ue6c7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "plusempty",
|
||||||
|
"unicode": "\ue67b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "pulldown",
|
||||||
|
"unicode": "\ue632"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "pyq",
|
||||||
|
"unicode": "\ue682"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "qq",
|
||||||
|
"unicode": "\ue680"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "redo",
|
||||||
|
"unicode": "\ue64a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "redo-filled",
|
||||||
|
"unicode": "\ue655"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "refresh",
|
||||||
|
"unicode": "\ue657"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "refresh-filled",
|
||||||
|
"unicode": "\ue656"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "refreshempty",
|
||||||
|
"unicode": "\ue6bf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "reload",
|
||||||
|
"unicode": "\ue6b2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "right",
|
||||||
|
"unicode": "\ue6b5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "scan",
|
||||||
|
"unicode": "\ue62a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "search",
|
||||||
|
"unicode": "\ue654"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "settings",
|
||||||
|
"unicode": "\ue653"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "settings-filled",
|
||||||
|
"unicode": "\ue6ce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "shop",
|
||||||
|
"unicode": "\ue62f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "shop-filled",
|
||||||
|
"unicode": "\ue6cd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "smallcircle",
|
||||||
|
"unicode": "\ue67c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "smallcircle-filled",
|
||||||
|
"unicode": "\ue665"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "sound",
|
||||||
|
"unicode": "\ue684"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "sound-filled",
|
||||||
|
"unicode": "\ue686"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "spinner-cycle",
|
||||||
|
"unicode": "\ue68a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "staff",
|
||||||
|
"unicode": "\ue6a7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "staff-filled",
|
||||||
|
"unicode": "\ue6cb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "star",
|
||||||
|
"unicode": "\ue688"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "star-filled",
|
||||||
|
"unicode": "\ue68f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "starhalf",
|
||||||
|
"unicode": "\ue683"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "trash",
|
||||||
|
"unicode": "\ue687"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "trash-filled",
|
||||||
|
"unicode": "\ue685"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "tune",
|
||||||
|
"unicode": "\ue6aa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "tune-filled",
|
||||||
|
"unicode": "\ue6ca"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "undo",
|
||||||
|
"unicode": "\ue64f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "undo-filled",
|
||||||
|
"unicode": "\ue64c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "up",
|
||||||
|
"unicode": "\ue6b6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "top",
|
||||||
|
"unicode": "\ue6b6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "upload",
|
||||||
|
"unicode": "\ue690"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "upload-filled",
|
||||||
|
"unicode": "\ue68e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "videocam",
|
||||||
|
"unicode": "\ue68c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "videocam-filled",
|
||||||
|
"unicode": "\ue689"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "vip",
|
||||||
|
"unicode": "\ue6a8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "vip-filled",
|
||||||
|
"unicode": "\ue6c6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "wallet",
|
||||||
|
"unicode": "\ue6b1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "wallet-filled",
|
||||||
|
"unicode": "\ue6c2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "weibo",
|
||||||
|
"unicode": "\ue68b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"font_class": "weixin",
|
||||||
|
"unicode": "\ue691"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
|
89
uni_modules/uni-icons/package.json
Normal file
89
uni_modules/uni-icons/package.json
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
{
|
||||||
|
"id": "uni-icons",
|
||||||
|
"displayName": "uni-icons 图标",
|
||||||
|
"version": "2.0.10",
|
||||||
|
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"uniui",
|
||||||
|
"icon",
|
||||||
|
"图标"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.2.14"
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
|
||||||
|
"type": "component-vue"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": ["uni-scss"],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y",
|
||||||
|
"alipay": "n"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y",
|
||||||
|
"app-uvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y",
|
||||||
|
"钉钉": "y",
|
||||||
|
"快手": "y",
|
||||||
|
"飞书": "y",
|
||||||
|
"京东": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "y",
|
||||||
|
"联盟": "y"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
uni_modules/uni-icons/readme.md
Normal file
8
uni_modules/uni-icons/readme.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
## Icons 图标
|
||||||
|
> **组件名:uni-icons**
|
||||||
|
> 代码块: `uIcons`
|
||||||
|
|
||||||
|
用于展示 icons 图标 。
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
8
uni_modules/uni-scss/changelog.md
Normal file
8
uni_modules/uni-scss/changelog.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
## 1.0.3(2022-01-21)
|
||||||
|
- 优化 组件示例
|
||||||
|
## 1.0.2(2021-11-22)
|
||||||
|
- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
|
||||||
|
## 1.0.1(2021-11-22)
|
||||||
|
- 修复 vue3中scss语法兼容问题
|
||||||
|
## 1.0.0(2021-11-18)
|
||||||
|
- init
|
1
uni_modules/uni-scss/index.scss
Normal file
1
uni_modules/uni-scss/index.scss
Normal file
|
@ -0,0 +1 @@
|
||||||
|
@import './styles/index.scss';
|
82
uni_modules/uni-scss/package.json
Normal file
82
uni_modules/uni-scss/package.json
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
{
|
||||||
|
"id": "uni-scss",
|
||||||
|
"displayName": "uni-scss 辅助样式",
|
||||||
|
"version": "1.0.3",
|
||||||
|
"description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
|
||||||
|
"keywords": [
|
||||||
|
"uni-scss",
|
||||||
|
"uni-ui",
|
||||||
|
"辅助样式"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"category": [
|
||||||
|
"JS SDK",
|
||||||
|
"通用 SDK"
|
||||||
|
],
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "u"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "n",
|
||||||
|
"联盟": "n"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
uni_modules/uni-scss/readme.md
Normal file
4
uni_modules/uni-scss/readme.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
7
uni_modules/uni-scss/styles/index.scss
Normal file
7
uni_modules/uni-scss/styles/index.scss
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
@import './setting/_variables.scss';
|
||||||
|
@import './setting/_border.scss';
|
||||||
|
@import './setting/_color.scss';
|
||||||
|
@import './setting/_space.scss';
|
||||||
|
@import './setting/_radius.scss';
|
||||||
|
@import './setting/_text.scss';
|
||||||
|
@import './setting/_styles.scss';
|
3
uni_modules/uni-scss/styles/setting/_border.scss
Normal file
3
uni_modules/uni-scss/styles/setting/_border.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.uni-border {
|
||||||
|
border: 1px $uni-border-1 solid;
|
||||||
|
}
|
66
uni_modules/uni-scss/styles/setting/_color.scss
Normal file
66
uni_modules/uni-scss/styles/setting/_color.scss
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
|
||||||
|
// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
|
||||||
|
// @mixin get-styles($k,$c) {
|
||||||
|
// @if $k == size or $k == weight{
|
||||||
|
// font-#{$k}:#{$c}
|
||||||
|
// }@else{
|
||||||
|
// #{$k}:#{$c}
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
$uni-ui-color:(
|
||||||
|
// 主色
|
||||||
|
primary: $uni-primary,
|
||||||
|
primary-disable: $uni-primary-disable,
|
||||||
|
primary-light: $uni-primary-light,
|
||||||
|
// 辅助色
|
||||||
|
success: $uni-success,
|
||||||
|
success-disable: $uni-success-disable,
|
||||||
|
success-light: $uni-success-light,
|
||||||
|
warning: $uni-warning,
|
||||||
|
warning-disable: $uni-warning-disable,
|
||||||
|
warning-light: $uni-warning-light,
|
||||||
|
error: $uni-error,
|
||||||
|
error-disable: $uni-error-disable,
|
||||||
|
error-light: $uni-error-light,
|
||||||
|
info: $uni-info,
|
||||||
|
info-disable: $uni-info-disable,
|
||||||
|
info-light: $uni-info-light,
|
||||||
|
// 中性色
|
||||||
|
main-color: $uni-main-color,
|
||||||
|
base-color: $uni-base-color,
|
||||||
|
secondary-color: $uni-secondary-color,
|
||||||
|
extra-color: $uni-extra-color,
|
||||||
|
// 背景色
|
||||||
|
bg-color: $uni-bg-color,
|
||||||
|
// 边框颜色
|
||||||
|
border-1: $uni-border-1,
|
||||||
|
border-2: $uni-border-2,
|
||||||
|
border-3: $uni-border-3,
|
||||||
|
border-4: $uni-border-4,
|
||||||
|
// 黑色
|
||||||
|
black:$uni-black,
|
||||||
|
// 白色
|
||||||
|
white:$uni-white,
|
||||||
|
// 透明
|
||||||
|
transparent:$uni-transparent
|
||||||
|
) !default;
|
||||||
|
@each $key, $child in $uni-ui-color {
|
||||||
|
.uni-#{"" + $key} {
|
||||||
|
color: $child;
|
||||||
|
}
|
||||||
|
.uni-#{"" + $key}-bg {
|
||||||
|
background-color: $child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.uni-shadow-sm {
|
||||||
|
box-shadow: $uni-shadow-sm;
|
||||||
|
}
|
||||||
|
.uni-shadow-base {
|
||||||
|
box-shadow: $uni-shadow-base;
|
||||||
|
}
|
||||||
|
.uni-shadow-lg {
|
||||||
|
box-shadow: $uni-shadow-lg;
|
||||||
|
}
|
||||||
|
.uni-mask {
|
||||||
|
background-color:$uni-mask;
|
||||||
|
}
|
55
uni_modules/uni-scss/styles/setting/_radius.scss
Normal file
55
uni_modules/uni-scss/styles/setting/_radius.scss
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
@mixin radius($r,$d:null ,$important: false){
|
||||||
|
$radius-value:map-get($uni-radius, $r) if($important, !important, null);
|
||||||
|
// Key exists within the $uni-radius variable
|
||||||
|
@if (map-has-key($uni-radius, $r) and $d){
|
||||||
|
@if $d == t {
|
||||||
|
border-top-left-radius:$radius-value;
|
||||||
|
border-top-right-radius:$radius-value;
|
||||||
|
}@else if $d == r {
|
||||||
|
border-top-right-radius:$radius-value;
|
||||||
|
border-bottom-right-radius:$radius-value;
|
||||||
|
}@else if $d == b {
|
||||||
|
border-bottom-left-radius:$radius-value;
|
||||||
|
border-bottom-right-radius:$radius-value;
|
||||||
|
}@else if $d == l {
|
||||||
|
border-top-left-radius:$radius-value;
|
||||||
|
border-bottom-left-radius:$radius-value;
|
||||||
|
}@else if $d == tl {
|
||||||
|
border-top-left-radius:$radius-value;
|
||||||
|
}@else if $d == tr {
|
||||||
|
border-top-right-radius:$radius-value;
|
||||||
|
}@else if $d == br {
|
||||||
|
border-bottom-right-radius:$radius-value;
|
||||||
|
}@else if $d == bl {
|
||||||
|
border-bottom-left-radius:$radius-value;
|
||||||
|
}
|
||||||
|
}@else{
|
||||||
|
border-radius:$radius-value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $key, $child in $uni-radius {
|
||||||
|
@if($key){
|
||||||
|
.uni-radius-#{"" + $key} {
|
||||||
|
@include radius($key)
|
||||||
|
}
|
||||||
|
}@else{
|
||||||
|
.uni-radius {
|
||||||
|
@include radius($key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $direction in t, r, b, l,tl, tr, br, bl {
|
||||||
|
@each $key, $child in $uni-radius {
|
||||||
|
@if($key){
|
||||||
|
.uni-radius-#{"" + $direction}-#{"" + $key} {
|
||||||
|
@include radius($key,$direction,false)
|
||||||
|
}
|
||||||
|
}@else{
|
||||||
|
.uni-radius-#{$direction} {
|
||||||
|
@include radius($key,$direction,false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
uni_modules/uni-scss/styles/setting/_space.scss
Normal file
56
uni_modules/uni-scss/styles/setting/_space.scss
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
|
||||||
|
@mixin fn($space,$direction,$size,$n) {
|
||||||
|
@if $n {
|
||||||
|
#{$space}-#{$direction}: #{$size*$uni-space-root}px
|
||||||
|
} @else {
|
||||||
|
#{$space}-#{$direction}: #{-$size*$uni-space-root}px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin get-styles($direction,$i,$space,$n){
|
||||||
|
@if $direction == t {
|
||||||
|
@include fn($space, top,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == r {
|
||||||
|
@include fn($space, right,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == b {
|
||||||
|
@include fn($space, bottom,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == l {
|
||||||
|
@include fn($space, left,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == x {
|
||||||
|
@include fn($space, left,$i,$n);
|
||||||
|
@include fn($space, right,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == y {
|
||||||
|
@include fn($space, top,$i,$n);
|
||||||
|
@include fn($space, bottom,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == a {
|
||||||
|
@if $n {
|
||||||
|
#{$space}:#{$i*$uni-space-root}px;
|
||||||
|
} @else {
|
||||||
|
#{$space}:#{-$i*$uni-space-root}px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $orientation in m,p {
|
||||||
|
$space: margin;
|
||||||
|
@if $orientation == m {
|
||||||
|
$space: margin;
|
||||||
|
} @else {
|
||||||
|
$space: padding;
|
||||||
|
}
|
||||||
|
@for $i from 0 through 16 {
|
||||||
|
@each $direction in t, r, b, l, x, y, a {
|
||||||
|
.uni-#{$orientation}#{$direction}-#{$i} {
|
||||||
|
@include get-styles($direction,$i,$space,true);
|
||||||
|
}
|
||||||
|
.uni-#{$orientation}#{$direction}-n#{$i} {
|
||||||
|
@include get-styles($direction,$i,$space,false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
167
uni_modules/uni-scss/styles/setting/_styles.scss
Normal file
167
uni_modules/uni-scss/styles/setting/_styles.scss
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
|
||||||
|
$-color-white:#fff;
|
||||||
|
$-color-black:#000;
|
||||||
|
@mixin base-style($color) {
|
||||||
|
color: #fff;
|
||||||
|
background-color: $color;
|
||||||
|
border-color: mix($-color-black, $color, 8%);
|
||||||
|
&:not([hover-class]):active {
|
||||||
|
background: mix($-color-black, $color, 10%);
|
||||||
|
border-color: mix($-color-black, $color, 20%);
|
||||||
|
color: $-color-white;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin is-color($color) {
|
||||||
|
@include base-style($color);
|
||||||
|
&[loading] {
|
||||||
|
@include base-style($color);
|
||||||
|
&::before {
|
||||||
|
margin-right:5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&[disabled] {
|
||||||
|
&,
|
||||||
|
&[loading],
|
||||||
|
&:not([hover-class]):active {
|
||||||
|
color: $-color-white;
|
||||||
|
border-color: mix(darken($color,10%), $-color-white);
|
||||||
|
background-color: mix($color, $-color-white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@mixin base-plain-style($color) {
|
||||||
|
color:$color;
|
||||||
|
background-color: mix($-color-white, $color, 90%);
|
||||||
|
border-color: mix($-color-white, $color, 70%);
|
||||||
|
&:not([hover-class]):active {
|
||||||
|
background: mix($-color-white, $color, 80%);
|
||||||
|
color: $color;
|
||||||
|
outline: none;
|
||||||
|
border-color: mix($-color-white, $color, 50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin is-plain($color){
|
||||||
|
&[plain] {
|
||||||
|
@include base-plain-style($color);
|
||||||
|
&[loading] {
|
||||||
|
@include base-plain-style($color);
|
||||||
|
&::before {
|
||||||
|
margin-right:5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&[disabled] {
|
||||||
|
&,
|
||||||
|
&:active {
|
||||||
|
color: mix($-color-white, $color, 40%);
|
||||||
|
background-color: mix($-color-white, $color, 90%);
|
||||||
|
border-color: mix($-color-white, $color, 80%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.uni-btn {
|
||||||
|
margin: 5px;
|
||||||
|
color: #393939;
|
||||||
|
border:1px solid #ccc;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 200;
|
||||||
|
background-color: #F9F9F9;
|
||||||
|
// TODO 暂时处理边框隐藏一边的问题
|
||||||
|
overflow: visible;
|
||||||
|
&::after{
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not([type]),&[type=default] {
|
||||||
|
color: #999;
|
||||||
|
&[loading] {
|
||||||
|
background: none;
|
||||||
|
&::before {
|
||||||
|
margin-right:5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&[disabled]{
|
||||||
|
color: mix($-color-white, #999, 60%);
|
||||||
|
&,
|
||||||
|
&[loading],
|
||||||
|
&:active {
|
||||||
|
color: mix($-color-white, #999, 60%);
|
||||||
|
background-color: mix($-color-white,$-color-black , 98%);
|
||||||
|
border-color: mix($-color-white, #999, 85%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[plain] {
|
||||||
|
color: #999;
|
||||||
|
background: none;
|
||||||
|
border-color: $uni-border-1;
|
||||||
|
&:not([hover-class]):active {
|
||||||
|
background: none;
|
||||||
|
color: mix($-color-white, $-color-black, 80%);
|
||||||
|
border-color: mix($-color-white, $-color-black, 90%);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
&[disabled]{
|
||||||
|
&,
|
||||||
|
&[loading],
|
||||||
|
&:active {
|
||||||
|
background: none;
|
||||||
|
color: mix($-color-white, #999, 60%);
|
||||||
|
border-color: mix($-color-white, #999, 85%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not([hover-class]):active {
|
||||||
|
color: mix($-color-white, $-color-black, 50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[size=mini] {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 200;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&.uni-btn-small {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
&.uni-btn-mini {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.uni-btn-radius {
|
||||||
|
border-radius: 999px;
|
||||||
|
}
|
||||||
|
&[type=primary] {
|
||||||
|
@include is-color($uni-primary);
|
||||||
|
@include is-plain($uni-primary)
|
||||||
|
}
|
||||||
|
&[type=success] {
|
||||||
|
@include is-color($uni-success);
|
||||||
|
@include is-plain($uni-success)
|
||||||
|
}
|
||||||
|
&[type=error] {
|
||||||
|
@include is-color($uni-error);
|
||||||
|
@include is-plain($uni-error)
|
||||||
|
}
|
||||||
|
&[type=warning] {
|
||||||
|
@include is-color($uni-warning);
|
||||||
|
@include is-plain($uni-warning)
|
||||||
|
}
|
||||||
|
&[type=info] {
|
||||||
|
@include is-color($uni-info);
|
||||||
|
@include is-plain($uni-info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
24
uni_modules/uni-scss/styles/setting/_text.scss
Normal file
24
uni_modules/uni-scss/styles/setting/_text.scss
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
@mixin get-styles($k,$c) {
|
||||||
|
@if $k == size or $k == weight{
|
||||||
|
font-#{$k}:#{$c}
|
||||||
|
}@else{
|
||||||
|
#{$k}:#{$c}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $key, $child in $uni-headings {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
.uni-#{$key} {
|
||||||
|
@each $k, $c in $child {
|
||||||
|
@include get-styles($k,$c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
.container .uni-#{$key} {
|
||||||
|
@each $k, $c in $child {
|
||||||
|
@include get-styles($k,$c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
}
|
146
uni_modules/uni-scss/styles/setting/_variables.scss
Normal file
146
uni_modules/uni-scss/styles/setting/_variables.scss
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
// @use "sass:math";
|
||||||
|
@import '../tools/functions.scss';
|
||||||
|
// 间距基础倍数
|
||||||
|
$uni-space-root: 2 !default;
|
||||||
|
// 边框半径默认值
|
||||||
|
$uni-radius-root:5px !default;
|
||||||
|
$uni-radius: () !default;
|
||||||
|
// 边框半径断点
|
||||||
|
$uni-radius: map-deep-merge(
|
||||||
|
(
|
||||||
|
0: 0,
|
||||||
|
// TODO 当前版本暂时不支持 sm 属性
|
||||||
|
// 'sm': math.div($uni-radius-root, 2),
|
||||||
|
null: $uni-radius-root,
|
||||||
|
'lg': $uni-radius-root * 2,
|
||||||
|
'xl': $uni-radius-root * 6,
|
||||||
|
'pill': 9999px,
|
||||||
|
'circle': 50%
|
||||||
|
),
|
||||||
|
$uni-radius
|
||||||
|
);
|
||||||
|
// 字体家族
|
||||||
|
$body-font-family: 'Roboto', sans-serif !default;
|
||||||
|
// 文本
|
||||||
|
$heading-font-family: $body-font-family !default;
|
||||||
|
$uni-headings: () !default;
|
||||||
|
$letterSpacing: -0.01562em;
|
||||||
|
$uni-headings: map-deep-merge(
|
||||||
|
(
|
||||||
|
'h1': (
|
||||||
|
size: 32px,
|
||||||
|
weight: 300,
|
||||||
|
line-height: 50px,
|
||||||
|
// letter-spacing:-0.01562em
|
||||||
|
),
|
||||||
|
'h2': (
|
||||||
|
size: 28px,
|
||||||
|
weight: 300,
|
||||||
|
line-height: 40px,
|
||||||
|
// letter-spacing: -0.00833em
|
||||||
|
),
|
||||||
|
'h3': (
|
||||||
|
size: 24px,
|
||||||
|
weight: 400,
|
||||||
|
line-height: 32px,
|
||||||
|
// letter-spacing: normal
|
||||||
|
),
|
||||||
|
'h4': (
|
||||||
|
size: 20px,
|
||||||
|
weight: 400,
|
||||||
|
line-height: 30px,
|
||||||
|
// letter-spacing: 0.00735em
|
||||||
|
),
|
||||||
|
'h5': (
|
||||||
|
size: 16px,
|
||||||
|
weight: 400,
|
||||||
|
line-height: 24px,
|
||||||
|
// letter-spacing: normal
|
||||||
|
),
|
||||||
|
'h6': (
|
||||||
|
size: 14px,
|
||||||
|
weight: 500,
|
||||||
|
line-height: 18px,
|
||||||
|
// letter-spacing: 0.0125em
|
||||||
|
),
|
||||||
|
'subtitle': (
|
||||||
|
size: 12px,
|
||||||
|
weight: 400,
|
||||||
|
line-height: 20px,
|
||||||
|
// letter-spacing: 0.00937em
|
||||||
|
),
|
||||||
|
'body': (
|
||||||
|
font-size: 14px,
|
||||||
|
font-weight: 400,
|
||||||
|
line-height: 22px,
|
||||||
|
// letter-spacing: 0.03125em
|
||||||
|
),
|
||||||
|
'caption': (
|
||||||
|
'size': 12px,
|
||||||
|
'weight': 400,
|
||||||
|
'line-height': 20px,
|
||||||
|
// 'letter-spacing': 0.03333em,
|
||||||
|
// 'text-transform': false
|
||||||
|
)
|
||||||
|
),
|
||||||
|
$uni-headings
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 主色
|
||||||
|
$uni-primary: #2979ff !default;
|
||||||
|
$uni-primary-disable:lighten($uni-primary,20%) !default;
|
||||||
|
$uni-primary-light: lighten($uni-primary,25%) !default;
|
||||||
|
|
||||||
|
// 辅助色
|
||||||
|
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||||
|
$uni-success: #18bc37 !default;
|
||||||
|
$uni-success-disable:lighten($uni-success,20%) !default;
|
||||||
|
$uni-success-light: lighten($uni-success,25%) !default;
|
||||||
|
|
||||||
|
$uni-warning: #f3a73f !default;
|
||||||
|
$uni-warning-disable:lighten($uni-warning,20%) !default;
|
||||||
|
$uni-warning-light: lighten($uni-warning,25%) !default;
|
||||||
|
|
||||||
|
$uni-error: #e43d33 !default;
|
||||||
|
$uni-error-disable:lighten($uni-error,20%) !default;
|
||||||
|
$uni-error-light: lighten($uni-error,25%) !default;
|
||||||
|
|
||||||
|
$uni-info: #8f939c !default;
|
||||||
|
$uni-info-disable:lighten($uni-info,20%) !default;
|
||||||
|
$uni-info-light: lighten($uni-info,25%) !default;
|
||||||
|
|
||||||
|
// 中性色
|
||||||
|
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||||
|
$uni-main-color: #3a3a3a !default; // 主要文字
|
||||||
|
$uni-base-color: #6a6a6a !default; // 常规文字
|
||||||
|
$uni-secondary-color: #909399 !default; // 次要文字
|
||||||
|
$uni-extra-color: #c7c7c7 !default; // 辅助说明
|
||||||
|
|
||||||
|
// 边框颜色
|
||||||
|
$uni-border-1: #F0F0F0 !default;
|
||||||
|
$uni-border-2: #EDEDED !default;
|
||||||
|
$uni-border-3: #DCDCDC !default;
|
||||||
|
$uni-border-4: #B9B9B9 !default;
|
||||||
|
|
||||||
|
// 常规色
|
||||||
|
$uni-black: #000000 !default;
|
||||||
|
$uni-white: #ffffff !default;
|
||||||
|
$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
|
||||||
|
|
||||||
|
// 背景色
|
||||||
|
$uni-bg-color: #f7f7f7 !default;
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
$uni-spacing-sm: 8px !default;
|
||||||
|
$uni-spacing-base: 15px !default;
|
||||||
|
$uni-spacing-lg: 30px !default;
|
||||||
|
|
||||||
|
// 阴影
|
||||||
|
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
|
||||||
|
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
|
||||||
|
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
|
||||||
|
|
||||||
|
// 蒙版
|
||||||
|
$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
|
19
uni_modules/uni-scss/styles/tools/functions.scss
Normal file
19
uni_modules/uni-scss/styles/tools/functions.scss
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// 合并 map
|
||||||
|
@function map-deep-merge($parent-map, $child-map){
|
||||||
|
$result: $parent-map;
|
||||||
|
@each $key, $child in $child-map {
|
||||||
|
$parent-has-key: map-has-key($result, $key);
|
||||||
|
$parent-value: map-get($result, $key);
|
||||||
|
$parent-type: type-of($parent-value);
|
||||||
|
$child-type: type-of($child);
|
||||||
|
$parent-is-map: $parent-type == map;
|
||||||
|
$child-is-map: $child-type == map;
|
||||||
|
|
||||||
|
@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
|
||||||
|
$result: map-merge($result, ( $key: $child ));
|
||||||
|
}@else {
|
||||||
|
$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@return $result;
|
||||||
|
};
|
31
uni_modules/uni-scss/theme.scss
Normal file
31
uni_modules/uni-scss/theme.scss
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// 间距基础倍数
|
||||||
|
$uni-space-root: 2;
|
||||||
|
// 边框半径默认值
|
||||||
|
$uni-radius-root:5px;
|
||||||
|
// 主色
|
||||||
|
$uni-primary: #2979ff;
|
||||||
|
// 辅助色
|
||||||
|
$uni-success: #4cd964;
|
||||||
|
// 警告色
|
||||||
|
$uni-warning: #f0ad4e;
|
||||||
|
// 错误色
|
||||||
|
$uni-error: #dd524d;
|
||||||
|
// 描述色
|
||||||
|
$uni-info: #909399;
|
||||||
|
// 中性色
|
||||||
|
$uni-main-color: #303133;
|
||||||
|
$uni-base-color: #606266;
|
||||||
|
$uni-secondary-color: #909399;
|
||||||
|
$uni-extra-color: #C0C4CC;
|
||||||
|
// 背景色
|
||||||
|
$uni-bg-color: #f5f5f5;
|
||||||
|
// 边框颜色
|
||||||
|
$uni-border-1: #DCDFE6;
|
||||||
|
$uni-border-2: #E4E7ED;
|
||||||
|
$uni-border-3: #EBEEF5;
|
||||||
|
$uni-border-4: #F2F6FC;
|
||||||
|
|
||||||
|
// 常规色
|
||||||
|
$uni-black: #000000;
|
||||||
|
$uni-white: #ffffff;
|
||||||
|
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
62
uni_modules/uni-scss/variables.scss
Normal file
62
uni_modules/uni-scss/variables.scss
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
@import './styles/setting/_variables.scss';
|
||||||
|
// 间距基础倍数
|
||||||
|
$uni-space-root: 2;
|
||||||
|
// 边框半径默认值
|
||||||
|
$uni-radius-root:5px;
|
||||||
|
|
||||||
|
// 主色
|
||||||
|
$uni-primary: #2979ff;
|
||||||
|
$uni-primary-disable:mix(#fff,$uni-primary,50%);
|
||||||
|
$uni-primary-light: mix(#fff,$uni-primary,80%);
|
||||||
|
|
||||||
|
// 辅助色
|
||||||
|
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||||
|
$uni-success: #18bc37;
|
||||||
|
$uni-success-disable:mix(#fff,$uni-success,50%);
|
||||||
|
$uni-success-light: mix(#fff,$uni-success,80%);
|
||||||
|
|
||||||
|
$uni-warning: #f3a73f;
|
||||||
|
$uni-warning-disable:mix(#fff,$uni-warning,50%);
|
||||||
|
$uni-warning-light: mix(#fff,$uni-warning,80%);
|
||||||
|
|
||||||
|
$uni-error: #e43d33;
|
||||||
|
$uni-error-disable:mix(#fff,$uni-error,50%);
|
||||||
|
$uni-error-light: mix(#fff,$uni-error,80%);
|
||||||
|
|
||||||
|
$uni-info: #8f939c;
|
||||||
|
$uni-info-disable:mix(#fff,$uni-info,50%);
|
||||||
|
$uni-info-light: mix(#fff,$uni-info,80%);
|
||||||
|
|
||||||
|
// 中性色
|
||||||
|
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||||
|
$uni-main-color: #3a3a3a; // 主要文字
|
||||||
|
$uni-base-color: #6a6a6a; // 常规文字
|
||||||
|
$uni-secondary-color: #909399; // 次要文字
|
||||||
|
$uni-extra-color: #c7c7c7; // 辅助说明
|
||||||
|
|
||||||
|
// 边框颜色
|
||||||
|
$uni-border-1: #F0F0F0;
|
||||||
|
$uni-border-2: #EDEDED;
|
||||||
|
$uni-border-3: #DCDCDC;
|
||||||
|
$uni-border-4: #B9B9B9;
|
||||||
|
|
||||||
|
// 常规色
|
||||||
|
$uni-black: #000000;
|
||||||
|
$uni-white: #ffffff;
|
||||||
|
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
||||||
|
|
||||||
|
// 背景色
|
||||||
|
$uni-bg-color: #f7f7f7;
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
$uni-spacing-sm: 8px;
|
||||||
|
$uni-spacing-base: 15px;
|
||||||
|
$uni-spacing-lg: 30px;
|
||||||
|
|
||||||
|
// 阴影
|
||||||
|
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
|
||||||
|
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
|
||||||
|
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
|
||||||
|
|
||||||
|
// 蒙版
|
||||||
|
$uni-mask: rgba($color: #000000, $alpha: 0.4);
|
47
uni_modules/uni-search-bar/changelog.md
Normal file
47
uni_modules/uni-search-bar/changelog.md
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
## 1.3.0(2024-04-22)
|
||||||
|
- 修复 textColor默认值导致的文字不显示的bug
|
||||||
|
## 1.2.9(2024-04-17)
|
||||||
|
- 修复 textColor不生效的bug
|
||||||
|
## 1.2.8(2024-02-22)
|
||||||
|
- 修复 清空按钮emit值错误的bug
|
||||||
|
## 1.2.7(2024-02-21)
|
||||||
|
- 新增 设置输入框字体颜色:textColor
|
||||||
|
## 1.2.6(2024-02-20)
|
||||||
|
- 修复 uni-search-bar在支付宝小程序下样式兼容问题
|
||||||
|
## 1.2.5(2024-01-31)
|
||||||
|
- 修复 uni-search-bar居中问题,现在默认居左,并修复样式偏移问题
|
||||||
|
## 1.2.4(2023-05-09)
|
||||||
|
- 修复 i18n 国际化不正确的 Bug
|
||||||
|
## 1.2.3(2022-05-24)
|
||||||
|
- 新增 readonly 属性,组件只读
|
||||||
|
## 1.2.2(2022-05-06)
|
||||||
|
- 修复 vue3 input 事件不生效的bug
|
||||||
|
## 1.2.1(2022-05-06)
|
||||||
|
- 修复 多余代码导致的bug
|
||||||
|
## 1.2.0(2021-11-19)
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-search-bar](https://uniapp.dcloud.io/component/uniui/uni-search-bar)
|
||||||
|
## 1.1.2(2021-08-30)
|
||||||
|
- 修复 value 属性与 modelValue 属性不兼容的Bug
|
||||||
|
## 1.1.1(2021-08-24)
|
||||||
|
- 新增 支持国际化
|
||||||
|
## 1.1.0(2021-07-30)
|
||||||
|
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 1.0.9(2021-05-12)
|
||||||
|
- 新增 项目示例地址
|
||||||
|
## 1.0.8(2021-04-21)
|
||||||
|
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
|
||||||
|
## 1.0.7(2021-04-15)
|
||||||
|
- uni-ui 新增 uni-search-bar 的 focus 事件
|
||||||
|
|
||||||
|
## 1.0.6(2021-02-05)
|
||||||
|
- 优化 组件引用关系,通过uni_modules引用组件
|
||||||
|
|
||||||
|
## 1.0.5(2021-02-05)
|
||||||
|
- 调整为uni_modules目录规范
|
||||||
|
- 新增 支持双向绑定
|
||||||
|
- 更改 input 事件的返回值,e={value:Number} --> e=value
|
||||||
|
- 新增 支持图标插槽
|
||||||
|
- 新增 支持 clear、blur 事件
|
||||||
|
- 新增 支持 focus 属性
|
||||||
|
- 去掉组件背景色
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"uni-search-bar.cancel": "cancel",
|
||||||
|
"uni-search-bar.placeholder": "Search enter content"
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
import en from './en.json'
|
||||||
|
import zhHans from './zh-Hans.json'
|
||||||
|
import zhHant from './zh-Hant.json'
|
||||||
|
export default {
|
||||||
|
en,
|
||||||
|
'zh-Hans': zhHans,
|
||||||
|
'zh-Hant': zhHant
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"uni-search-bar.cancel": "取消",
|
||||||
|
"uni-search-bar.placeholder": "请输入搜索内容"
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"uni-search-bar.cancel": "取消",
|
||||||
|
"uni-search-bar.placeholder": "請輸入搜索內容"
|
||||||
|
}
|
|
@ -0,0 +1,309 @@
|
||||||
|
<template>
|
||||||
|
<view class="uni-searchbar">
|
||||||
|
<view :style="{borderRadius:radius+'px',backgroundColor: bgColor}" class="uni-searchbar__box"
|
||||||
|
@click="searchClick">
|
||||||
|
<view class="uni-searchbar__box-icon-search">
|
||||||
|
<slot name="searchIcon">
|
||||||
|
<uni-icons color="#c0c4cc" size="18" type="search" />
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<input v-if="show || searchVal" :focus="showSync" :disabled="readonly" :placeholder="placeholderText" :maxlength="maxlength"
|
||||||
|
class="uni-searchbar__box-search-input" confirm-type="search" type="text" v-model="searchVal" :style="{color:textColor}"
|
||||||
|
@confirm="confirm" @blur="blur" @focus="emitFocus"/>
|
||||||
|
<text v-else class="uni-searchbar__text-placeholder">{{ placeholder }}</text>
|
||||||
|
<view v-if="show && (clearButton==='always'||clearButton==='auto'&&searchVal!=='') &&!readonly"
|
||||||
|
class="uni-searchbar__box-icon-clear" @click="clear">
|
||||||
|
<slot name="clearIcon">
|
||||||
|
<uni-icons color="#c0c4cc" size="20" type="clear" />
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<text @click="cancel" class="uni-searchbar__cancel"
|
||||||
|
v-if="cancelButton ==='always' || show && cancelButton ==='auto'">{{cancelTextI18n}}</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
initVueI18n
|
||||||
|
} from '@dcloudio/uni-i18n'
|
||||||
|
import messages from './i18n/index.js'
|
||||||
|
const {
|
||||||
|
t
|
||||||
|
} = initVueI18n(messages)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SearchBar 搜索栏
|
||||||
|
* @description 搜索栏组件,通常用于搜索商品、文章等
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=866
|
||||||
|
* @property {Number} radius 搜索栏圆角
|
||||||
|
* @property {Number} maxlength 输入最大长度
|
||||||
|
* @property {String} placeholder 搜索栏Placeholder
|
||||||
|
* @property {String} clearButton = [always|auto|none] 是否显示清除按钮
|
||||||
|
* @value always 一直显示
|
||||||
|
* @value auto 输入框不为空时显示
|
||||||
|
* @value none 一直不显示
|
||||||
|
* @property {String} cancelButton = [always|auto|none] 是否显示取消按钮
|
||||||
|
* @value always 一直显示
|
||||||
|
* @value auto 输入框不为空时显示
|
||||||
|
* @value none 一直不显示
|
||||||
|
* @property {String} cancelText 取消按钮的文字
|
||||||
|
* @property {String} bgColor 输入框背景颜色
|
||||||
|
* @property {String} textColor 输入文字颜色
|
||||||
|
* @property {Boolean} focus 是否自动聚焦
|
||||||
|
* @property {Boolean} readonly 组件只读,不能有任何操作,只做展示
|
||||||
|
* @event {Function} confirm uniSearchBar 的输入框 confirm 事件,返回参数为uniSearchBar的value,e={value:Number}
|
||||||
|
* @event {Function} input uniSearchBar 的 value 改变时触发事件,返回参数为uniSearchBar的value,e=value
|
||||||
|
* @event {Function} cancel 点击取消按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
|
||||||
|
* @event {Function} clear 点击清除按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
|
||||||
|
* @event {Function} blur input失去焦点时触发事件,返回参数为uniSearchBar的value,e={value:Number}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "UniSearchBar",
|
||||||
|
emits: ['input', 'update:modelValue', 'clear', 'cancel', 'confirm', 'blur', 'focus'],
|
||||||
|
props: {
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
radius: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 5
|
||||||
|
},
|
||||||
|
clearButton: {
|
||||||
|
type: String,
|
||||||
|
default: "auto"
|
||||||
|
},
|
||||||
|
cancelButton: {
|
||||||
|
type: String,
|
||||||
|
default: "auto"
|
||||||
|
},
|
||||||
|
cancelText: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
bgColor: {
|
||||||
|
type: String,
|
||||||
|
default: "#F8F8F8"
|
||||||
|
},
|
||||||
|
textColor: {
|
||||||
|
type: String,
|
||||||
|
default: "#000000"
|
||||||
|
},
|
||||||
|
maxlength: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 100
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
focus: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show: false,
|
||||||
|
showSync: false,
|
||||||
|
searchVal: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
cancelTextI18n() {
|
||||||
|
return this.cancelText || t("uni-search-bar.cancel")
|
||||||
|
},
|
||||||
|
placeholderText() {
|
||||||
|
return this.placeholder || t("uni-search-bar.placeholder")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// #ifndef VUE3
|
||||||
|
value: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newVal) {
|
||||||
|
this.searchVal = newVal
|
||||||
|
if (newVal) {
|
||||||
|
this.show = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newVal) {
|
||||||
|
this.searchVal = newVal
|
||||||
|
if (newVal) {
|
||||||
|
this.show = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
focus: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newVal) {
|
||||||
|
if (newVal) {
|
||||||
|
if(this.readonly) return
|
||||||
|
this.show = true;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.showSync = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
searchVal(newVal, oldVal) {
|
||||||
|
this.$emit("input", newVal)
|
||||||
|
// #ifdef VUE3
|
||||||
|
this.$emit("update:modelValue", newVal)
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
searchClick() {
|
||||||
|
if(this.readonly) return
|
||||||
|
if (this.show) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.show = true;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.showSync = true
|
||||||
|
})
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
this.searchVal = ""
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$emit("clear", { value: "" })
|
||||||
|
})
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
if(this.readonly) return
|
||||||
|
this.$emit("cancel", {
|
||||||
|
value: this.searchVal
|
||||||
|
});
|
||||||
|
this.searchVal = ""
|
||||||
|
this.show = false
|
||||||
|
this.showSync = false
|
||||||
|
// #ifndef APP-PLUS
|
||||||
|
uni.hideKeyboard()
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
plus.key.hideSoftKeybord()
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
confirm() {
|
||||||
|
// #ifndef APP-PLUS
|
||||||
|
uni.hideKeyboard();
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
plus.key.hideSoftKeybord()
|
||||||
|
// #endif
|
||||||
|
this.$emit("confirm", {
|
||||||
|
value: this.searchVal
|
||||||
|
})
|
||||||
|
},
|
||||||
|
blur() {
|
||||||
|
// #ifndef APP-PLUS
|
||||||
|
uni.hideKeyboard();
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
plus.key.hideSoftKeybord()
|
||||||
|
// #endif
|
||||||
|
this.$emit("blur", {
|
||||||
|
value: this.searchVal
|
||||||
|
})
|
||||||
|
},
|
||||||
|
emitFocus(e) {
|
||||||
|
this.$emit("focus", e.detail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
$uni-searchbar-height: 36px;
|
||||||
|
|
||||||
|
.uni-searchbar {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
position: relative;
|
||||||
|
padding: 10px;
|
||||||
|
// background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-searchbar__box {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
box-sizing: border-box;
|
||||||
|
justify-content: left;
|
||||||
|
/* #endif */
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
height: $uni-searchbar-height;
|
||||||
|
padding: 5px 8px 5px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-searchbar__box-icon-search {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
// width: 32px;
|
||||||
|
padding: 0 8px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: #B3B3B3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-searchbar__box-search-input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-top: 1px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
background-color: inherit;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-searchbar__box-icon-clear {
|
||||||
|
align-items: center;
|
||||||
|
line-height: 24px;
|
||||||
|
padding-left: 8px;
|
||||||
|
/* #ifdef H5 */
|
||||||
|
cursor: pointer;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-searchbar__text-placeholder {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #B3B3B3;
|
||||||
|
margin-left: 5px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-searchbar__cancel {
|
||||||
|
padding-left: 10px;
|
||||||
|
line-height: $uni-searchbar-height;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333333;
|
||||||
|
/* #ifdef H5 */
|
||||||
|
cursor: pointer;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
</style>
|
87
uni_modules/uni-search-bar/package.json
Normal file
87
uni_modules/uni-search-bar/package.json
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
{
|
||||||
|
"id": "uni-search-bar",
|
||||||
|
"displayName": "uni-search-bar 搜索栏",
|
||||||
|
"version": "1.3.0",
|
||||||
|
"description": "搜索栏组件,通常用于搜索商品、文章等",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"uniui",
|
||||||
|
"搜索框",
|
||||||
|
"搜索栏"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": ""
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
|
||||||
|
"type": "component-vue"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uni-scss",
|
||||||
|
"uni-icons"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y",
|
||||||
|
"alipay": "n"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
uni_modules/uni-search-bar/readme.md
Normal file
14
uni_modules/uni-search-bar/readme.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
|
||||||
|
## SearchBar 搜索栏
|
||||||
|
|
||||||
|
> **组件名:uni-search-bar**
|
||||||
|
> 代码块: `uSearchBar`
|
||||||
|
|
||||||
|
|
||||||
|
搜索栏组件
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-search-bar)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="uni-navbar">
|
<view class="uni-navbar">
|
||||||
<view :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }" :style="{ 'background-color': backgroundColor }"
|
<view
|
||||||
class="uni-navbar__content">
|
:class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }"
|
||||||
|
:style="{ 'background-color': backgroundColor }"
|
||||||
|
class="uni-navbar__content"
|
||||||
|
>
|
||||||
<uni-status-bar v-if="statusBar" />
|
<uni-status-bar v-if="statusBar" />
|
||||||
<view :style="{ color: color,backgroundColor: backgroundColor }" class="uni-navbar__header uni-navbar__content_view">
|
<view :style="{ color: color, backgroundColor: backgroundColor }" class="uni-navbar__header uni-navbar__content_view">
|
||||||
<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left uni-navbar__content_view">
|
<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left uni-navbar__content_view">
|
||||||
<view class="uni-navbar__content_view" v-if="leftIcon.length">
|
<view class="uni-navbar__content_view" v-if="leftIcon.length">
|
||||||
<uni-icons :color="color" :type="leftIcon" size="24" />
|
<uni-icons :color="color" :type="leftIcon" size="24" />
|
||||||
</view>
|
</view>
|
||||||
<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length }" class="uni-navbar-btn-text uni-navbar__content_view"
|
<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length }" class="uni-navbar-btn-text uni-navbar__content_view" v-if="leftText.length">
|
||||||
v-if="leftText.length">
|
<text :style="{ color: color, fontSize: '16px' }">{{ leftText }}</text>
|
||||||
<text :style="{ color: color, fontSize: '14px' }">{{ leftText }}</text>
|
|
||||||
</view>
|
</view>
|
||||||
<slot name="left" />
|
<slot name="left" />
|
||||||
</view>
|
</view>
|
||||||
<view class="uni-navbar__header-container uni-navbar__content_view" @tap="onClickTitle">
|
<view class="uni-navbar__header-container uni-navbar__content_view" @tap="onClickTitle">
|
||||||
<view class="uni-navbar__header-container-inner uni-navbar__content_view" v-if="title.length">
|
<view class="uni-navbar__header-container-inner uni-navbar__content_view" v-if="title.length">
|
||||||
<text class="uni-nav-bar-text" :style="{color: color }">{{ title }}</text>
|
<text class="uni-nav-bar-text" :style="{ color: color }">{{ title }}</text>
|
||||||
</view>
|
</view>
|
||||||
<!-- 标题插槽 -->
|
<!-- 标题插槽 -->
|
||||||
<slot />
|
<slot />
|
||||||
|
@ -41,10 +43,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import uniStatusBar from "../uni-status-bar/uni-status-bar.vue";
|
import uniStatusBar from '../uni-status-bar/uni-status-bar.vue';
|
||||||
import uniIcons from "../uni-icons/uni-icons.vue";
|
import uniIcons from '../uni-icons/uni-icons.vue';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NavBar 自定义导航栏
|
* NavBar 自定义导航栏
|
||||||
* @description 导航栏组件,主要用于头部导航
|
* @description 导航栏组件,主要用于头部导航
|
||||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=52
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=52
|
||||||
|
@ -62,8 +64,8 @@
|
||||||
* @event {Function} clickRight 右侧按钮点击时触发
|
* @event {Function} clickRight 右侧按钮点击时触发
|
||||||
* @event {Function} clickTitle 中间标题点击时触发
|
* @event {Function} clickTitle 中间标题点击时触发
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
name: "UniNavBar",
|
name: 'UniNavBar',
|
||||||
components: {
|
components: {
|
||||||
uniStatusBar,
|
uniStatusBar,
|
||||||
uniIcons
|
uniIcons
|
||||||
|
@ -71,23 +73,23 @@
|
||||||
props: {
|
props: {
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ''
|
||||||
},
|
},
|
||||||
leftText: {
|
leftText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ''
|
||||||
},
|
},
|
||||||
rightText: {
|
rightText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ''
|
||||||
},
|
},
|
||||||
leftIcon: {
|
leftIcon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ''
|
||||||
},
|
},
|
||||||
rightIcon: {
|
rightIcon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ''
|
||||||
},
|
},
|
||||||
fixed: {
|
fixed: {
|
||||||
type: [Boolean, String],
|
type: [Boolean, String],
|
||||||
|
@ -95,11 +97,11 @@
|
||||||
},
|
},
|
||||||
color: {
|
color: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "#000000"
|
default: '#000000'
|
||||||
},
|
},
|
||||||
backgroundColor: {
|
backgroundColor: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "#FFFFFF"
|
default: '#FFFFFF'
|
||||||
},
|
},
|
||||||
statusBar: {
|
statusBar: {
|
||||||
type: [Boolean, String],
|
type: [Boolean, String],
|
||||||
|
@ -115,57 +117,57 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if(uni.report && this.title !== '') {
|
if (uni.report && this.title !== '') {
|
||||||
uni.report('title', this.title)
|
uni.report('title', this.title);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onClickLeft() {
|
onClickLeft() {
|
||||||
this.$emit("clickLeft");
|
this.$emit('clickLeft');
|
||||||
},
|
},
|
||||||
onClickRight() {
|
onClickRight() {
|
||||||
this.$emit("clickRight");
|
this.$emit('clickRight');
|
||||||
},
|
},
|
||||||
onClickTitle() {
|
onClickTitle() {
|
||||||
this.$emit("clickTitle");
|
this.$emit('clickTitle');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
$nav-height: 44px;
|
$nav-height: 44px;
|
||||||
|
|
||||||
.uni-nav-bar-text {
|
.uni-nav-bar-text {
|
||||||
/* #ifdef APP-PLUS */
|
/* #ifdef APP-PLUS */
|
||||||
font-size: 34rpx;
|
font-size: 34rpx;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
/* #ifndef APP-PLUS */
|
/* #ifndef APP-PLUS */
|
||||||
font-size: $uni-font-size-lg;
|
font-size: $uni-font-size-lg;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-nav-bar-right-text {
|
.uni-nav-bar-right-text {
|
||||||
font-size: $uni-font-size-base;
|
font-size: $uni-font-size-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-navbar__content {
|
.uni-navbar__content {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: $uni-bg-color;
|
background-color: $uni-bg-color;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 750rpx;
|
width: 750rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-navbar__content_view {
|
.uni-navbar__content_view {
|
||||||
/* #ifndef APP-NVUE */
|
/* #ifndef APP-NVUE */
|
||||||
display: flex;
|
display: flex;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
// background-color: #FFFFFF;
|
// background-color: #FFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-navbar__header {
|
.uni-navbar__header {
|
||||||
/* #ifndef APP-NVUE */
|
/* #ifndef APP-NVUE */
|
||||||
display: flex;
|
display: flex;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
|
@ -174,9 +176,9 @@
|
||||||
line-height: $nav-height;
|
line-height: $nav-height;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
// background-color: #ffffff;
|
// background-color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-navbar__header-btns {
|
.uni-navbar__header-btns {
|
||||||
/* #ifndef APP-NVUE */
|
/* #ifndef APP-NVUE */
|
||||||
display: flex;
|
display: flex;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
|
@ -185,30 +187,30 @@
|
||||||
padding: 0 6px;
|
padding: 0 6px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-navbar__header-btns-left {
|
.uni-navbar__header-btns-left {
|
||||||
/* #ifndef APP-NVUE */
|
/* #ifndef APP-NVUE */
|
||||||
display: flex;
|
display: flex;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
width: 150rpx;
|
width: 150rpx;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-navbar__header-btns-right {
|
.uni-navbar__header-btns-right {
|
||||||
/* #ifndef APP-NVUE */
|
/* #ifndef APP-NVUE */
|
||||||
display: flex;
|
display: flex;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
width: 150rpx;
|
width: 150rpx;
|
||||||
padding-right: 30rpx;
|
padding-right: 30rpx;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-navbar__header-container {
|
.uni-navbar__header-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-navbar__header-container-inner {
|
.uni-navbar__header-container-inner {
|
||||||
/* #ifndef APP-NVUE */
|
/* #ifndef APP-NVUE */
|
||||||
display: flex;
|
display: flex;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
|
@ -216,27 +218,26 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: $uni-font-size-base;
|
font-size: $uni-font-size-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.uni-navbar__placeholder-view {
|
||||||
.uni-navbar__placeholder-view {
|
|
||||||
height: $nav-height;
|
height: $nav-height;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-navbar--fixed {
|
.uni-navbar--fixed {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 998;
|
z-index: 998;
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-navbar--shadow {
|
.uni-navbar--shadow {
|
||||||
/* #ifndef APP-NVUE */
|
/* #ifndef APP-NVUE */
|
||||||
box-shadow: 0 1px 6px #ccc;
|
box-shadow: 0 1px 6px #ccc;
|
||||||
/* #endif */
|
/* #endif */
|
||||||
}
|
}
|
||||||
|
|
||||||
.uni-navbar--border {
|
.uni-navbar--border {
|
||||||
border-bottom-width: 1rpx;
|
border-bottom-width: 1rpx;
|
||||||
border-bottom-style: solid;
|
border-bottom-style: solid;
|
||||||
border-bottom-color: $uni-border-color;
|
border-bottom-color: $uni-border-color;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
21
uni_modules/uview-plus/LICENSE
Normal file
21
uni_modules/uview-plus/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 www.uviewui.com
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
64
uni_modules/uview-plus/README.md
Normal file
64
uni_modules/uview-plus/README.md
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
<p align="center">
|
||||||
|
<img alt="logo" src="https://uviewui.com/common/logo.png" width="120" height="120" style="margin-bottom: 10px;">
|
||||||
|
</p>
|
||||||
|
<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">uview-plus 3.0</h3>
|
||||||
|
<h3 align="center">多平台快速开发的UI框架</h3>
|
||||||
|
|
||||||
|
[![stars](https://img.shields.io/github/stars/ijry/uview-plus?style=flat-square&logo=GitHub)](https://github.com/ijry/uview-plus)
|
||||||
|
[![forks](https://img.shields.io/github/forks/ijry/uview-plus?style=flat-square&logo=GitHub)](https://github.com/ijry/uview-plus)
|
||||||
|
[![issues](https://img.shields.io/github/issues/ijry/uview-plus?style=flat-square&logo=GitHub)](https://github.com/ijry/uview-plus/issues)
|
||||||
|
[![release](https://img.shields.io/github/v/release/ijry/uview-plus?style=flat-square)](https://gitee.com/jry/uview-plus/releases)
|
||||||
|
[![license](https://img.shields.io/github/license/ijry/uview-plus?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)
|
||||||
|
|
||||||
|
## 说明
|
||||||
|
|
||||||
|
uview-plus,是uni-app全面兼容vue3/nvue的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水。uview-plus是基于uView2.x移植的支持vue3的版本,感谢uView。
|
||||||
|
|
||||||
|
## [官方文档:https://uview-plus.jiangruyi.com](https://uview-plus.jiangruyi.com)
|
||||||
|
|
||||||
|
|
||||||
|
## 预览
|
||||||
|
|
||||||
|
您可以通过**微信**扫码,查看最佳的演示效果。
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<img src="https://uview-plus.jiangruyi.com/common/h5_qrcode.png" width="220" height="220" >
|
||||||
|
|
||||||
|
## 链接
|
||||||
|
|
||||||
|
- [官方文档](https://uview-plus.jiangruyi.com)
|
||||||
|
- [更新日志](https://uview-plus.jiangruyi.com/components/changelog.html)
|
||||||
|
- [升级指南](https://uview-plus.jiangruyi.com/components/changeGuide.html)
|
||||||
|
- [关于我们](https://uview-plus.jiangruyi.com/cooperation/about.html)
|
||||||
|
|
||||||
|
## 交流反馈
|
||||||
|
|
||||||
|
欢迎加入我们的QQ群交流反馈:[点此跳转](https://uview-plus.jiangruyi.com/components/addQQGroup.html)
|
||||||
|
|
||||||
|
## 关于PR
|
||||||
|
|
||||||
|
> 我们非常乐意接受各位的优质PR,但在此之前我希望您了解uview-plus是一个需要兼容多个平台的(小程序、h5、ios app、android app)包括nvue页面、vue页面。
|
||||||
|
> 所以希望在您修复bug并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢!
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
|
||||||
|
#### **uni-app插件市场链接** —— [https://ext.dcloud.net.cn/plugin?name=uview-plus](https://ext.dcloud.net.cn/plugin?name=uview-plus)
|
||||||
|
|
||||||
|
请通过[官网安装文档](https://uview-plus.jiangruyi.com/components/install.html)了解更详细的内容
|
||||||
|
|
||||||
|
## 快速上手
|
||||||
|
|
||||||
|
请通过[快速上手](https://uview-plus.jiangruyi.com/components/quickstart.html)了解更详细的内容
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<u-button text="按钮"></u-button>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 版权信息
|
||||||
|
uview-plus遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uview-plus应用到您的产品中。
|
||||||
|
|
204
uni_modules/uview-plus/changelog.md
Normal file
204
uni_modules/uview-plus/changelog.md
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
## 3.2.24(2024-06-11)
|
||||||
|
fix: 修复时间选择器confirm事件触发时机导致2次才会触发v-model更新
|
||||||
|
## 3.2.23(2024-05-30)
|
||||||
|
fix: #378 H5 u-input 在表单中初始值为空也会触发一次 formValidate(this,"change")事件导致进入页面直接校验了一次
|
||||||
|
|
||||||
|
fix: #373 搜索组件up-search的@clear事件无效
|
||||||
|
|
||||||
|
fix: #372 ActionSheet 组件的取消按钮触发区域太小
|
||||||
|
|
||||||
|
## 3.2.22(2024-05-13)
|
||||||
|
上传组件支持微信小程序预览视频
|
||||||
|
|
||||||
|
修复折叠面板右侧箭头不显示
|
||||||
|
|
||||||
|
修复uxp2px
|
||||||
|
|
||||||
|
## 3.2.21(2024-05-10)
|
||||||
|
fix: loading-icon修复flex布局
|
||||||
|
## 3.2.20(2024-05-10)
|
||||||
|
修复瀑布流大小写#355
|
||||||
|
## 3.2.19(2024-05-10)
|
||||||
|
去除意外的文件引入
|
||||||
|
## 3.2.18(2024-05-09)
|
||||||
|
fix: 349 popup 组件设置 zIndex 属性后,组件渲染异常#
|
||||||
|
feat: 搜索框增加adjustPosition属性
|
||||||
|
fix: #331增加u-action-sheet__cancel
|
||||||
|
优化mixin兼容性
|
||||||
|
feat: #326 up-list增加下拉刷新功能
|
||||||
|
fix: #319 优化up-tabs参数与定义匹配
|
||||||
|
fix: index-list组件微信小程序端使用自定义导航栏异常
|
||||||
|
fix: #285 pickerimmediateChange 写死为true
|
||||||
|
fix: #111 u-scroll-list组件,隐藏指示器后报错, 提示找不到ref
|
||||||
|
list增加微信小程序防抖配置
|
||||||
|
|
||||||
|
## 3.2.17(2024-05-08)
|
||||||
|
fix: 支付宝小程序二维码渲染
|
||||||
|
## 3.2.16(2024-05-06)
|
||||||
|
修复tabs中,当前激活样式的undefined bug
|
||||||
|
|
||||||
|
fix: #341u-code 倒计时没结束前退出,再次进入结束后退出界面,再次进入重新开始倒计时bug
|
||||||
|
|
||||||
|
受到uni-app内置text样式影响修复
|
||||||
|
|
||||||
|
## 3.2.15(2024-04-28)
|
||||||
|
优化时间选择器hasInput模式初始化值
|
||||||
|
## 3.2.14(2024-04-24)
|
||||||
|
去除pleaseSetTranspileDependencies
|
||||||
|
|
||||||
|
http采用useStore
|
||||||
|
|
||||||
|
## 3.2.13(2024-04-22)
|
||||||
|
修复modal标题样式
|
||||||
|
|
||||||
|
优化日期选择器hasInput模式宽度
|
||||||
|
|
||||||
|
## 3.2.12(2024-04-22)
|
||||||
|
修复color应用
|
||||||
|
## 3.2.11(2024-04-18)
|
||||||
|
修复import化带来的问题
|
||||||
|
## 3.2.10(2024-04-17)
|
||||||
|
完善input清空事件App端失效的兼容性
|
||||||
|
|
||||||
|
修复日历组件二次打开后当前月份显示不正确
|
||||||
|
|
||||||
|
## 3.2.9(2024-04-16)
|
||||||
|
组件内uni.$u用法改为import引入
|
||||||
|
|
||||||
|
规范化及兼容性增强
|
||||||
|
|
||||||
|
## 3.2.8(2024-04-15)
|
||||||
|
修复up-tag语法错
|
||||||
|
## 3.2.7(2024-04-15)
|
||||||
|
修复下拉菜单背景色在支付宝小程序无效
|
||||||
|
|
||||||
|
setConfig改为浅拷贝解决无法用import导入代替uni.$u.props设置
|
||||||
|
|
||||||
|
## 3.2.6(2024-04-14)
|
||||||
|
修复某些情况下滑动单元格默认右侧按钮是展开的问题
|
||||||
|
## 3.2.5(2024-04-13)
|
||||||
|
调整分段器尺寸及修复窗口大小改变时重新计算尺寸
|
||||||
|
|
||||||
|
多个组件支持cursor-pointer增强PC端体验
|
||||||
|
|
||||||
|
## 3.2.4(2024-04-12)
|
||||||
|
初步支持typescript
|
||||||
|
## 3.2.3(2024-04-12)
|
||||||
|
fix: 修复square属性在小程序下无效问题
|
||||||
|
|
||||||
|
fix:修复lastIndex异常导致的column异常问题
|
||||||
|
|
||||||
|
fix: alipayapp picker style
|
||||||
|
|
||||||
|
feat(button): 添加用户同意隐私协议事件回调
|
||||||
|
|
||||||
|
fix: input switch password
|
||||||
|
|
||||||
|
fix: 修复u-code组件keepRuning失效问题
|
||||||
|
|
||||||
|
feat: form-item添加labelPosition属性
|
||||||
|
|
||||||
|
新增dropdown组件
|
||||||
|
|
||||||
|
分段器支持内部current值
|
||||||
|
|
||||||
|
优化cell和action-sheet视觉大小
|
||||||
|
|
||||||
|
修复tabs文字换行
|
||||||
|
|
||||||
|
## 3.2.2(2024-04-11)
|
||||||
|
修复换行符问题
|
||||||
|
## 3.2.1(2024-04-11)
|
||||||
|
修复演示H5二维码
|
||||||
|
|
||||||
|
fix: #270 ReadMore 展开阅读更多内容变化兼容
|
||||||
|
|
||||||
|
fix: #238Calendar组件maxDate修改为不能小于minDate
|
||||||
|
|
||||||
|
checkbox支持独立使用
|
||||||
|
|
||||||
|
修复popup中在微信小程序中真机调试滚动失效
|
||||||
|
|
||||||
|
## 3.2.0(2024-04-10)
|
||||||
|
修复轮播图在nvue显示
|
||||||
|
修复疑似u-slider名称被占用导致slider在App下不显示
|
||||||
|
解决微信小程序提示 Some selectors are not allowed in component wxss
|
||||||
|
示例中u-前缀统一为up-
|
||||||
|
增加瀑布流与图片懒加载组件
|
||||||
|
fix: #308修复tag组件缺失iconColor参数
|
||||||
|
fix: #297使用grid布局解决目前编译为抖音小程序无法开启virtualHost
|
||||||
|
## 3.1.52(2024-04-07)
|
||||||
|
工具类方法调用import化改造
|
||||||
|
新增up-copy复制组件
|
||||||
|
## 3.1.51(2024-04-07)
|
||||||
|
优化时间选择器自带输入框格式化显示
|
||||||
|
防止按钮文字换行
|
||||||
|
修复订单列表模板滑动
|
||||||
|
增加u-qrcode二维码组件
|
||||||
|
## 3.1.49(2024-03-27)
|
||||||
|
日期时间组件支持自带输入框
|
||||||
|
fix: popup弹窗滚动穿透问题
|
||||||
|
fix: 修复小程序numberbox bug
|
||||||
|
## 3.1.48(2024-03-18)
|
||||||
|
fix:[plugin:uni:pre-css] Unbalanced delimiter found in string
|
||||||
|
## 3.1.47(2024-03-18)
|
||||||
|
fix: setConfig设置组件默认参数无效问题
|
||||||
|
fix: 修复自定义图标无效问题
|
||||||
|
feat: 增加u-form-item单独设置规则变量
|
||||||
|
fix:#293小程序是自定义导航栏的时候即传了customNavHeight的时候会出现跳转偏移的情况
|
||||||
|
|
||||||
|
## 3.1.46(2024-01-29)
|
||||||
|
beforeUnmount
|
||||||
|
## 3.1.45(2024-01-24)
|
||||||
|
fix: #262ext组件为超链接的情况下size属性不生效
|
||||||
|
fix: #263最新版本3.1.42中微信小程序u-swipe-action-item报错
|
||||||
|
fix: #224最新版本3.1.42中微信小程序u-swipe-action-item报错
|
||||||
|
fix: #263支持支付宝小程序
|
||||||
|
fix: #261u-input在直接修改v-model的绑定值时,每隔一次会无法出发change事件
|
||||||
|
优化折叠面板兼容微信小程序
|
||||||
|
## 3.1.42(2024-01-15)
|
||||||
|
修复u-number-box默认值0时在小程序不显示值
|
||||||
|
优化u-code的timer判断
|
||||||
|
优化支付宝小程序下textarea字数统计兼容
|
||||||
|
优化u-calendar
|
||||||
|
## 3.1.41(2023-11-18)
|
||||||
|
#215优化u-cell图标容器间距问题
|
||||||
|
## 3.1.40(2023-11-16)
|
||||||
|
修复u-slider双向绑定
|
||||||
|
## 3.1.39(2023-11-10)
|
||||||
|
修复头条小程序不支持env(safe-area-inset-bottom)
|
||||||
|
优化#201u-grid 指定列数导致闪烁
|
||||||
|
#193IndexList 索引列表 高度错误
|
||||||
|
其他优化
|
||||||
|
## 3.1.38(2023-10-08)
|
||||||
|
修复u-slider
|
||||||
|
## 3.1.37(2023-09-13)
|
||||||
|
完善emits定义及修复code-input双向数据绑定
|
||||||
|
## 3.1.36(2023-08-08)
|
||||||
|
修复富文本事件名称大小写
|
||||||
|
## 3.1.35(2023-08-02)
|
||||||
|
修复编译到支付宝小程序u-form报错
|
||||||
|
## 3.1.34(2023-07-27)
|
||||||
|
修复App打包uni.$u.mpMixin方式sdk暂时不支持导致报错
|
||||||
|
## 3.1.33(2023-07-13)
|
||||||
|
修复弹窗进入动画、模板页面样式等
|
||||||
|
## 3.1.31(2023-07-11)
|
||||||
|
修复dayjs引用
|
||||||
|
## 3.0.8(2022-07-12)
|
||||||
|
修复u-tag默认宽度撑满容器
|
||||||
|
## 3.0.7(2022-07-12)
|
||||||
|
修复u-navbar自定义插槽演示示例
|
||||||
|
## 3.0.6(2022-07-11)
|
||||||
|
修复u-image缺少emits申明
|
||||||
|
## 3.0.5(2022-07-11)
|
||||||
|
修复u-upload缺少emits申明
|
||||||
|
## 3.0.4(2022-07-10)
|
||||||
|
修复u-textarea/u-input/u-datetime-picker/u-number-box/u-radio-group/u-switch/u-rate在vue3下数据绑定
|
||||||
|
## 3.0.3(2022-07-09)
|
||||||
|
启用自建演示二维码
|
||||||
|
## 3.0.2(2022-07-09)
|
||||||
|
修复dayjs/clipboard等导致打包报错
|
||||||
|
## 3.0.1(2022-07-09)
|
||||||
|
增加插件市场地址
|
||||||
|
## 3.0.0(2022-07-09)
|
||||||
|
# uview-plus(vue3)初步发布
|
80
uni_modules/uview-plus/components/u--form/u--form.vue
Normal file
80
uni_modules/uview-plus/components/u--form/u--form.vue
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
<template>
|
||||||
|
<uvForm
|
||||||
|
ref="uForm"
|
||||||
|
:model="model"
|
||||||
|
:rules="rules"
|
||||||
|
:errorType="errorType"
|
||||||
|
:borderBottom="borderBottom"
|
||||||
|
:labelPosition="labelPosition"
|
||||||
|
:labelWidth="labelWidth"
|
||||||
|
:labelAlign="labelAlign"
|
||||||
|
:labelStyle="labelStyle"
|
||||||
|
:customStyle="customStyle"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</uvForm>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* 此组件存在的理由是,在nvue下,u-form被uni-app官方占用了,u-form在nvue中相当于form组件
|
||||||
|
* 所以在nvue下,取名为u--form,内部其实还是u-form.vue,只不过做一层中转
|
||||||
|
*/
|
||||||
|
import uvForm from '../u-form/u-form.vue';
|
||||||
|
import props from '../u-form/props.js';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
export default {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
name: 'u-form',
|
||||||
|
// #endif
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
name: 'u--form',
|
||||||
|
// #endif
|
||||||
|
mixins: [mpMixin, props, mixin],
|
||||||
|
components: {
|
||||||
|
uvForm
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.children = []
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 手动设置校验的规则,如果规则中有函数的话,微信小程序中会过滤掉,所以只能手动调用设置规则
|
||||||
|
setRules(rules) {
|
||||||
|
this.$refs.uForm.setRules(rules)
|
||||||
|
},
|
||||||
|
validate() {
|
||||||
|
/**
|
||||||
|
* 在微信小程序中,通过this.$parent拿到的父组件是u--form,而不是其内嵌的u-form
|
||||||
|
* 导致在u-form组件中,拿不到对应的children数组,从而校验无效,所以这里每次调用u-form组件中的
|
||||||
|
* 对应方法的时候,在小程序中都先将u--form的children赋值给u-form中的children
|
||||||
|
*/
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.setMpData()
|
||||||
|
// #endif
|
||||||
|
return this.$refs.uForm.validate()
|
||||||
|
},
|
||||||
|
validateField(value, callback) {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.setMpData()
|
||||||
|
// #endif
|
||||||
|
return this.$refs.uForm.validateField(value, callback)
|
||||||
|
},
|
||||||
|
resetFields() {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.setMpData()
|
||||||
|
// #endif
|
||||||
|
return this.$refs.uForm.resetFields()
|
||||||
|
},
|
||||||
|
clearValidate(props) {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.setMpData()
|
||||||
|
// #endif
|
||||||
|
return this.$refs.uForm.clearValidate(props)
|
||||||
|
},
|
||||||
|
setMpData() {
|
||||||
|
this.$refs.uForm.children = this.children
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
50
uni_modules/uview-plus/components/u--image/u--image.vue
Normal file
50
uni_modules/uview-plus/components/u--image/u--image.vue
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<template>
|
||||||
|
<uvImage
|
||||||
|
:src="src"
|
||||||
|
:mode="mode"
|
||||||
|
:width="width"
|
||||||
|
:height="height"
|
||||||
|
:shape="shape"
|
||||||
|
:radius="radius"
|
||||||
|
:lazyLoad="lazyLoad"
|
||||||
|
:showMenuByLongpress="showMenuByLongpress"
|
||||||
|
:loadingIcon="loadingIcon"
|
||||||
|
:errorIcon="errorIcon"
|
||||||
|
:showLoading="showLoading"
|
||||||
|
:showError="showError"
|
||||||
|
:fade="fade"
|
||||||
|
:webp="webp"
|
||||||
|
:duration="duration"
|
||||||
|
:bgColor="bgColor"
|
||||||
|
:customStyle="customStyle"
|
||||||
|
@click="$emit('click')"
|
||||||
|
@error="$emit('error')"
|
||||||
|
@load="$emit('load')"
|
||||||
|
>
|
||||||
|
<template v-slot:loading>
|
||||||
|
<slot name="loading"></slot>
|
||||||
|
</template>
|
||||||
|
<template v-slot:error>
|
||||||
|
<slot name="error"></slot>
|
||||||
|
</template>
|
||||||
|
</uvImage>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* 此组件存在的理由是,在nvue下,u-image被uni-app官方占用了,u-image在nvue中相当于image组件
|
||||||
|
* 所以在nvue下,取名为u--image,内部其实还是u-iamge.vue,只不过做一层中转
|
||||||
|
*/
|
||||||
|
import uvImage from '../u-image/u-image.vue';
|
||||||
|
import props from '../u-image/props.js';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
export default {
|
||||||
|
name: 'u--image',
|
||||||
|
mixins: [mpMixin, props, mixin],
|
||||||
|
components: {
|
||||||
|
uvImage
|
||||||
|
},
|
||||||
|
emits: ['click', 'error', 'load']
|
||||||
|
}
|
||||||
|
</script>
|
74
uni_modules/uview-plus/components/u--input/u--input.vue
Normal file
74
uni_modules/uview-plus/components/u--input/u--input.vue
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<template>
|
||||||
|
<uvInput
|
||||||
|
<!-- #ifdef VUE2 -->
|
||||||
|
:value="value"
|
||||||
|
@input="e => $emit('input', e)"
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifdef VUE3 -->
|
||||||
|
:modelValue="modelValue"
|
||||||
|
@update:modelValue="e => $emit('update:modelValue', e)"
|
||||||
|
<!-- #endif -->
|
||||||
|
:type="type"
|
||||||
|
:fixed="fixed"
|
||||||
|
:disabled="disabled"
|
||||||
|
:disabledColor="disabledColor"
|
||||||
|
:clearable="clearable"
|
||||||
|
:password="password"
|
||||||
|
:maxlength="maxlength"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:placeholderClass="placeholderClass"
|
||||||
|
:placeholderStyle="placeholderStyle"
|
||||||
|
:showWordLimit="showWordLimit"
|
||||||
|
:confirmType="confirmType"
|
||||||
|
:confirmHold="confirmHold"
|
||||||
|
:holdKeyboard="holdKeyboard"
|
||||||
|
:focus="focus"
|
||||||
|
:autoBlur="autoBlur"
|
||||||
|
:disableDefaultPadding="disableDefaultPadding"
|
||||||
|
:cursor="cursor"
|
||||||
|
:cursorSpacing="cursorSpacing"
|
||||||
|
:selectionStart="selectionStart"
|
||||||
|
:selectionEnd="selectionEnd"
|
||||||
|
:adjustPosition="adjustPosition"
|
||||||
|
:inputAlign="inputAlign"
|
||||||
|
:fontSize="fontSize"
|
||||||
|
:color="color"
|
||||||
|
:prefixIcon="prefixIcon"
|
||||||
|
:suffixIcon="suffixIcon"
|
||||||
|
:suffixIconStyle="suffixIconStyle"
|
||||||
|
:prefixIconStyle="prefixIconStyle"
|
||||||
|
:border="border"
|
||||||
|
:readonly="readonly"
|
||||||
|
:shape="shape"
|
||||||
|
:customStyle="customStyle"
|
||||||
|
:formatter="formatter"
|
||||||
|
:ignoreCompositionEvent="ignoreCompositionEvent"
|
||||||
|
>
|
||||||
|
<!-- #ifdef MP -->
|
||||||
|
<slot name="prefix"></slot>
|
||||||
|
<slot name="suffix"></slot>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef MP -->
|
||||||
|
<slot name="prefix" slot="prefix"></slot>
|
||||||
|
<slot name="suffix" slot="suffix"></slot>
|
||||||
|
<!-- #endif -->
|
||||||
|
</uvInput>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* 此组件存在的理由是,在nvue下,u-input被uni-app官方占用了,u-input在nvue中相当于input组件
|
||||||
|
* 所以在nvue下,取名为u--input,内部其实还是u-input.vue,只不过做一层中转
|
||||||
|
*/
|
||||||
|
import uvInput from '../u-input/u-input.vue';
|
||||||
|
import props from '../u-input/props.js';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
export default {
|
||||||
|
name: 'u--input',
|
||||||
|
mixins: [mpMixin, props, mixin],
|
||||||
|
components: {
|
||||||
|
uvInput
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
45
uni_modules/uview-plus/components/u--text/u--text.vue
Normal file
45
uni_modules/uview-plus/components/u--text/u--text.vue
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<template>
|
||||||
|
<uvText
|
||||||
|
:type="type"
|
||||||
|
:show="show"
|
||||||
|
:text="text"
|
||||||
|
:prefixIcon="prefixIcon"
|
||||||
|
:suffixIcon="suffixIcon"
|
||||||
|
:mode="mode"
|
||||||
|
:href="href"
|
||||||
|
:format="format"
|
||||||
|
:call="call"
|
||||||
|
:openType="openType"
|
||||||
|
:bold="bold"
|
||||||
|
:block="block"
|
||||||
|
:lines="lines"
|
||||||
|
:color="color"
|
||||||
|
:decoration="decoration"
|
||||||
|
:size="size"
|
||||||
|
:iconStyle="iconStyle"
|
||||||
|
:margin="margin"
|
||||||
|
:lineHeight="lineHeight"
|
||||||
|
:align="align"
|
||||||
|
:wordWrap="wordWrap"
|
||||||
|
:customStyle="customStyle"
|
||||||
|
></uvText>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* 此组件存在的理由是,在nvue下,u-text被uni-app官方占用了,u-text在nvue中相当于input组件
|
||||||
|
* 所以在nvue下,取名为u--input,内部其实还是u-text.vue,只不过做一层中转
|
||||||
|
* 不使用v-bind="$attrs",而是分开独立写传参,是因为微信小程序不支持此写法
|
||||||
|
*/
|
||||||
|
import uvText from "../u-text/u-text.vue";
|
||||||
|
import props from "../u-text/props.js";
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin.js'
|
||||||
|
import mixin from '../../libs/mixin/mixin.js'
|
||||||
|
export default {
|
||||||
|
name: "u--text",
|
||||||
|
mixins: [mpMixin, mixin, props,],
|
||||||
|
components: {
|
||||||
|
uvText,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<template>
|
||||||
|
<uvTextarea
|
||||||
|
:value="value"
|
||||||
|
:modelValue="modelValue"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:height="height"
|
||||||
|
:confirmType="confirmType"
|
||||||
|
:disabled="disabled"
|
||||||
|
:count="count"
|
||||||
|
:focus="focus"
|
||||||
|
:autoHeight="autoHeight"
|
||||||
|
:fixed="fixed"
|
||||||
|
:cursorSpacing="cursorSpacing"
|
||||||
|
:cursor="cursor"
|
||||||
|
:showConfirmBar="showConfirmBar"
|
||||||
|
:selectionStart="selectionStart"
|
||||||
|
:selectionEnd="selectionEnd"
|
||||||
|
:adjustPosition="adjustPosition"
|
||||||
|
:disableDefaultPadding="disableDefaultPadding"
|
||||||
|
:holdKeyboard="holdKeyboard"
|
||||||
|
:maxlength="maxlength"
|
||||||
|
:border="border"
|
||||||
|
:customStyle="customStyle"
|
||||||
|
:formatter="formatter"
|
||||||
|
:ignoreCompositionEvent="ignoreCompositionEvent"
|
||||||
|
@input="e => $emit('input', e)"
|
||||||
|
@update:modelValue="e => $emit('update:modelValue', e)"
|
||||||
|
></uvTextarea>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* 此组件存在的理由是,在nvue下,u--textarea被uni-app官方占用了,u-textarea在nvue中相当于textarea组件
|
||||||
|
* 所以在nvue下,取名为u--textarea,内部其实还是u-textarea.vue,只不过做一层中转
|
||||||
|
*/
|
||||||
|
import uvTextarea from '../u-textarea/u-textarea.vue';
|
||||||
|
import props from '../u-textarea/props.js';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
export default {
|
||||||
|
name: 'u--textarea',
|
||||||
|
mixins: [mpMixin, props, mixin],
|
||||||
|
components: {
|
||||||
|
uvTextarea
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
55
uni_modules/uview-plus/components/u-action-sheet/props.js
Normal file
55
uni_modules/uview-plus/components/u-action-sheet/props.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 操作菜单是否展示 (默认false)
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.actionSheet.show
|
||||||
|
},
|
||||||
|
// 标题
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.actionSheet.title
|
||||||
|
},
|
||||||
|
// 选项上方的描述信息
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.actionSheet.description
|
||||||
|
},
|
||||||
|
// 数据
|
||||||
|
actions: {
|
||||||
|
type: Array,
|
||||||
|
default: () => defProps.actionSheet.actions
|
||||||
|
},
|
||||||
|
// 取消按钮的文字,不为空时显示按钮
|
||||||
|
cancelText: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.actionSheet.cancelText
|
||||||
|
},
|
||||||
|
// 点击某个菜单项时是否关闭弹窗
|
||||||
|
closeOnClickAction: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.actionSheet.closeOnClickAction
|
||||||
|
},
|
||||||
|
// 处理底部安全区(默认true)
|
||||||
|
safeAreaInsetBottom: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.actionSheet.safeAreaInsetBottom
|
||||||
|
},
|
||||||
|
// 小程序的打开方式
|
||||||
|
openType: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.actionSheet.openType
|
||||||
|
},
|
||||||
|
// 点击遮罩是否允许关闭 (默认true)
|
||||||
|
closeOnClickOverlay: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.actionSheet.closeOnClickOverlay
|
||||||
|
},
|
||||||
|
// 圆角值
|
||||||
|
round: {
|
||||||
|
type: [Boolean, String, Number],
|
||||||
|
default: () => defProps.actionSheet.round
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,281 @@
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<u-popup
|
||||||
|
:show="show"
|
||||||
|
mode="bottom"
|
||||||
|
@close="closeHandler"
|
||||||
|
:safeAreaInsetBottom="safeAreaInsetBottom"
|
||||||
|
:round="round"
|
||||||
|
>
|
||||||
|
<view class="u-action-sheet">
|
||||||
|
<view
|
||||||
|
class="u-action-sheet__header"
|
||||||
|
v-if="title"
|
||||||
|
>
|
||||||
|
<text class="u-action-sheet__header__title u-line-1">{{title}}</text>
|
||||||
|
<view
|
||||||
|
class="u-action-sheet__header__icon-wrap"
|
||||||
|
@tap.stop="cancel"
|
||||||
|
>
|
||||||
|
<u-icon
|
||||||
|
name="close"
|
||||||
|
size="17"
|
||||||
|
color="#c8c9cc"
|
||||||
|
bold
|
||||||
|
></u-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<text
|
||||||
|
class="u-action-sheet__description"
|
||||||
|
:style="[{
|
||||||
|
marginTop: `${title && description ? 0 : '18px'}`
|
||||||
|
}]"
|
||||||
|
v-if="description"
|
||||||
|
>{{description}}</text>
|
||||||
|
<slot>
|
||||||
|
<u-line v-if="description"></u-line>
|
||||||
|
<view class="u-action-sheet__item-wrap">
|
||||||
|
<view :key="index" v-for="(item, index) in actions">
|
||||||
|
<!-- #ifdef MP -->
|
||||||
|
<button
|
||||||
|
class="u-reset-button"
|
||||||
|
:openType="item.openType"
|
||||||
|
@getuserinfo="onGetUserInfo"
|
||||||
|
@contact="onContact"
|
||||||
|
@getphonenumber="onGetPhoneNumber"
|
||||||
|
@error="onError"
|
||||||
|
@launchapp="onLaunchApp"
|
||||||
|
@opensetting="onOpenSetting"
|
||||||
|
:lang="lang"
|
||||||
|
:session-from="sessionFrom"
|
||||||
|
:send-message-title="sendMessageTitle"
|
||||||
|
:send-message-path="sendMessagePath"
|
||||||
|
:send-message-img="sendMessageImg"
|
||||||
|
:show-message-card="showMessageCard"
|
||||||
|
:app-parameter="appParameter"
|
||||||
|
@tap="selectHandler(index)"
|
||||||
|
:hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
|
||||||
|
>
|
||||||
|
<!-- #endif -->
|
||||||
|
<view
|
||||||
|
class="u-action-sheet__item-wrap__item"
|
||||||
|
@tap.stop="selectHandler(index)"
|
||||||
|
:hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
|
||||||
|
:hover-stay-time="150"
|
||||||
|
>
|
||||||
|
<template v-if="!item.loading">
|
||||||
|
<text
|
||||||
|
class="u-action-sheet__item-wrap__item__name"
|
||||||
|
:style="[itemStyle(index)]"
|
||||||
|
>{{ item.name }}</text>
|
||||||
|
<text
|
||||||
|
v-if="item.subname"
|
||||||
|
class="u-action-sheet__item-wrap__item__subname"
|
||||||
|
>{{ item.subname }}</text>
|
||||||
|
</template>
|
||||||
|
<u-loading-icon
|
||||||
|
v-else
|
||||||
|
custom-class="van-action-sheet__loading"
|
||||||
|
size="18"
|
||||||
|
mode="circle"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<!-- #ifdef MP -->
|
||||||
|
</button>
|
||||||
|
<!-- #endif -->
|
||||||
|
<u-line v-if="index !== actions.length - 1"></u-line>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</slot>
|
||||||
|
<u-gap
|
||||||
|
bgColor="#eaeaec"
|
||||||
|
height="6"
|
||||||
|
v-if="cancelText"
|
||||||
|
></u-gap>
|
||||||
|
<view class="u-action-sheet__item-wrap__item u-action-sheet__cancel"
|
||||||
|
hover-class="u-action-sheet--hover" @tap="cancel">
|
||||||
|
<text
|
||||||
|
@touchmove.stop.prevent
|
||||||
|
:hover-stay-time="150"
|
||||||
|
v-if="cancelText"
|
||||||
|
class="u-action-sheet__cancel-text"
|
||||||
|
>{{cancelText}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import openType from '../../libs/mixin/openType'
|
||||||
|
import button from '../../libs/mixin/button'
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addUnit } from '../../libs/function/index';
|
||||||
|
/**
|
||||||
|
* ActionSheet 操作菜单
|
||||||
|
* @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/actionSheet.html
|
||||||
|
*
|
||||||
|
* @property {Boolean} show 操作菜单是否展示 (默认 false )
|
||||||
|
* @property {String} title 操作菜单标题
|
||||||
|
* @property {String} description 选项上方的描述信息
|
||||||
|
* @property {Array<Object>} actions 按钮的文字数组,见官方文档示例
|
||||||
|
* @property {String} cancelText 取消按钮的提示文字,不为空时显示按钮
|
||||||
|
* @property {Boolean} closeOnClickAction 点击某个菜单项时是否关闭弹窗 (默认 true )
|
||||||
|
* @property {Boolean} safeAreaInsetBottom 处理底部安全区 (默认 true )
|
||||||
|
* @property {String} openType 小程序的打开方式 (contact | launchApp | getUserInfo | openSetting |getPhoneNumber |error )
|
||||||
|
* @property {Boolean} closeOnClickOverlay 点击遮罩是否允许关闭 (默认 true )
|
||||||
|
* @property {Number|String} round 圆角值,默认无圆角 (默认 0 )
|
||||||
|
* @property {String} lang 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文
|
||||||
|
* @property {String} sessionFrom 会话来源,openType="contact"时有效
|
||||||
|
* @property {String} sendMessageTitle 会话内消息卡片标题,openType="contact"时有效
|
||||||
|
* @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径,openType="contact"时有效
|
||||||
|
* @property {String} sendMessageImg 会话内消息卡片图片,openType="contact"时有效
|
||||||
|
* @property {Boolean} showMessageCard 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效 (默认 false )
|
||||||
|
* @property {String} appParameter 打开 APP 时,向 APP 传递的参数,openType=launchApp 时有效
|
||||||
|
*
|
||||||
|
* @event {Function} select 点击ActionSheet列表项时触发
|
||||||
|
* @event {Function} close 点击取消按钮时触发
|
||||||
|
* @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与 wx.getUserInfo 返回的一致,openType="getUserInfo"时有效
|
||||||
|
* @event {Function} contact 客服消息回调,openType="contact"时有效
|
||||||
|
* @event {Function} getphonenumber 获取用户手机号回调,openType="getPhoneNumber"时有效
|
||||||
|
* @event {Function} error 当使用开放能力时,发生错误的回调,openType="error"时有效
|
||||||
|
* @event {Function} launchapp 打开 APP 成功的回调,openType="launchApp"时有效
|
||||||
|
* @event {Function} opensetting 在打开授权设置页后回调,openType="openSetting"时有效
|
||||||
|
* @example <u-action-sheet :actions="list" :title="title" :show="show"></u-action-sheet>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: "u-action-sheet",
|
||||||
|
// 一些props参数和methods方法,通过mixin混入,因为其他文件也会用到
|
||||||
|
mixins: [openType, button, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 操作项目的样式
|
||||||
|
itemStyle() {
|
||||||
|
return (index) => {
|
||||||
|
let style = {};
|
||||||
|
if (this.actions[index].color) style.color = this.actions[index].color
|
||||||
|
if (this.actions[index].fontSize) style.fontSize = addUnit(this.actions[index].fontSize)
|
||||||
|
// 选项被禁用的样式
|
||||||
|
if (this.actions[index].disabled) style.color = '#c0c4cc'
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ["close", "select"],
|
||||||
|
methods: {
|
||||||
|
closeHandler() {
|
||||||
|
// 允许点击遮罩关闭时,才发出close事件
|
||||||
|
if(this.closeOnClickOverlay) {
|
||||||
|
this.$emit('close')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 点击取消按钮
|
||||||
|
cancel() {
|
||||||
|
this.$emit('close')
|
||||||
|
},
|
||||||
|
selectHandler(index) {
|
||||||
|
const item = this.actions[index]
|
||||||
|
if (item && !item.disabled && !item.loading) {
|
||||||
|
this.$emit('select', item)
|
||||||
|
if (this.closeOnClickAction) {
|
||||||
|
this.$emit('close')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
$u-action-sheet-reset-button-width:100% !default;
|
||||||
|
$u-action-sheet-title-font-size: 16px !default;
|
||||||
|
$u-action-sheet-title-padding: 12px 30px !default;
|
||||||
|
$u-action-sheet-title-color: $u-main-color !default;
|
||||||
|
$u-action-sheet-header-icon-wrap-right:15px !default;
|
||||||
|
$u-action-sheet-header-icon-wrap-top:15px !default;
|
||||||
|
$u-action-sheet-description-font-size:13px !default;
|
||||||
|
$u-action-sheet-description-color:14px !default;
|
||||||
|
$u-action-sheet-description-margin: 18px 15px !default;
|
||||||
|
$u-action-sheet-item-wrap-item-padding:17px !default;
|
||||||
|
$u-action-sheet-item-wrap-name-font-size:16px !default;
|
||||||
|
$u-action-sheet-item-wrap-subname-font-size:13px !default;
|
||||||
|
$u-action-sheet-item-wrap-subname-color: #c0c4cc !default;
|
||||||
|
$u-action-sheet-item-wrap-subname-margin-top:10px !default;
|
||||||
|
$u-action-sheet-cancel-text-font-size:16px !default;
|
||||||
|
$u-action-sheet-cancel-text-color:$u-content-color !default;
|
||||||
|
$u-action-sheet-cancel-text-font-size:15px !default;
|
||||||
|
$u-action-sheet-cancel-text-hover-background-color:rgb(242, 243, 245) !default;
|
||||||
|
|
||||||
|
.u-reset-button {
|
||||||
|
width: $u-action-sheet-reset-button-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-action-sheet {
|
||||||
|
text-align: center;
|
||||||
|
&__header {
|
||||||
|
position: relative;
|
||||||
|
padding: $u-action-sheet-title-padding;
|
||||||
|
&__title {
|
||||||
|
font-size: $u-action-sheet-title-font-size;
|
||||||
|
color: $u-action-sheet-title-color;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon-wrap {
|
||||||
|
position: absolute;
|
||||||
|
right: $u-action-sheet-header-icon-wrap-right;
|
||||||
|
top: $u-action-sheet-header-icon-wrap-top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__description {
|
||||||
|
font-size: $u-action-sheet-description-font-size;
|
||||||
|
color: $u-tips-color;
|
||||||
|
margin: $u-action-sheet-description-margin;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__item-wrap {
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
padding: $u-action-sheet-item-wrap-item-padding;
|
||||||
|
@include flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
font-size: $u-action-sheet-item-wrap-name-font-size;
|
||||||
|
color: $u-main-color;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__subname {
|
||||||
|
font-size: $u-action-sheet-item-wrap-subname-font-size;
|
||||||
|
color: $u-action-sheet-item-wrap-subname-color;
|
||||||
|
margin-top: $u-action-sheet-item-wrap-subname-margin-top;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__cancel-text {
|
||||||
|
font-size: $u-action-sheet-cancel-text-font-size;
|
||||||
|
color: $u-action-sheet-cancel-text-color;
|
||||||
|
text-align: center;
|
||||||
|
padding: $u-action-sheet-cancel-text-font-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--hover {
|
||||||
|
background-color: $u-action-sheet-cancel-text-hover-background-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
60
uni_modules/uview-plus/components/u-album/props.js
Normal file
60
uni_modules/uview-plus/components/u-album/props.js
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 图片地址,Array<String>|Array<Object>形式
|
||||||
|
urls: {
|
||||||
|
type: Array,
|
||||||
|
default: () => defProps.album.urls
|
||||||
|
},
|
||||||
|
// 指定从数组的对象元素中读取哪个属性作为图片地址
|
||||||
|
keyName: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.album.keyName
|
||||||
|
},
|
||||||
|
// 单图时,图片长边的长度
|
||||||
|
singleSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.album.singleSize
|
||||||
|
},
|
||||||
|
// 多图时,图片边长
|
||||||
|
multipleSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.album.multipleSize
|
||||||
|
},
|
||||||
|
// 多图时,图片水平和垂直之间的间隔
|
||||||
|
space: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.album.space
|
||||||
|
},
|
||||||
|
// 单图时,图片缩放裁剪的模式
|
||||||
|
singleMode: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.album.singleMode
|
||||||
|
},
|
||||||
|
// 多图时,图片缩放裁剪的模式
|
||||||
|
multipleMode: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.album.multipleMode
|
||||||
|
},
|
||||||
|
// 最多展示的图片数量,超出时最后一个位置将会显示剩余图片数量
|
||||||
|
maxCount: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.album.maxCount
|
||||||
|
},
|
||||||
|
// 是否可以预览图片
|
||||||
|
previewFullImage: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.album.previewFullImage
|
||||||
|
},
|
||||||
|
// 每行展示图片数量,如设置,singleSize和multipleSize将会无效
|
||||||
|
rowCount: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.album.rowCount
|
||||||
|
},
|
||||||
|
// 超出maxCount时是否显示查看更多的提示
|
||||||
|
showMore: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.album.showMore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
264
uni_modules/uview-plus/components/u-album/u-album.vue
Normal file
264
uni_modules/uview-plus/components/u-album/u-album.vue
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
<template>
|
||||||
|
<view class="u-album">
|
||||||
|
<view
|
||||||
|
class="u-album__row"
|
||||||
|
ref="u-album__row"
|
||||||
|
v-for="(arr, index) in showUrls"
|
||||||
|
:forComputedUse="albumWidth"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-album__row__wrapper"
|
||||||
|
v-for="(item, index1) in arr"
|
||||||
|
:key="index1"
|
||||||
|
:style="[imageStyle(index + 1, index1 + 1)]"
|
||||||
|
@tap="previewFullImage ? onPreviewTap(getSrc(item)) : ''"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
:src="getSrc(item)"
|
||||||
|
:mode="
|
||||||
|
urls.length === 1
|
||||||
|
? imageHeight > 0
|
||||||
|
? singleMode
|
||||||
|
: 'widthFix'
|
||||||
|
: multipleMode
|
||||||
|
"
|
||||||
|
:style="[
|
||||||
|
{
|
||||||
|
width: imageWidth,
|
||||||
|
height: imageHeight
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
></image>
|
||||||
|
<view
|
||||||
|
v-if="
|
||||||
|
showMore &&
|
||||||
|
urls.length > rowCount * showUrls.length &&
|
||||||
|
index === showUrls.length - 1 &&
|
||||||
|
index1 === showUrls[showUrls.length - 1].length - 1
|
||||||
|
"
|
||||||
|
class="u-album__row__wrapper__text"
|
||||||
|
>
|
||||||
|
<up-text
|
||||||
|
:text="`+${urls.length - maxCount}`"
|
||||||
|
color="#fff"
|
||||||
|
:size="multipleSize * 0.3"
|
||||||
|
align="center"
|
||||||
|
customStyle="justify-content: center"
|
||||||
|
></up-text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addUnit, sleep } from '../../libs/function/index';
|
||||||
|
import test from '../../libs/function/test';
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
// 由于weex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度
|
||||||
|
const dom = uni.requireNativePlugin('dom')
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Album 相册
|
||||||
|
* @description 本组件提供一个类似相册的功能,让开发者开发起来更加得心应手。减少重复的模板代码
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/album.html
|
||||||
|
*
|
||||||
|
* @property {Array} urls 图片地址列表 Array<String>|Array<Object>形式
|
||||||
|
* @property {String} keyName 指定从数组的对象元素中读取哪个属性作为图片地址
|
||||||
|
* @property {String | Number} singleSize 单图时,图片长边的长度 (默认 180 )
|
||||||
|
* @property {String | Number} multipleSize 多图时,图片边长 (默认 70 )
|
||||||
|
* @property {String | Number} space 多图时,图片水平和垂直之间的间隔 (默认 6 )
|
||||||
|
* @property {String} singleMode 单图时,图片缩放裁剪的模式 (默认 'scaleToFill' )
|
||||||
|
* @property {String} multipleMode 多图时,图片缩放裁剪的模式 (默认 'aspectFill' )
|
||||||
|
* @property {String | Number} maxCount 取消按钮的提示文字 (默认 9 )
|
||||||
|
* @property {Boolean} previewFullImage 是否可以预览图片 (默认 true )
|
||||||
|
* @property {String | Number} rowCount 每行展示图片数量,如设置,singleSize和multipleSize将会无效 (默认 3 )
|
||||||
|
* @property {Boolean} showMore 超出maxCount时是否显示查看更多的提示 (默认 true )
|
||||||
|
*
|
||||||
|
* @event {Function} albumWidth 某些特殊的情况下,需要让文字与相册的宽度相等,这里事件的形式对外发送 (回调参数 width )
|
||||||
|
* @example <u-album :urls="urls2" @albumWidth="width => albumWidth = width" multipleSize="68" ></u-album>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-album',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 单图的宽度
|
||||||
|
singleWidth: 0,
|
||||||
|
// 单图的高度
|
||||||
|
singleHeight: 0,
|
||||||
|
// 单图时,如果无法获取图片的尺寸信息,让图片宽度默认为容器的一定百分比
|
||||||
|
singlePercent: 0.6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
urls: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newVal) {
|
||||||
|
if (newVal.length === 1) {
|
||||||
|
this.getImageRect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ["albumWidth"],
|
||||||
|
computed: {
|
||||||
|
imageStyle() {
|
||||||
|
return (index1, index2) => {
|
||||||
|
const { space, rowCount, multipleSize, urls } = this,
|
||||||
|
{ addUnit, addStyle } = uni.$u,
|
||||||
|
rowLen = this.showUrls.length,
|
||||||
|
allLen = this.urls.length
|
||||||
|
const style = {
|
||||||
|
marginRight: addUnit(space),
|
||||||
|
marginBottom: addUnit(space)
|
||||||
|
}
|
||||||
|
// 如果为最后一行,则每个图片都无需下边框
|
||||||
|
if (index1 === rowLen) style.marginBottom = 0
|
||||||
|
// 每行的最右边一张和总长度的最后一张无需右边框
|
||||||
|
if (
|
||||||
|
index2 === rowCount ||
|
||||||
|
(index1 === rowLen &&
|
||||||
|
index2 === this.showUrls[index1 - 1].length)
|
||||||
|
)
|
||||||
|
style.marginRight = 0
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 将数组划分为二维数组
|
||||||
|
showUrls() {
|
||||||
|
const arr = []
|
||||||
|
this.urls.map((item, index) => {
|
||||||
|
// 限制最大展示数量
|
||||||
|
if (index + 1 <= this.maxCount) {
|
||||||
|
// 计算该元素为第几个素组内
|
||||||
|
const itemIndex = Math.floor(index / this.rowCount)
|
||||||
|
// 判断对应的索引是否存在
|
||||||
|
if (!arr[itemIndex]) {
|
||||||
|
arr[itemIndex] = []
|
||||||
|
}
|
||||||
|
arr[itemIndex].push(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return arr
|
||||||
|
},
|
||||||
|
imageWidth() {
|
||||||
|
return addUnit(
|
||||||
|
this.urls.length === 1 ? this.singleWidth : this.multipleSize
|
||||||
|
)
|
||||||
|
},
|
||||||
|
imageHeight() {
|
||||||
|
return addUnit(
|
||||||
|
this.urls.length === 1 ? this.singleHeight : this.multipleSize
|
||||||
|
)
|
||||||
|
},
|
||||||
|
// 此变量无实际用途,仅仅是为了利用computed特性,让其在urls长度等变化时,重新计算图片的宽度
|
||||||
|
// 因为用户在某些特殊的情况下,需要让文字与相册的宽度相等,所以这里事件的形式对外发送
|
||||||
|
albumWidth() {
|
||||||
|
let width = 0
|
||||||
|
if (this.urls.length === 1) {
|
||||||
|
width = this.singleWidth
|
||||||
|
} else {
|
||||||
|
width =
|
||||||
|
this.showUrls[0].length * this.multipleSize +
|
||||||
|
this.space * (this.showUrls[0].length - 1)
|
||||||
|
}
|
||||||
|
this.$emit('albumWidth', width)
|
||||||
|
return width
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 预览图片
|
||||||
|
onPreviewTap(url) {
|
||||||
|
const urls = this.urls.map((item) => {
|
||||||
|
return this.getSrc(item)
|
||||||
|
})
|
||||||
|
uni.previewImage({
|
||||||
|
current: url,
|
||||||
|
urls
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获取图片的路径
|
||||||
|
getSrc(item) {
|
||||||
|
return test.object(item)
|
||||||
|
? (this.keyName && item[this.keyName]) || item.src
|
||||||
|
: item
|
||||||
|
},
|
||||||
|
// 单图时,获取图片的尺寸
|
||||||
|
// 在小程序中,需要将网络图片的的域名添加到小程序的download域名才可能获取尺寸
|
||||||
|
// 在没有添加的情况下,让单图宽度默认为盒子的一定宽度(singlePercent)
|
||||||
|
getImageRect() {
|
||||||
|
const src = this.getSrc(this.urls[0])
|
||||||
|
uni.getImageInfo({
|
||||||
|
src,
|
||||||
|
success: (res) => {
|
||||||
|
// 判断图片横向还是竖向展示方式
|
||||||
|
const isHorizotal = res.width >= res.height
|
||||||
|
this.singleWidth = isHorizotal
|
||||||
|
? this.singleSize
|
||||||
|
: (res.width / res.height) * this.singleSize
|
||||||
|
this.singleHeight = !isHorizotal
|
||||||
|
? this.singleSize
|
||||||
|
: (res.height / res.width) * this.singleWidth
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
this.getComponentWidth()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获取组件的宽度
|
||||||
|
async getComponentWidth() {
|
||||||
|
// 延时一定时间,以获取dom尺寸
|
||||||
|
await sleep(30)
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.$uGetRect('.u-album__row').then((size) => {
|
||||||
|
this.singleWidth = size.width * this.singlePercent
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
// 这里ref="u-album__row"所在的标签为通过for循环出来,导致this.$refs['u-album__row']是一个数组
|
||||||
|
const ref = this.$refs['u-album__row'][0]
|
||||||
|
ref &&
|
||||||
|
dom.getComponentRect(ref, (res) => {
|
||||||
|
this.singleWidth = res.size.width * this.singlePercent
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../../libs/css/components.scss';
|
||||||
|
|
||||||
|
.u-album {
|
||||||
|
@include flex(column);
|
||||||
|
|
||||||
|
&__row {
|
||||||
|
@include flex(row);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
&__wrapper {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
@include flex(row);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
45
uni_modules/uview-plus/components/u-alert/props.js
Normal file
45
uni_modules/uview-plus/components/u-alert/props.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 显示文字
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.alert.title
|
||||||
|
},
|
||||||
|
// 主题,success/warning/info/error
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.alert.type
|
||||||
|
},
|
||||||
|
// 辅助性文字
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.alert.description
|
||||||
|
},
|
||||||
|
// 是否可关闭
|
||||||
|
closable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.alert.closable
|
||||||
|
},
|
||||||
|
// 是否显示图标
|
||||||
|
showIcon: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.alert.showIcon
|
||||||
|
},
|
||||||
|
// 浅或深色调,light-浅色,dark-深色
|
||||||
|
effect: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.alert.effect
|
||||||
|
},
|
||||||
|
// 文字是否居中
|
||||||
|
center: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.alert.center
|
||||||
|
},
|
||||||
|
// 字体大小
|
||||||
|
fontSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.alert.fontSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
249
uni_modules/uview-plus/components/u-alert/u-alert.vue
Normal file
249
uni_modules/uview-plus/components/u-alert/u-alert.vue
Normal file
|
@ -0,0 +1,249 @@
|
||||||
|
<template>
|
||||||
|
<u-transition
|
||||||
|
mode="fade"
|
||||||
|
:show="show"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-alert"
|
||||||
|
:class="[`u-alert--${type}--${effect}`]"
|
||||||
|
@tap.stop="clickHandler"
|
||||||
|
:style="[addStyle(customStyle)]"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-alert__icon"
|
||||||
|
v-if="showIcon"
|
||||||
|
>
|
||||||
|
<u-icon
|
||||||
|
:name="iconName"
|
||||||
|
size="18"
|
||||||
|
:color="iconColor"
|
||||||
|
></u-icon>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="u-alert__content"
|
||||||
|
:style="[{
|
||||||
|
paddingRight: closable ? '20px' : 0
|
||||||
|
}]"
|
||||||
|
>
|
||||||
|
<text
|
||||||
|
class="u-alert__content__title"
|
||||||
|
v-if="title"
|
||||||
|
:style="[{
|
||||||
|
fontSize: addUnit(fontSize),
|
||||||
|
textAlign: center ? 'center' : 'left'
|
||||||
|
}]"
|
||||||
|
:class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
|
||||||
|
>{{ title }}</text>
|
||||||
|
<text
|
||||||
|
class="u-alert__content__desc"
|
||||||
|
v-if="description"
|
||||||
|
:style="[{
|
||||||
|
fontSize: addUnit(fontSize),
|
||||||
|
textAlign: center ? 'center' : 'left'
|
||||||
|
}]"
|
||||||
|
:class="[effect === 'dark' ? 'u-alert__text--dark' : `u-alert__text--${type}--light`]"
|
||||||
|
>{{ description }}</text>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="u-alert__close"
|
||||||
|
v-if="closable"
|
||||||
|
@tap.stop="closeHandler"
|
||||||
|
>
|
||||||
|
<u-icon
|
||||||
|
name="close"
|
||||||
|
:color="iconColor"
|
||||||
|
size="15"
|
||||||
|
></u-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addUnit, addStyle } from '../../libs/function/index';
|
||||||
|
/**
|
||||||
|
* Alert 警告提示
|
||||||
|
* @description 警告提示,展现需要关注的信息。
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/alertTips.html
|
||||||
|
*
|
||||||
|
* @property {String} title 显示的文字
|
||||||
|
* @property {String} type 使用预设的颜色 (默认 'warning' )
|
||||||
|
* @property {String} description 辅助性文字,颜色比title浅一点,字号也小一点,可选
|
||||||
|
* @property {Boolean} closable 关闭按钮(默认为叉号icon图标) (默认 false )
|
||||||
|
* @property {Boolean} showIcon 是否显示左边的辅助图标 ( 默认 false )
|
||||||
|
* @property {String} effect 多图时,图片缩放裁剪的模式 (默认 'light' )
|
||||||
|
* @property {Boolean} center 文字是否居中 (默认 false )
|
||||||
|
* @property {String | Number} fontSize 字体大小 (默认 14 )
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
* @event {Function} click 点击组件时触发
|
||||||
|
* @example <u-alert :title="title" type = "warning" :closable="closable" :description = "description"></u-alert>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-alert',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
iconColor() {
|
||||||
|
return this.effect === 'light' ? this.type : '#fff'
|
||||||
|
},
|
||||||
|
// 不同主题对应不同的图标
|
||||||
|
iconName() {
|
||||||
|
switch (this.type) {
|
||||||
|
case 'success':
|
||||||
|
return 'checkmark-circle-fill';
|
||||||
|
break;
|
||||||
|
case 'error':
|
||||||
|
return 'close-circle-fill';
|
||||||
|
break;
|
||||||
|
case 'warning':
|
||||||
|
return 'error-circle-fill';
|
||||||
|
break;
|
||||||
|
case 'info':
|
||||||
|
return 'info-circle-fill';
|
||||||
|
break;
|
||||||
|
case 'primary':
|
||||||
|
return 'more-circle-fill';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 'error-circle-fill';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ["click"],
|
||||||
|
methods: {
|
||||||
|
addUnit,
|
||||||
|
addStyle,
|
||||||
|
// 点击内容
|
||||||
|
clickHandler() {
|
||||||
|
this.$emit('click')
|
||||||
|
},
|
||||||
|
// 点击关闭按钮
|
||||||
|
closeHandler() {
|
||||||
|
this.show = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
.u-alert {
|
||||||
|
position: relative;
|
||||||
|
background-color: $u-primary;
|
||||||
|
padding: 8px 10px;
|
||||||
|
@include flex(row);
|
||||||
|
align-items: center;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
|
||||||
|
&--primary--dark {
|
||||||
|
background-color: $u-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--primary--light {
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--error--dark {
|
||||||
|
background-color: $u-error;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--error--light {
|
||||||
|
background-color: #FEF0F0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success--dark {
|
||||||
|
background-color: $u-success;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success--light {
|
||||||
|
background-color: #f5fff0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--warning--dark {
|
||||||
|
background-color: $u-warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--warning--light {
|
||||||
|
background-color: #FDF6EC;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--info--dark {
|
||||||
|
background-color: $u-info;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--info--light {
|
||||||
|
background-color: #f4f4f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
@include flex(column);
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
color: $u-main-color;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__desc {
|
||||||
|
color: $u-main-color;
|
||||||
|
font-size: 14px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title--dark,
|
||||||
|
&__desc--dark {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--primary--light,
|
||||||
|
&__text--primary--light {
|
||||||
|
color: $u-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--success--light,
|
||||||
|
&__text--success--light {
|
||||||
|
color: $u-success;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--warning--light,
|
||||||
|
&__text--warning--light {
|
||||||
|
color: $u-warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--error--light,
|
||||||
|
&__text--error--light {
|
||||||
|
color: $u-error;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--info--light,
|
||||||
|
&__text--info--light {
|
||||||
|
color: $u-info;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__close {
|
||||||
|
position: absolute;
|
||||||
|
top: 11px;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
53
uni_modules/uview-plus/components/u-avatar-group/props.js
Normal file
53
uni_modules/uview-plus/components/u-avatar-group/props.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 头像图片组
|
||||||
|
urls: {
|
||||||
|
type: Array,
|
||||||
|
default: () => defProps.avatarGroup.urls
|
||||||
|
},
|
||||||
|
// 最多展示的头像数量
|
||||||
|
maxCount: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.avatarGroup.maxCount
|
||||||
|
},
|
||||||
|
// 头像形状
|
||||||
|
shape: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatarGroup.shape
|
||||||
|
},
|
||||||
|
// 图片裁剪模式
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatarGroup.mode
|
||||||
|
},
|
||||||
|
// 超出maxCount时是否显示查看更多的提示
|
||||||
|
showMore: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.avatarGroup.showMore
|
||||||
|
},
|
||||||
|
// 头像大小
|
||||||
|
size: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.avatarGroup.size
|
||||||
|
},
|
||||||
|
// 指定从数组的对象元素中读取哪个属性作为图片地址
|
||||||
|
keyName: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatarGroup.keyName
|
||||||
|
},
|
||||||
|
// 头像之间的遮挡比例
|
||||||
|
gap: {
|
||||||
|
type: [String, Number],
|
||||||
|
validator(value) {
|
||||||
|
return value >= 0 && value <= 1
|
||||||
|
},
|
||||||
|
default: () => defProps.avatarGroup.gap
|
||||||
|
},
|
||||||
|
// 需额外显示的值
|
||||||
|
extraValue: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: () => defProps.avatarGroup.extraValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
<template>
|
||||||
|
<view class="u-avatar-group">
|
||||||
|
<view
|
||||||
|
class="u-avatar-group__item"
|
||||||
|
v-for="(item, index) in showUrl"
|
||||||
|
:key="index"
|
||||||
|
:style="{
|
||||||
|
marginLeft: index === 0 ? 0 : addUnit(-size * gap)
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<u-avatar
|
||||||
|
:size="size"
|
||||||
|
:shape="shape"
|
||||||
|
:mode="mode"
|
||||||
|
:src="testObject(item) ? keyName && item[keyName] || item.url : item"
|
||||||
|
></u-avatar>
|
||||||
|
<view
|
||||||
|
class="u-avatar-group__item__show-more"
|
||||||
|
v-if="showMore && index === showUrl.length - 1 && (urls.length > maxCount || extraValue > 0)"
|
||||||
|
@tap="clickHandler"
|
||||||
|
>
|
||||||
|
<up-text
|
||||||
|
color="#ffffff"
|
||||||
|
:size="size * 0.4"
|
||||||
|
:text="`+${extraValue || urls.length - showUrl.length}`"
|
||||||
|
align="center"
|
||||||
|
customStyle="justify-content: center"
|
||||||
|
></up-text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addUnit } from '../../libs/function/index';
|
||||||
|
import test from '../../libs/function/test';
|
||||||
|
/**
|
||||||
|
* AvatarGroup 头像组
|
||||||
|
* @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/avatar.html
|
||||||
|
*
|
||||||
|
* @property {Array} urls 头像图片组 (默认 [] )
|
||||||
|
* @property {String | Number} maxCount 最多展示的头像数量 ( 默认 5 )
|
||||||
|
* @property {String} shape 头像形状( 'circle' (默认) | 'square' )
|
||||||
|
* @property {String} mode 图片裁剪模式(默认 'scaleToFill' )
|
||||||
|
* @property {Boolean} showMore 超出maxCount时是否显示查看更多的提示 (默认 true )
|
||||||
|
* @property {String | Number} size 头像大小 (默认 40 )
|
||||||
|
* @property {String} keyName 指定从数组的对象元素中读取哪个属性作为图片地址
|
||||||
|
* @property {String | Number} gap 头像之间的遮挡比例(0.4代表遮挡40%) (默认 0.5 )
|
||||||
|
* @property {String | Number} extraValue 需额外显示的值
|
||||||
|
* @event {Function} showMore 头像组更多点击
|
||||||
|
* @example <u-avatar-group:urls="urls" size="35" gap="0.4" ></u-avatar-group:urls=>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-avatar-group',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
showUrl() {
|
||||||
|
return this.urls.slice(0, this.maxCount)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ["showMore"],
|
||||||
|
methods: {
|
||||||
|
addUnit,
|
||||||
|
testObject: test.object,
|
||||||
|
clickHandler() {
|
||||||
|
this.$emit('showMore')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
.u-avatar-group {
|
||||||
|
@include flex;
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
margin-left: -10px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&--no-indent {
|
||||||
|
// 如果你想质疑作者不会使用:first-child,说明你太年轻,因为nvue不支持
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__show-more {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
@include flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
80
uni_modules/uview-plus/components/u-avatar/props.js
Normal file
80
uni_modules/uview-plus/components/u-avatar/props.js
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
import test from '../../libs/function/test';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 头像图片路径(不能为相对路径)
|
||||||
|
src: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatar.src
|
||||||
|
},
|
||||||
|
// 头像形状,circle-圆形,square-方形
|
||||||
|
shape: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatar.shape
|
||||||
|
},
|
||||||
|
// 头像尺寸
|
||||||
|
size: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.avatar.size
|
||||||
|
},
|
||||||
|
// 裁剪模式
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatar.mode
|
||||||
|
},
|
||||||
|
// 显示的文字
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatar.text
|
||||||
|
},
|
||||||
|
// 背景色
|
||||||
|
bgColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatar.bgColor
|
||||||
|
},
|
||||||
|
// 文字颜色
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatar.color
|
||||||
|
},
|
||||||
|
// 文字大小
|
||||||
|
fontSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.avatar.fontSize
|
||||||
|
},
|
||||||
|
// 显示的图标
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatar.icon
|
||||||
|
},
|
||||||
|
// 显示小程序头像,只对百度,微信,QQ小程序有效
|
||||||
|
mpAvatar: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.avatar.mpAvatar
|
||||||
|
},
|
||||||
|
// 是否使用随机背景色
|
||||||
|
randomBgColor: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.avatar.randomBgColor
|
||||||
|
},
|
||||||
|
// 加载失败的默认头像(组件有内置默认图片)
|
||||||
|
defaultUrl: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatar.defaultUrl
|
||||||
|
},
|
||||||
|
// 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
|
||||||
|
colorIndex: {
|
||||||
|
type: [String, Number],
|
||||||
|
// 校验参数规则,索引在0-19之间
|
||||||
|
validator(n) {
|
||||||
|
return test.range(n, [0, 19]) || n === ''
|
||||||
|
},
|
||||||
|
default: () => defProps.avatar.colorIndex
|
||||||
|
},
|
||||||
|
// 组件标识符
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.avatar.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
180
uni_modules/uview-plus/components/u-avatar/u-avatar.vue
Normal file
180
uni_modules/uview-plus/components/u-avatar/u-avatar.vue
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
<template>
|
||||||
|
<view
|
||||||
|
class="u-avatar"
|
||||||
|
:class="[`u-avatar--${shape}`]"
|
||||||
|
:style="[{
|
||||||
|
backgroundColor: (text || icon) ? (randomBgColor ? colors[colorIndex !== '' ? colorIndex : random(0, 19)] : bgColor) : 'transparent',
|
||||||
|
width: addUnit(size),
|
||||||
|
height: addUnit(size),
|
||||||
|
}, addStyle(customStyle)]"
|
||||||
|
@tap="clickHandler"
|
||||||
|
>
|
||||||
|
<slot>
|
||||||
|
<!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU -->
|
||||||
|
<open-data
|
||||||
|
v-if="mpAvatar && allowMp"
|
||||||
|
type="userAvatarUrl"
|
||||||
|
:style="[{
|
||||||
|
width: addUnit(size),
|
||||||
|
height: addUnit(size)
|
||||||
|
}]"
|
||||||
|
/>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU -->
|
||||||
|
<template v-if="mpAvatar && allowMp"></template>
|
||||||
|
<!-- #endif -->
|
||||||
|
<u-icon
|
||||||
|
v-else-if="icon"
|
||||||
|
:name="icon"
|
||||||
|
:size="fontSize"
|
||||||
|
:color="color"
|
||||||
|
></u-icon>
|
||||||
|
<up-text
|
||||||
|
v-else-if="text"
|
||||||
|
:text="text"
|
||||||
|
:size="fontSize"
|
||||||
|
:color="color"
|
||||||
|
align="center"
|
||||||
|
customStyle="justify-content: center"
|
||||||
|
></up-text>
|
||||||
|
<image
|
||||||
|
class="u-avatar__image"
|
||||||
|
v-else
|
||||||
|
:class="[`u-avatar__image--${shape}`]"
|
||||||
|
:src="avatarUrl || defaultUrl"
|
||||||
|
:mode="mode"
|
||||||
|
@error="errorHandler"
|
||||||
|
:style="[{
|
||||||
|
width: addUnit(size),
|
||||||
|
height: addUnit(size)
|
||||||
|
}]"
|
||||||
|
></image>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addStyle, addUnit, random } from '../../libs/function/index';
|
||||||
|
const base64Avatar =
|
||||||
|
"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";
|
||||||
|
/**
|
||||||
|
* Avatar 头像
|
||||||
|
* @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/avatar.html
|
||||||
|
*
|
||||||
|
* @property {String} src 头像路径,如加载失败,将会显示默认头像(不能为相对路径)
|
||||||
|
* @property {String} shape 头像形状 ( circle (默认) | square)
|
||||||
|
* @property {String | Number} size 头像尺寸,可以为指定字符串(large, default, mini),或者数值 (默认 40 )
|
||||||
|
* @property {String} mode 头像图片的裁剪类型,与uni的image组件的mode参数一致,如效果达不到需求,可尝试传widthFix值 (默认 'scaleToFill' )
|
||||||
|
* @property {String} text 用文字替代图片,级别优先于src
|
||||||
|
* @property {String} bgColor 背景颜色,一般显示文字时用 (默认 '#c0c4cc' )
|
||||||
|
* @property {String} color 文字颜色 (默认 '#ffffff' )
|
||||||
|
* @property {String | Number} fontSize 文字大小 (默认 18 )
|
||||||
|
* @property {String} icon 显示的图标
|
||||||
|
* @property {Boolean} mpAvatar 显示小程序头像,只对百度,微信,QQ小程序有效 (默认 false )
|
||||||
|
* @property {Boolean} randomBgColor 是否使用随机背景色 (默认 false )
|
||||||
|
* @property {String} defaultUrl 加载失败的默认头像(组件有内置默认图片)
|
||||||
|
* @property {String | Number} colorIndex 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
|
||||||
|
* @property {String} name 组件标识符 (默认 'level' )
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
*
|
||||||
|
* @event {Function} click 点击组件时触发 index: 用户传递的标识符
|
||||||
|
* @example <u-avatar :src="src" mode="square"></u-avatar>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-avatar',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 如果配置randomBgColor参数为true,在图标或者文字的模式下,会随机从中取出一个颜色值当做背景色
|
||||||
|
colors: ['#ffb34b', '#f2bba9', '#f7a196', '#f18080', '#88a867', '#bfbf39', '#89c152', '#94d554', '#f19ec2',
|
||||||
|
'#afaae4', '#e1b0df', '#c38cc1', '#72dcdc', '#9acdcb', '#77b1cc', '#448aca', '#86cefa', '#98d1ee',
|
||||||
|
'#73d1f1',
|
||||||
|
'#80a7dc'
|
||||||
|
],
|
||||||
|
avatarUrl: this.src,
|
||||||
|
allowMp: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// 监听头像src的变化,赋值给内部的avatarUrl变量,因为图片加载失败时,需要修改图片的src为默认值
|
||||||
|
// 而组件内部不能直接修改props的值,所以需要一个中间变量
|
||||||
|
src: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newVal) {
|
||||||
|
this.avatarUrl = newVal
|
||||||
|
// 如果没有传src,则主动触发error事件,用于显示默认的头像,否则src为''空字符等的时候,会无内容展示
|
||||||
|
if(!newVal) {
|
||||||
|
this.errorHandler()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
imageStyle() {
|
||||||
|
const style = {}
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
emits: ["click"],
|
||||||
|
methods: {
|
||||||
|
addStyle,
|
||||||
|
addUnit,
|
||||||
|
random,
|
||||||
|
init() {
|
||||||
|
// 目前只有这几个小程序平台具有open-data标签
|
||||||
|
// 其他平台可以通过uni.getUserInfo类似接口获取信息,但是需要弹窗授权(首次),不合符组件逻辑
|
||||||
|
// 故目前自动获取小程序头像只支持这几个平台
|
||||||
|
// #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU
|
||||||
|
this.allowMp = true
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
// 判断传入的name属性,是否图片路径,只要带有"/"均认为是图片形式
|
||||||
|
isImg() {
|
||||||
|
return this.src.indexOf('/') !== -1
|
||||||
|
},
|
||||||
|
// 图片加载时失败时触发
|
||||||
|
errorHandler() {
|
||||||
|
this.avatarUrl = this.defaultUrl || base64Avatar
|
||||||
|
},
|
||||||
|
clickHandler() {
|
||||||
|
this.$emit('click', this.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
.u-avatar {
|
||||||
|
@include flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&--circle {
|
||||||
|
border-radius: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--square {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__image {
|
||||||
|
&--circle {
|
||||||
|
border-radius: 100px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--square {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
55
uni_modules/uview-plus/components/u-back-top/props.js
Normal file
55
uni_modules/uview-plus/components/u-back-top/props.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 返回顶部的形状,circle-圆形,square-方形
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.backtop.mode
|
||||||
|
},
|
||||||
|
// 自定义图标
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.backtop.icon
|
||||||
|
},
|
||||||
|
// 提示文字
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.backtop.text
|
||||||
|
},
|
||||||
|
// 返回顶部滚动时间
|
||||||
|
duration: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.backtop.duration
|
||||||
|
},
|
||||||
|
// 滚动距离
|
||||||
|
scrollTop: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.backtop.scrollTop
|
||||||
|
},
|
||||||
|
// 距离顶部多少距离显示,单位px
|
||||||
|
top: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.backtop.top
|
||||||
|
},
|
||||||
|
// 返回顶部按钮到底部的距离,单位px
|
||||||
|
bottom: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.backtop.bottom
|
||||||
|
},
|
||||||
|
// 返回顶部按钮到右边的距离,单位px
|
||||||
|
right: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.backtop.right
|
||||||
|
},
|
||||||
|
// 层级
|
||||||
|
zIndex: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.backtop.zIndex
|
||||||
|
},
|
||||||
|
// 图标的样式,对象形式
|
||||||
|
iconStyle: {
|
||||||
|
type: Object,
|
||||||
|
default: () => defProps.backtop.iconStyle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
133
uni_modules/uview-plus/components/u-back-top/u-back-top.vue
Normal file
133
uni_modules/uview-plus/components/u-back-top/u-back-top.vue
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
<template>
|
||||||
|
<u-transition
|
||||||
|
mode="fade"
|
||||||
|
:customStyle="backTopStyle"
|
||||||
|
:show="show"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-back-top"
|
||||||
|
:style="[contentStyle]"
|
||||||
|
v-if="!$slots.default && !$slots.$default"
|
||||||
|
@click="backToTop"
|
||||||
|
>
|
||||||
|
<u-icon
|
||||||
|
:name="icon"
|
||||||
|
:custom-style="iconStyle"
|
||||||
|
></u-icon>
|
||||||
|
<text
|
||||||
|
v-if="text"
|
||||||
|
class="u-back-top__text"
|
||||||
|
>{{text}}</text>
|
||||||
|
</view>
|
||||||
|
<slot v-else />
|
||||||
|
</u-transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addUnit, addStyle, getPx, deepMerge, error } from '../../libs/function/index';
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
const dom = weex.requireModule('dom')
|
||||||
|
// #endif
|
||||||
|
/**
|
||||||
|
* backTop 返回顶部
|
||||||
|
* @description 本组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。
|
||||||
|
* @tutorial https://uview-plus.jiangruyi.com/components/backTop.html
|
||||||
|
*
|
||||||
|
* @property {String} mode 返回顶部的形状,circle-圆形,square-方形 (默认 'circle' )
|
||||||
|
* @property {String} icon 自定义图标 (默认 'arrow-upward' ) 见官方文档示例
|
||||||
|
* @property {String} text 提示文字
|
||||||
|
* @property {String | Number} duration 返回顶部滚动时间 (默认 100)
|
||||||
|
* @property {String | Number} scrollTop 滚动距离 (默认 0 )
|
||||||
|
* @property {String | Number} top 距离顶部多少距离显示,单位px (默认 400 )
|
||||||
|
* @property {String | Number} bottom 返回顶部按钮到底部的距离,单位px (默认 100 )
|
||||||
|
* @property {String | Number} right 返回顶部按钮到右边的距离,单位px (默认 20 )
|
||||||
|
* @property {String | Number} zIndex 层级 (默认 9 )
|
||||||
|
* @property {Object<Object>} iconStyle 图标的样式,对象形式 (默认 {color: '#909399',fontSize: '19px'})
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
*
|
||||||
|
* @example <u-back-top :scrollTop="scrollTop"></u-back-top>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-back-top',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
computed: {
|
||||||
|
backTopStyle() {
|
||||||
|
// 动画组件样式
|
||||||
|
const style = {
|
||||||
|
bottom: addUnit(this.bottom),
|
||||||
|
right: addUnit(this.right),
|
||||||
|
width: '40px',
|
||||||
|
height: '40px',
|
||||||
|
position: 'fixed',
|
||||||
|
zIndex: 10,
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
},
|
||||||
|
show() {
|
||||||
|
return getPx(this.scrollTop) > getPx(this.top)
|
||||||
|
},
|
||||||
|
contentStyle() {
|
||||||
|
const style = {}
|
||||||
|
let radius = 0
|
||||||
|
// 是否圆形
|
||||||
|
if(this.mode === 'circle') {
|
||||||
|
radius = '100px'
|
||||||
|
} else {
|
||||||
|
radius = '4px'
|
||||||
|
}
|
||||||
|
// 为了兼容安卓nvue,只能这么分开写
|
||||||
|
style.borderTopLeftRadius = radius
|
||||||
|
style.borderTopRightRadius = radius
|
||||||
|
style.borderBottomLeftRadius = radius
|
||||||
|
style.borderBottomRightRadius = radius
|
||||||
|
return deepMerge(style, addStyle(this.customStyle))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ["click"],
|
||||||
|
methods: {
|
||||||
|
backToTop() {
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
if (!this.$parent.$refs['u-back-top']) {
|
||||||
|
error(`nvue页面需要给页面最外层元素设置"ref='u-back-top'`)
|
||||||
|
}
|
||||||
|
dom.scrollToElement(this.$parent.$refs['u-back-top'], {
|
||||||
|
offset: 0
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
uni.pageScrollTo({
|
||||||
|
scrollTop: 0,
|
||||||
|
duration: this.duration
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
this.$emit('click')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../../libs/css/components.scss';
|
||||||
|
$u-back-top-flex:1 !default;
|
||||||
|
$u-back-top-height:100% !default;
|
||||||
|
$u-back-top-background-color:#E1E1E1 !default;
|
||||||
|
$u-back-top-tips-font-size:12px !default;
|
||||||
|
.u-back-top {
|
||||||
|
@include flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
flex:$u-back-top-flex;
|
||||||
|
height: $u-back-top-height;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: $u-back-top-background-color;
|
||||||
|
|
||||||
|
&__tips {
|
||||||
|
font-size:$u-back-top-tips-font-size;
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
78
uni_modules/uview-plus/components/u-badge/props.js
Normal file
78
uni_modules/uview-plus/components/u-badge/props.js
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 是否显示圆点
|
||||||
|
isDot: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.badge.isDot
|
||||||
|
},
|
||||||
|
// 显示的内容
|
||||||
|
value: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: () => defProps.badge.value
|
||||||
|
},
|
||||||
|
// 显示的内容
|
||||||
|
modelValue: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: () => defProps.badge.modelValue
|
||||||
|
},
|
||||||
|
// 是否显示
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.badge.show
|
||||||
|
},
|
||||||
|
// 最大值,超过最大值会显示 '{max}+'
|
||||||
|
max: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: () => defProps.badge.max
|
||||||
|
},
|
||||||
|
// 主题类型,error|warning|success|primary
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.badge.type
|
||||||
|
},
|
||||||
|
// 当数值为 0 时,是否展示 Badge
|
||||||
|
showZero: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.badge.showZero
|
||||||
|
},
|
||||||
|
// 背景颜色,优先级比type高,如设置,type参数会失效
|
||||||
|
bgColor: {
|
||||||
|
type: [String, null],
|
||||||
|
default: () => defProps.badge.bgColor
|
||||||
|
},
|
||||||
|
// 字体颜色
|
||||||
|
color: {
|
||||||
|
type: [String, null],
|
||||||
|
default: () => defProps.badge.color
|
||||||
|
},
|
||||||
|
// 徽标形状,circle-四角均为圆角,horn-左下角为直角
|
||||||
|
shape: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.badge.shape
|
||||||
|
},
|
||||||
|
// 设置数字的显示方式,overflow|ellipsis|limit
|
||||||
|
// overflow会根据max字段判断,超出显示`${max}+`
|
||||||
|
// ellipsis会根据max判断,超出显示`${max}...`
|
||||||
|
// limit会依据1000作为判断条件,超出1000,显示`${value/1000}K`,比如2.2k、3.34w,最多保留2位小数
|
||||||
|
numberType: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.badge.numberType
|
||||||
|
},
|
||||||
|
// 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效
|
||||||
|
offset: {
|
||||||
|
type: Array,
|
||||||
|
default: () => defProps.badge.offset
|
||||||
|
},
|
||||||
|
// 是否反转背景和字体颜色
|
||||||
|
inverted: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.badge.inverted
|
||||||
|
},
|
||||||
|
// 是否绝对定位
|
||||||
|
absolute: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.badge.absolute
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
181
uni_modules/uview-plus/components/u-badge/u-badge.vue
Normal file
181
uni_modules/uview-plus/components/u-badge/u-badge.vue
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
<template>
|
||||||
|
<text
|
||||||
|
v-if="show && ((Number(value) === 0 ? showZero : true) || isDot)"
|
||||||
|
:class="[isDot ? 'u-badge--dot' : 'u-badge--not-dot', inverted && 'u-badge--inverted', shape === 'horn' && 'u-badge--horn', `u-badge--${type}${inverted ? '--inverted' : ''}`]"
|
||||||
|
:style="[addStyle(customStyle), badgeStyle]"
|
||||||
|
class="u-badge"
|
||||||
|
>
|
||||||
|
{{ isDot ? '' : showValue }}
|
||||||
|
</text>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addStyle, addUnit } from '../../libs/function/index';
|
||||||
|
/**
|
||||||
|
* badge 徽标数
|
||||||
|
* @description 该组件一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。
|
||||||
|
* @tutorial https://uview-plus.jiangruyi.com/components/badge.html
|
||||||
|
*
|
||||||
|
* @property {Boolean} isDot 是否显示圆点 (默认 false )
|
||||||
|
* @property {String | Number} value 显示的内容
|
||||||
|
* @property {Boolean} show 是否显示 (默认 true )
|
||||||
|
* @property {String | Number} max 最大值,超过最大值会显示 '{max}+' (默认999)
|
||||||
|
* @property {String} type 主题类型,error|warning|success|primary (默认 'error' )
|
||||||
|
* @property {Boolean} showZero 当数值为 0 时,是否展示 Badge (默认 false )
|
||||||
|
* @property {String} bgColor 背景颜色,优先级比type高,如设置,type参数会失效
|
||||||
|
* @property {String} color 字体颜色 (默认 '#ffffff' )
|
||||||
|
* @property {String} shape 徽标形状,circle-四角均为圆角,horn-左下角为直角 (默认 'circle' )
|
||||||
|
* @property {String} numberType 设置数字的显示方式,overflow|ellipsis|limit (默认 'overflow' )
|
||||||
|
* @property {Array}} offset 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效
|
||||||
|
* @property {Boolean} inverted 是否反转背景和字体颜色(默认 false )
|
||||||
|
* @property {Boolean} absolute 是否绝对定位(默认 false )
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
* @example <u-badge :type="type" :count="count"></u-badge>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-badge',
|
||||||
|
mixins: [mpMixin, props, mixin],
|
||||||
|
computed: {
|
||||||
|
// 是否将badge中心与父组件右上角重合
|
||||||
|
boxStyle() {
|
||||||
|
let style = {};
|
||||||
|
return style;
|
||||||
|
},
|
||||||
|
// 整个组件的样式
|
||||||
|
badgeStyle() {
|
||||||
|
const style = {};
|
||||||
|
if (this.color) {
|
||||||
|
style.color = this.color;
|
||||||
|
}
|
||||||
|
if (this.bgColor && !this.inverted) {
|
||||||
|
style.backgroundColor = this.bgColor;
|
||||||
|
}
|
||||||
|
if (this.absolute) {
|
||||||
|
style.position = 'absolute';
|
||||||
|
// 如果有设置offset参数
|
||||||
|
if (this.offset.length) {
|
||||||
|
// top和right分为为offset的第一个和第二个值,如果没有第二个值,则right等于top
|
||||||
|
const top = this.offset[0];
|
||||||
|
const right = this.offset[1] || top;
|
||||||
|
style.top = addUnit(top);
|
||||||
|
style.right = addUnit(right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
},
|
||||||
|
showValue() {
|
||||||
|
switch (this.numberType) {
|
||||||
|
case 'overflow':
|
||||||
|
return Number(this.value) > Number(this.max) ? this.max + '+' : this.value;
|
||||||
|
break;
|
||||||
|
case 'ellipsis':
|
||||||
|
return Number(this.value) > Number(this.max) ? '...' : this.value;
|
||||||
|
break;
|
||||||
|
case 'limit':
|
||||||
|
return Number(this.value) > 999
|
||||||
|
? Number(this.value) >= 9999
|
||||||
|
? Math.floor((this.value / 1e4) * 100) / 100 + 'w'
|
||||||
|
: Math.floor((this.value / 1e3) * 100) / 100 + 'k'
|
||||||
|
: this.value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return Number(this.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addStyle
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../../libs/css/components.scss';
|
||||||
|
|
||||||
|
$u-badge-primary: $u-primary !default;
|
||||||
|
$u-badge-error: $u-error !default;
|
||||||
|
$u-badge-success: $u-success !default;
|
||||||
|
$u-badge-info: $u-info !default;
|
||||||
|
$u-badge-warning: $u-warning !default;
|
||||||
|
$u-badge-dot-radius: 100px !default;
|
||||||
|
$u-badge-dot-size: 8px !default;
|
||||||
|
$u-badge-dot-right: 4px !default;
|
||||||
|
$u-badge-dot-top: 0 !default;
|
||||||
|
$u-badge-text-font-size: 11px !default;
|
||||||
|
$u-badge-text-right: 10px !default;
|
||||||
|
$u-badge-text-padding: 2px 5px !default;
|
||||||
|
$u-badge-text-align: center !default;
|
||||||
|
$u-badge-text-color: #ffffff !default;
|
||||||
|
|
||||||
|
.u-badge {
|
||||||
|
border-top-right-radius: $u-badge-dot-radius;
|
||||||
|
border-top-left-radius: $u-badge-dot-radius;
|
||||||
|
border-bottom-left-radius: $u-badge-dot-radius;
|
||||||
|
border-bottom-right-radius: $u-badge-dot-radius;
|
||||||
|
@include flex;
|
||||||
|
line-height: $u-badge-text-font-size;
|
||||||
|
text-align: $u-badge-text-align;
|
||||||
|
font-size: $u-badge-text-font-size;
|
||||||
|
color: $u-badge-text-color;
|
||||||
|
|
||||||
|
&--dot {
|
||||||
|
height: $u-badge-dot-size;
|
||||||
|
width: $u-badge-dot-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--inverted {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--not-dot {
|
||||||
|
padding: $u-badge-text-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--horn {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--primary {
|
||||||
|
background-color: $u-badge-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--primary--inverted {
|
||||||
|
color: $u-badge-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--error {
|
||||||
|
background-color: $u-badge-error;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--error--inverted {
|
||||||
|
color: $u-badge-error;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success {
|
||||||
|
background-color: $u-badge-success;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success--inverted {
|
||||||
|
color: $u-badge-success;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--info {
|
||||||
|
background-color: $u-badge-info;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--info--inverted {
|
||||||
|
color: $u-badge-info;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--warning {
|
||||||
|
background-color: $u-badge-warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--warning--inverted {
|
||||||
|
color: $u-badge-warning;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
46
uni_modules/uview-plus/components/u-button/nvue.scss
Normal file
46
uni_modules/uview-plus/components/u-button/nvue.scss
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
$u-button-active-opacity:0.75 !default;
|
||||||
|
$u-button-loading-text-margin-left:4px !default;
|
||||||
|
$u-button-text-color: #FFFFFF !default;
|
||||||
|
$u-button-text-plain-error-color:$u-error !default;
|
||||||
|
$u-button-text-plain-warning-color:$u-warning !default;
|
||||||
|
$u-button-text-plain-success-color:$u-success !default;
|
||||||
|
$u-button-text-plain-info-color:$u-info !default;
|
||||||
|
$u-button-text-plain-primary-color:$u-primary !default;
|
||||||
|
.u-button {
|
||||||
|
&--active {
|
||||||
|
opacity: $u-button-active-opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--active--plain {
|
||||||
|
background-color: rgb(217, 217, 217);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__loading-text {
|
||||||
|
margin-left:$u-button-loading-text-margin-left;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text,
|
||||||
|
&__loading-text {
|
||||||
|
color:$u-button-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--plain--error {
|
||||||
|
color:$u-button-text-plain-error-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--plain--warning {
|
||||||
|
color:$u-button-text-plain-warning-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--plain--success{
|
||||||
|
color:$u-button-text-plain-success-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--plain--info {
|
||||||
|
color:$u-button-text-plain-info-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--plain--primary {
|
||||||
|
color:$u-button-text-plain-primary-color;
|
||||||
|
}
|
||||||
|
}
|
153
uni_modules/uview-plus/components/u-button/props.js
Normal file
153
uni_modules/uview-plus/components/u-button/props.js
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 是否细边框
|
||||||
|
hairline: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.button.hairline
|
||||||
|
},
|
||||||
|
// 按钮的预置样式,info,primary,error,warning,success
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.type
|
||||||
|
},
|
||||||
|
// 按钮尺寸,large,normal,small,mini
|
||||||
|
size: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.size
|
||||||
|
},
|
||||||
|
// 按钮形状,circle(两边为半圆),square(带圆角)
|
||||||
|
shape: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.shape
|
||||||
|
},
|
||||||
|
// 按钮是否镂空
|
||||||
|
plain: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.button.plain
|
||||||
|
},
|
||||||
|
// 是否禁止状态
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.button.disabled
|
||||||
|
},
|
||||||
|
// 是否加载中
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.button.loading
|
||||||
|
},
|
||||||
|
// 加载中提示文字
|
||||||
|
loadingText: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.button.loadingText
|
||||||
|
},
|
||||||
|
// 加载状态图标类型
|
||||||
|
loadingMode: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.loadingMode
|
||||||
|
},
|
||||||
|
// 加载图标大小
|
||||||
|
loadingSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.button.loadingSize
|
||||||
|
},
|
||||||
|
// 开放能力,具体请看uniapp稳定关于button组件部分说明
|
||||||
|
// https://uniapp.dcloud.io/component/button
|
||||||
|
openType: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.openType
|
||||||
|
},
|
||||||
|
// 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件
|
||||||
|
// 取值为submit(提交表单),reset(重置表单)
|
||||||
|
formType: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.formType
|
||||||
|
},
|
||||||
|
// 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效
|
||||||
|
// 只微信小程序、QQ小程序有效
|
||||||
|
appParameter: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.appParameter
|
||||||
|
},
|
||||||
|
// 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效
|
||||||
|
hoverStopPropagation: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.button.hoverStopPropagation
|
||||||
|
},
|
||||||
|
// 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效
|
||||||
|
lang: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.lang
|
||||||
|
},
|
||||||
|
// 会话来源,open-type="contact"时有效。只微信小程序有效
|
||||||
|
sessionFrom: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.sessionFrom
|
||||||
|
},
|
||||||
|
// 会话内消息卡片标题,open-type="contact"时有效
|
||||||
|
// 默认当前标题,只微信小程序有效
|
||||||
|
sendMessageTitle: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.sendMessageTitle
|
||||||
|
},
|
||||||
|
// 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效
|
||||||
|
// 默认当前分享路径,只微信小程序有效
|
||||||
|
sendMessagePath: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.sendMessagePath
|
||||||
|
},
|
||||||
|
// 会话内消息卡片图片,open-type="contact"时有效
|
||||||
|
// 默认当前页面截图,只微信小程序有效
|
||||||
|
sendMessageImg: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.sendMessageImg
|
||||||
|
},
|
||||||
|
// 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,
|
||||||
|
// 用户点击后可以快速发送小程序消息,open-type="contact"时有效
|
||||||
|
showMessageCard: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.button.showMessageCard
|
||||||
|
},
|
||||||
|
// 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
|
||||||
|
dataName: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.dataName
|
||||||
|
},
|
||||||
|
// 节流,一定时间内只能触发一次
|
||||||
|
throttleTime: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.button.throttleTime
|
||||||
|
},
|
||||||
|
// 按住后多久出现点击态,单位毫秒
|
||||||
|
hoverStartTime: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.button.hoverStartTime
|
||||||
|
},
|
||||||
|
// 手指松开后点击态保留时间,单位毫秒
|
||||||
|
hoverStayTime: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.button.hoverStayTime
|
||||||
|
},
|
||||||
|
// 按钮文字,之所以通过props传入,是因为slot传入的话
|
||||||
|
// nvue中无法控制文字的样式
|
||||||
|
text: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.button.text
|
||||||
|
},
|
||||||
|
// 按钮图标
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.icon
|
||||||
|
},
|
||||||
|
// 按钮图标
|
||||||
|
iconColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.icon
|
||||||
|
},
|
||||||
|
// 按钮颜色,支持传入linear-gradient渐变色
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.button.color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
503
uni_modules/uview-plus/components/u-button/u-button.vue
Normal file
503
uni_modules/uview-plus/components/u-button/u-button.vue
Normal file
|
@ -0,0 +1,503 @@
|
||||||
|
<template>
|
||||||
|
<!-- #ifndef APP-NVUE -->
|
||||||
|
<button
|
||||||
|
:hover-start-time="Number(hoverStartTime)"
|
||||||
|
:hover-stay-time="Number(hoverStayTime)"
|
||||||
|
:form-type="formType"
|
||||||
|
:open-type="openType"
|
||||||
|
:app-parameter="appParameter"
|
||||||
|
:hover-stop-propagation="hoverStopPropagation"
|
||||||
|
:send-message-title="sendMessageTitle"
|
||||||
|
:send-message-path="sendMessagePath"
|
||||||
|
:lang="lang"
|
||||||
|
:data-name="dataName"
|
||||||
|
:session-from="sessionFrom"
|
||||||
|
:send-message-img="sendMessageImg"
|
||||||
|
:show-message-card="showMessageCard"
|
||||||
|
@getphonenumber="getphonenumber"
|
||||||
|
@getuserinfo="getuserinfo"
|
||||||
|
@error="error"
|
||||||
|
@opensetting="opensetting"
|
||||||
|
@launchapp="launchapp"
|
||||||
|
@agreeprivacyauthorization="agreeprivacyauthorization"
|
||||||
|
:hover-class="!disabled && !loading ? 'u-button--active' : ''"
|
||||||
|
class="u-button u-reset-button"
|
||||||
|
:style="[baseColor, addStyle(customStyle)]"
|
||||||
|
@tap="clickHandler"
|
||||||
|
:class="bemClass"
|
||||||
|
>
|
||||||
|
<template v-if="loading">
|
||||||
|
<u-loading-icon
|
||||||
|
:mode="loadingMode"
|
||||||
|
:size="loadingSize * 1.15"
|
||||||
|
:color="loadingColor"
|
||||||
|
></u-loading-icon>
|
||||||
|
<text
|
||||||
|
class="u-button__loading-text"
|
||||||
|
:style="[{ fontSize: textSize + 'px' }]"
|
||||||
|
>{{ loadingText || text }}</text
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<u-icon
|
||||||
|
v-if="icon"
|
||||||
|
:name="icon"
|
||||||
|
:color="iconColorCom"
|
||||||
|
:size="textSize * 1.35"
|
||||||
|
:customStyle="{ marginRight: '2px' }"
|
||||||
|
></u-icon>
|
||||||
|
<slot>
|
||||||
|
<text
|
||||||
|
class="u-button__text"
|
||||||
|
:style="[{ fontSize: textSize + 'px' }]"
|
||||||
|
>{{ text }}</text
|
||||||
|
>
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
</button>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
<!-- #ifdef APP-NVUE -->
|
||||||
|
<view
|
||||||
|
:hover-start-time="Number(hoverStartTime)"
|
||||||
|
:hover-stay-time="Number(hoverStayTime)"
|
||||||
|
class="u-button"
|
||||||
|
:hover-class="
|
||||||
|
!disabled && !loading && !color && (plain || type === 'info')
|
||||||
|
? 'u-button--active--plain'
|
||||||
|
: !disabled && !loading && !plain
|
||||||
|
? 'u-button--active'
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
@tap="clickHandler"
|
||||||
|
:class="bemClass"
|
||||||
|
:style="[baseColor, addStyle(customStyle)]"
|
||||||
|
>
|
||||||
|
<template v-if="loading">
|
||||||
|
<u-loading-icon
|
||||||
|
:mode="loadingMode"
|
||||||
|
:size="loadingSize * 1.15"
|
||||||
|
:color="loadingColor"
|
||||||
|
></u-loading-icon>
|
||||||
|
<text
|
||||||
|
class="u-button__loading-text"
|
||||||
|
:style="[nvueTextStyle]"
|
||||||
|
:class="[plain && `u-button__text--plain--${type}`]"
|
||||||
|
>{{ loadingText || text }}</text
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<u-icon
|
||||||
|
v-if="icon"
|
||||||
|
:name="icon"
|
||||||
|
:color="iconColorCom"
|
||||||
|
:size="textSize * 1.35"
|
||||||
|
></u-icon>
|
||||||
|
<text
|
||||||
|
class="u-button__text"
|
||||||
|
:style="[
|
||||||
|
{
|
||||||
|
marginLeft: icon ? '2px' : 0,
|
||||||
|
},
|
||||||
|
nvueTextStyle,
|
||||||
|
]"
|
||||||
|
:class="[plain && `u-button__text--plain--${type}`]"
|
||||||
|
>{{ text }}</text
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import button from "../../libs/mixin/button";
|
||||||
|
import openType from "../../libs/mixin/openType";
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import props from "./props";
|
||||||
|
import { addStyle } from '../../libs/function/index';
|
||||||
|
import { throttle } from '../../libs/function/throttle';
|
||||||
|
import color from '../../libs/config/color';
|
||||||
|
/**
|
||||||
|
* button 按钮
|
||||||
|
* @description Button 按钮
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/button.html
|
||||||
|
*
|
||||||
|
* @property {Boolean} hairline 是否显示按钮的细边框 (默认 true )
|
||||||
|
* @property {String} type 按钮的预置样式,info,primary,error,warning,success (默认 'info' )
|
||||||
|
* @property {String} size 按钮尺寸,large,normal,mini (默认 normal)
|
||||||
|
* @property {String} shape 按钮形状,circle(两边为半圆),square(带圆角) (默认 'square' )
|
||||||
|
* @property {Boolean} plain 按钮是否镂空,背景色透明 (默认 false)
|
||||||
|
* @property {Boolean} disabled 是否禁用 (默认 false)
|
||||||
|
* @property {Boolean} loading 按钮名称前是否带 loading 图标(App-nvue 平台,在 ios 上为雪花,Android上为圆圈) (默认 false)
|
||||||
|
* @property {String | Number} loadingText 加载中提示文字
|
||||||
|
* @property {String} loadingMode 加载状态图标类型 (默认 'spinner' )
|
||||||
|
* @property {String | Number} loadingSize 加载图标大小 (默认 15 )
|
||||||
|
* @property {String} openType 开放能力,具体请看uniapp稳定关于button组件部分说明
|
||||||
|
* @property {String} formType 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件
|
||||||
|
* @property {String} appParameter 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 (注:只微信小程序、QQ小程序有效)
|
||||||
|
* @property {Boolean} hoverStopPropagation 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效(默认 true )
|
||||||
|
* @property {String} lang 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文(默认 en )
|
||||||
|
* @property {String} sessionFrom 会话来源,openType="contact"时有效
|
||||||
|
* @property {String} sendMessageTitle 会话内消息卡片标题,openType="contact"时有效
|
||||||
|
* @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径,openType="contact"时有效
|
||||||
|
* @property {String} sendMessageImg 会话内消息卡片图片,openType="contact"时有效
|
||||||
|
* @property {Boolean} showMessageCard 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效(默认false)
|
||||||
|
* @property {String} dataName 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
|
||||||
|
* @property {String | Number} throttleTime 节流,一定时间内只能触发一次 (默认 0 )
|
||||||
|
* @property {String | Number} hoverStartTime 按住后多久出现点击态,单位毫秒 (默认 0 )
|
||||||
|
* @property {String | Number} hoverStayTime 手指松开后点击态保留时间,单位毫秒 (默认 200 )
|
||||||
|
* @property {String | Number} text 按钮文字,之所以通过props传入,是因为slot传入的话(注:nvue中无法控制文字的样式)
|
||||||
|
* @property {String} icon 按钮图标
|
||||||
|
* @property {String} iconColor 按钮图标颜色
|
||||||
|
* @property {String} color 按钮颜色,支持传入linear-gradient渐变色
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
*
|
||||||
|
* @event {Function} click 非禁止并且非加载中,才能点击
|
||||||
|
* @event {Function} getphonenumber open-type="getPhoneNumber"时有效
|
||||||
|
* @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,从返回参数的detail中获取到的值同uni.getUserInfo
|
||||||
|
* @event {Function} error 当使用开放能力时,发生错误的回调
|
||||||
|
* @event {Function} opensetting 在打开授权设置页并关闭后回调
|
||||||
|
* @event {Function} launchapp 打开 APP 成功的回调
|
||||||
|
* @event {Function} agreeprivacyauthorization 用户同意隐私协议事件回调
|
||||||
|
* @example <u-button>月落</u-button>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: "u-button",
|
||||||
|
// #ifdef MP
|
||||||
|
mixins: [mpMixin, mixin, button, openType, props],
|
||||||
|
// #endif
|
||||||
|
// #ifndef MP
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
// #endif
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 生成bem风格的类名
|
||||||
|
bemClass() {
|
||||||
|
// this.bem为一个computed变量,在mixin中
|
||||||
|
if (!this.color) {
|
||||||
|
return this.bem(
|
||||||
|
"button",
|
||||||
|
["type", "shape", "size"],
|
||||||
|
["disabled", "plain", "hairline"]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// 由于nvue的原因,在有color参数时,不需要传入type,否则会生成type相关的类型,影响最终的样式
|
||||||
|
return this.bem(
|
||||||
|
"button",
|
||||||
|
["shape", "size"],
|
||||||
|
["disabled", "plain", "hairline"]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loadingColor() {
|
||||||
|
if (this.plain) {
|
||||||
|
// 如果有设置color值,则用color值,否则使用type主题颜色
|
||||||
|
return this.color
|
||||||
|
? this.color
|
||||||
|
: color[`u-${this.type}`];
|
||||||
|
}
|
||||||
|
if (this.type === "info") {
|
||||||
|
return "#c9c9c9";
|
||||||
|
}
|
||||||
|
return "rgb(200, 200, 200)";
|
||||||
|
},
|
||||||
|
iconColorCom() {
|
||||||
|
// 如果是镂空状态,设置了color就用color值,否则使用主题颜色,
|
||||||
|
// u-icon的color能接受一个主题颜色的值
|
||||||
|
if (this.iconColor) return this.iconColor;
|
||||||
|
if (this.plain) {
|
||||||
|
return this.color ? this.color : this.type;
|
||||||
|
} else {
|
||||||
|
return this.type === "info" ? "#000000" : "#ffffff";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
baseColor() {
|
||||||
|
let style = {};
|
||||||
|
if (this.color) {
|
||||||
|
// 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
|
||||||
|
style.color = this.plain ? this.color : "white";
|
||||||
|
if (!this.plain) {
|
||||||
|
// 非镂空,背景色使用自定义的颜色
|
||||||
|
style["background-color"] = this.color;
|
||||||
|
}
|
||||||
|
if (this.color.indexOf("gradient") !== -1) {
|
||||||
|
// 如果自定义的颜色为渐变色,不显示边框,以及通过backgroundImage设置渐变色
|
||||||
|
// weex文档说明可以写borderWidth的形式,为什么这里需要分开写?
|
||||||
|
// 因为weex是阿里巴巴为了部门业绩考核而做的你懂的东西,所以需要这么写才有效
|
||||||
|
style.borderTopWidth = 0;
|
||||||
|
style.borderRightWidth = 0;
|
||||||
|
style.borderBottomWidth = 0;
|
||||||
|
style.borderLeftWidth = 0;
|
||||||
|
if (!this.plain) {
|
||||||
|
style.backgroundImage = this.color;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 非渐变色,则设置边框相关的属性
|
||||||
|
style.borderColor = this.color;
|
||||||
|
style.borderWidth = "1px";
|
||||||
|
style.borderStyle = "solid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
},
|
||||||
|
// nvue版本按钮的字体不会继承父组件的颜色,需要对每一个text组件进行单独的设置
|
||||||
|
nvueTextStyle() {
|
||||||
|
let style = {};
|
||||||
|
// 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
|
||||||
|
if (this.type === "info") {
|
||||||
|
style.color = "#323233";
|
||||||
|
}
|
||||||
|
if (this.color) {
|
||||||
|
style.color = this.plain ? this.color : "white";
|
||||||
|
}
|
||||||
|
style.fontSize = this.textSize + "px";
|
||||||
|
return style;
|
||||||
|
},
|
||||||
|
// 字体大小
|
||||||
|
textSize() {
|
||||||
|
let fontSize = 14,
|
||||||
|
{ size } = this;
|
||||||
|
if (size === "large") fontSize = 16;
|
||||||
|
if (size === "normal") fontSize = 14;
|
||||||
|
if (size === "small") fontSize = 12;
|
||||||
|
if (size === "mini") fontSize = 10;
|
||||||
|
return fontSize;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ['click', 'getphonenumber', 'getuserinfo',
|
||||||
|
'error', 'opensetting', 'launchapp', 'agreeprivacyauthorization'],
|
||||||
|
methods: {
|
||||||
|
addStyle,
|
||||||
|
clickHandler() {
|
||||||
|
// 非禁止并且非加载中,才能点击
|
||||||
|
if (!this.disabled && !this.loading) {
|
||||||
|
// 进行节流控制,每this.throttle毫秒内,只在开始处执行
|
||||||
|
throttle(() => {
|
||||||
|
this.$emit("click");
|
||||||
|
}, this.throttleTime);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 下面为对接uniapp官方按钮开放能力事件回调的对接
|
||||||
|
getphonenumber(res: any) {
|
||||||
|
this.$emit("getphonenumber", res);
|
||||||
|
},
|
||||||
|
getuserinfo(res: any) {
|
||||||
|
this.$emit("getuserinfo", res);
|
||||||
|
},
|
||||||
|
error(res: any) {
|
||||||
|
this.$emit("error", res);
|
||||||
|
},
|
||||||
|
opensetting(res: any) {
|
||||||
|
this.$emit("opensetting", res);
|
||||||
|
},
|
||||||
|
launchapp(res: any) {
|
||||||
|
this.$emit("launchapp", res);
|
||||||
|
},
|
||||||
|
agreeprivacyauthorization(res) {
|
||||||
|
this.$emit("agreeprivacyauthorization", res);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
@import "./vue.scss";
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
@import "./nvue.scss";
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
$u-button-u-button-height: 40px !default;
|
||||||
|
$u-button-text-font-size: 15px !default;
|
||||||
|
$u-button-loading-text-font-size: 15px !default;
|
||||||
|
$u-button-loading-text-margin-left: 4px !default;
|
||||||
|
$u-button-large-width: 100% !default;
|
||||||
|
$u-button-large-height: 50px !default;
|
||||||
|
$u-button-normal-padding: 0 12px !default;
|
||||||
|
$u-button-large-padding: 0 15px !default;
|
||||||
|
$u-button-normal-font-size: 14px !default;
|
||||||
|
$u-button-small-min-width: 60px !default;
|
||||||
|
$u-button-small-height: 30px !default;
|
||||||
|
$u-button-small-padding: 0px 8px !default;
|
||||||
|
$u-button-mini-padding: 0px 8px !default;
|
||||||
|
$u-button-small-font-size: 12px !default;
|
||||||
|
$u-button-mini-height: 22px !default;
|
||||||
|
$u-button-mini-font-size: 10px !default;
|
||||||
|
$u-button-mini-min-width: 50px !default;
|
||||||
|
$u-button-disabled-opacity: 0.5 !default;
|
||||||
|
$u-button-info-color: #323233 !default;
|
||||||
|
$u-button-info-background-color: #fff !default;
|
||||||
|
$u-button-info-border-color: #ebedf0 !default;
|
||||||
|
$u-button-info-border-width: 1px !default;
|
||||||
|
$u-button-info-border-style: solid !default;
|
||||||
|
$u-button-success-color: #fff !default;
|
||||||
|
$u-button-success-background-color: $u-success !default;
|
||||||
|
$u-button-success-border-color: $u-button-success-background-color !default;
|
||||||
|
$u-button-success-border-width: 1px !default;
|
||||||
|
$u-button-success-border-style: solid !default;
|
||||||
|
$u-button-primary-color: #fff !default;
|
||||||
|
$u-button-primary-background-color: $u-primary !default;
|
||||||
|
$u-button-primary-border-color: $u-button-primary-background-color !default;
|
||||||
|
$u-button-primary-border-width: 1px !default;
|
||||||
|
$u-button-primary-border-style: solid !default;
|
||||||
|
$u-button-error-color: #fff !default;
|
||||||
|
$u-button-error-background-color: $u-error !default;
|
||||||
|
$u-button-error-border-color: $u-button-error-background-color !default;
|
||||||
|
$u-button-error-border-width: 1px !default;
|
||||||
|
$u-button-error-border-style: solid !default;
|
||||||
|
$u-button-warning-color: #fff !default;
|
||||||
|
$u-button-warning-background-color: $u-warning !default;
|
||||||
|
$u-button-warning-border-color: $u-button-warning-background-color !default;
|
||||||
|
$u-button-warning-border-width: 1px !default;
|
||||||
|
$u-button-warning-border-style: solid !default;
|
||||||
|
$u-button-block-width: 100% !default;
|
||||||
|
$u-button-circle-border-top-right-radius: 100px !default;
|
||||||
|
$u-button-circle-border-top-left-radius: 100px !default;
|
||||||
|
$u-button-circle-border-bottom-left-radius: 100px !default;
|
||||||
|
$u-button-circle-border-bottom-right-radius: 100px !default;
|
||||||
|
$u-button-square-border-top-right-radius: 3px !default;
|
||||||
|
$u-button-square-border-top-left-radius: 3px !default;
|
||||||
|
$u-button-square-border-bottom-left-radius: 3px !default;
|
||||||
|
$u-button-square-border-bottom-right-radius: 3px !default;
|
||||||
|
$u-button-icon-min-width: 1em !default;
|
||||||
|
$u-button-plain-background-color: #fff !default;
|
||||||
|
$u-button-hairline-border-width: 0.5px !default;
|
||||||
|
|
||||||
|
.u-button {
|
||||||
|
height: $u-button-u-button-height;
|
||||||
|
position: relative;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
@include flex;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
font-size: $u-button-text-font-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__loading-text {
|
||||||
|
font-size: $u-button-loading-text-font-size;
|
||||||
|
margin-left: $u-button-loading-text-margin-left;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--large {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
width: $u-button-large-width;
|
||||||
|
/* #endif */
|
||||||
|
height: $u-button-large-height;
|
||||||
|
padding: $u-button-large-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--normal {
|
||||||
|
padding: $u-button-normal-padding;
|
||||||
|
font-size: $u-button-normal-font-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--small {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
min-width: $u-button-small-min-width;
|
||||||
|
/* #endif */
|
||||||
|
height: $u-button-small-height;
|
||||||
|
padding: $u-button-small-padding;
|
||||||
|
font-size: $u-button-small-font-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--mini {
|
||||||
|
height: $u-button-mini-height;
|
||||||
|
font-size: $u-button-mini-font-size;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
min-width: $u-button-mini-min-width;
|
||||||
|
/* #endif */
|
||||||
|
padding: $u-button-mini-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
opacity: $u-button-disabled-opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--info {
|
||||||
|
color: $u-button-info-color;
|
||||||
|
background-color: $u-button-info-background-color;
|
||||||
|
border-color: $u-button-info-border-color;
|
||||||
|
border-width: $u-button-info-border-width;
|
||||||
|
border-style: $u-button-info-border-style;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success {
|
||||||
|
color: $u-button-success-color;
|
||||||
|
background-color: $u-button-success-background-color;
|
||||||
|
border-color: $u-button-success-border-color;
|
||||||
|
border-width: $u-button-success-border-width;
|
||||||
|
border-style: $u-button-success-border-style;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--primary {
|
||||||
|
color: $u-button-primary-color;
|
||||||
|
background-color: $u-button-primary-background-color;
|
||||||
|
border-color: $u-button-primary-border-color;
|
||||||
|
border-width: $u-button-primary-border-width;
|
||||||
|
border-style: $u-button-primary-border-style;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--error {
|
||||||
|
color: $u-button-error-color;
|
||||||
|
background-color: $u-button-error-background-color;
|
||||||
|
border-color: $u-button-error-border-color;
|
||||||
|
border-width: $u-button-error-border-width;
|
||||||
|
border-style: $u-button-error-border-style;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--warning {
|
||||||
|
color: $u-button-warning-color;
|
||||||
|
background-color: $u-button-warning-background-color;
|
||||||
|
border-color: $u-button-warning-border-color;
|
||||||
|
border-width: $u-button-warning-border-width;
|
||||||
|
border-style: $u-button-warning-border-style;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--block {
|
||||||
|
@include flex;
|
||||||
|
width: $u-button-block-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--circle {
|
||||||
|
border-top-right-radius: $u-button-circle-border-top-right-radius;
|
||||||
|
border-top-left-radius: $u-button-circle-border-top-left-radius;
|
||||||
|
border-bottom-left-radius: $u-button-circle-border-bottom-left-radius;
|
||||||
|
border-bottom-right-radius: $u-button-circle-border-bottom-right-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--square {
|
||||||
|
border-bottom-left-radius: $u-button-square-border-top-right-radius;
|
||||||
|
border-bottom-right-radius: $u-button-square-border-top-left-radius;
|
||||||
|
border-top-left-radius: $u-button-square-border-bottom-left-radius;
|
||||||
|
border-top-right-radius: $u-button-square-border-bottom-right-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
min-width: $u-button-icon-min-width;
|
||||||
|
line-height: inherit !important;
|
||||||
|
vertical-align: top;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
background-color: $u-button-plain-background-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--hairline {
|
||||||
|
border-width: $u-button-hairline-border-width !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
81
uni_modules/uview-plus/components/u-button/vue.scss
Normal file
81
uni_modules/uview-plus/components/u-button/vue.scss
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
// nvue下hover-class无效
|
||||||
|
$u-button-before-top:50% !default;
|
||||||
|
$u-button-before-left:50% !default;
|
||||||
|
$u-button-before-width:100% !default;
|
||||||
|
$u-button-before-height:100% !default;
|
||||||
|
$u-button-before-transform:translate(-50%, -50%) !default;
|
||||||
|
$u-button-before-opacity:0 !default;
|
||||||
|
$u-button-before-background-color:#000 !default;
|
||||||
|
$u-button-before-border-color:#000 !default;
|
||||||
|
$u-button-active-before-opacity:.15 !default;
|
||||||
|
$u-button-icon-margin-left:4px !default;
|
||||||
|
$u-button-plain-u-button-info-color:$u-info;
|
||||||
|
$u-button-plain-u-button-success-color:$u-success;
|
||||||
|
$u-button-plain-u-button-error-color:$u-error;
|
||||||
|
$u-button-plain-u-button-warning-color:$u-error;
|
||||||
|
|
||||||
|
.u-button {
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
position: absolute;
|
||||||
|
top:$u-button-before-top;
|
||||||
|
left:$u-button-before-left;
|
||||||
|
width:$u-button-before-width;
|
||||||
|
height:$u-button-before-height;
|
||||||
|
border: inherit;
|
||||||
|
border-radius: inherit;
|
||||||
|
transform:$u-button-before-transform;
|
||||||
|
opacity:$u-button-before-opacity;
|
||||||
|
content: " ";
|
||||||
|
background-color:$u-button-before-background-color;
|
||||||
|
border-color:$u-button-before-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
&:before {
|
||||||
|
opacity: .15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon+&__text:not(:empty),
|
||||||
|
&__loading-text {
|
||||||
|
margin-left:$u-button-icon-margin-left;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
&.u-button--primary {
|
||||||
|
color: $u-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
&.u-button--info {
|
||||||
|
color:$u-button-plain-u-button-info-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
&.u-button--success {
|
||||||
|
color:$u-button-plain-u-button-success-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
&.u-button--error {
|
||||||
|
color:$u-button-plain-u-button-error-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
&.u-button--warning {
|
||||||
|
color:$u-button-plain-u-button-warning-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
101
uni_modules/uview-plus/components/u-calendar/header.vue
Normal file
101
uni_modules/uview-plus/components/u-calendar/header.vue
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
<template>
|
||||||
|
<view class="u-calendar-header u-border-bottom">
|
||||||
|
<text
|
||||||
|
class="u-calendar-header__title"
|
||||||
|
v-if="showTitle"
|
||||||
|
>{{ title }}</text>
|
||||||
|
<text
|
||||||
|
class="u-calendar-header__subtitle"
|
||||||
|
v-if="showSubtitle"
|
||||||
|
>{{ subtitle }}</text>
|
||||||
|
<view class="u-calendar-header__weekdays">
|
||||||
|
<text class="u-calendar-header__weekdays__weekday">一</text>
|
||||||
|
<text class="u-calendar-header__weekdays__weekday">二</text>
|
||||||
|
<text class="u-calendar-header__weekdays__weekday">三</text>
|
||||||
|
<text class="u-calendar-header__weekdays__weekday">四</text>
|
||||||
|
<text class="u-calendar-header__weekdays__weekday">五</text>
|
||||||
|
<text class="u-calendar-header__weekdays__weekday">六</text>
|
||||||
|
<text class="u-calendar-header__weekdays__weekday">日</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
export default {
|
||||||
|
name: 'u-calendar-header',
|
||||||
|
mixins: [mpMixin, mixin],
|
||||||
|
props: {
|
||||||
|
// 标题
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 副标题
|
||||||
|
subtitle: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 是否显示标题
|
||||||
|
showTitle: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 是否显示副标题
|
||||||
|
showSubtitle: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
name() {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
.u-calendar-header {
|
||||||
|
padding-bottom: 4px;
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
font-size: 16px;
|
||||||
|
color: $u-main-color;
|
||||||
|
text-align: center;
|
||||||
|
height: 42px;
|
||||||
|
line-height: 42px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: $u-main-color;
|
||||||
|
height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 40px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__weekdays {
|
||||||
|
@include flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
&__weekday {
|
||||||
|
font-size: 13px;
|
||||||
|
color: $u-main-color;
|
||||||
|
line-height: 30px;
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
585
uni_modules/uview-plus/components/u-calendar/month.vue
Normal file
585
uni_modules/uview-plus/components/u-calendar/month.vue
Normal file
|
@ -0,0 +1,585 @@
|
||||||
|
<template>
|
||||||
|
<view class="u-calendar-month-wrapper" ref="u-calendar-month-wrapper">
|
||||||
|
<view v-for="(item, index) in months" :key="index" :class="[`u-calendar-month-${index}`]"
|
||||||
|
:ref="`u-calendar-month-${index}`" :id="`month-${index}`">
|
||||||
|
<text v-if="index !== 0" class="u-calendar-month__title">{{ item.year }}年{{ item.month }}月</text>
|
||||||
|
<view class="u-calendar-month__days">
|
||||||
|
<view v-if="showMark" class="u-calendar-month__days__month-mark-wrapper">
|
||||||
|
<text class="u-calendar-month__days__month-mark-wrapper__text">{{ item.month }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="u-calendar-month__days__day" v-for="(item1, index1) in item.date" :key="index1"
|
||||||
|
:style="[dayStyle(index, index1, item1)]" @tap="clickHandler(index, index1, item1)"
|
||||||
|
:class="[item1.selected && 'u-calendar-month__days__day__select--selected']">
|
||||||
|
<view class="u-calendar-month__days__day__select" :style="[daySelectStyle(index, index1, item1)]">
|
||||||
|
<text class="u-calendar-month__days__day__select__info"
|
||||||
|
:class="[item1.disabled && 'u-calendar-month__days__day__select__info--disabled']"
|
||||||
|
:style="[textStyle(item1)]">{{ item1.day }}</text>
|
||||||
|
<text v-if="getBottomInfo(index, index1, item1)"
|
||||||
|
class="u-calendar-month__days__day__select__buttom-info"
|
||||||
|
:class="[item1.disabled && 'u-calendar-month__days__day__select__buttom-info--disabled']"
|
||||||
|
:style="[textStyle(item1)]">{{ getBottomInfo(index, index1, item1) }}</text>
|
||||||
|
<text v-if="item1.dot" class="u-calendar-month__days__day__select__dot"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
// 由于nvue不支持百分比单位,需要查询宽度来计算每个日期的宽度
|
||||||
|
const dom = uni.requireNativePlugin('dom')
|
||||||
|
// #endif
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addUnit, deepClone, toast, sleep } from '../../libs/function/index';
|
||||||
|
import { colorGradient } from '../../libs/function/colorGradient';
|
||||||
|
import test from '../../libs/function/test';
|
||||||
|
import defProps from '../../libs/config/props';
|
||||||
|
import dayjs from 'dayjs/esm/index'
|
||||||
|
export default {
|
||||||
|
name: 'u-calendar-month',
|
||||||
|
mixins: [mpMixin, mixin],
|
||||||
|
props: {
|
||||||
|
// 是否显示月份背景色
|
||||||
|
showMark: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 主题色,对底部按钮和选中日期有效
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: '#3c9cff'
|
||||||
|
},
|
||||||
|
// 月份数据
|
||||||
|
months: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
// 日期选择类型
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'single'
|
||||||
|
},
|
||||||
|
// 日期行高
|
||||||
|
rowHeight: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 58
|
||||||
|
},
|
||||||
|
// mode=multiple时,最多可选多少个日期
|
||||||
|
maxCount: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: Infinity
|
||||||
|
},
|
||||||
|
// mode=range时,第一个日期底部的提示文字
|
||||||
|
startText: {
|
||||||
|
type: String,
|
||||||
|
default: '开始'
|
||||||
|
},
|
||||||
|
// mode=range时,最后一个日期底部的提示文字
|
||||||
|
endText: {
|
||||||
|
type: String,
|
||||||
|
default: '结束'
|
||||||
|
},
|
||||||
|
// 默认选中的日期,mode为multiple或range是必须为数组格式
|
||||||
|
defaultDate: {
|
||||||
|
type: [Array, String, Date],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
// 最小的可选日期
|
||||||
|
minDate: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
// 最大可选日期
|
||||||
|
maxDate: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
// 如果没有设置maxDate,则往后推多少个月
|
||||||
|
maxMonth: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 2
|
||||||
|
},
|
||||||
|
// 是否为只读状态,只读状态下禁止选择日期
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.calendar.readonly
|
||||||
|
},
|
||||||
|
// 日期区间最多可选天数,默认无限制,mode = range时有效
|
||||||
|
maxRange: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: Infinity
|
||||||
|
},
|
||||||
|
// 范围选择超过最多可选天数时的提示文案,mode = range时有效
|
||||||
|
rangePrompt: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效
|
||||||
|
showRangePrompt: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 是否允许日期范围的起止时间为同一天,mode = range时有效
|
||||||
|
allowSameDay: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 每个日期的宽度
|
||||||
|
width: 0,
|
||||||
|
// 当前选中的日期item
|
||||||
|
item: {},
|
||||||
|
selected: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
selectedChange: {
|
||||||
|
immediate: true,
|
||||||
|
handler(n) {
|
||||||
|
this.setDefaultDate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 多个条件的变化,会引起选中日期的变化,这里统一管理监听
|
||||||
|
selectedChange() {
|
||||||
|
return [this.minDate, this.maxDate, this.defaultDate]
|
||||||
|
},
|
||||||
|
dayStyle(index1, index2, item) {
|
||||||
|
return (index1, index2, item) => {
|
||||||
|
const style = {}
|
||||||
|
let week = item.week
|
||||||
|
// 不进行四舍五入的形式保留2位小数
|
||||||
|
const dayWidth = Number(parseFloat(this.width / 7).toFixed(3).slice(0, -1))
|
||||||
|
// 得出每个日期的宽度
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
style.width = addUnit(dayWidth)
|
||||||
|
// #endif
|
||||||
|
style.height = addUnit(this.rowHeight)
|
||||||
|
if (index2 === 0) {
|
||||||
|
// 获取当前为星期几,如果为0,则为星期天,减一为每月第一天时,需要向左偏移的item个数
|
||||||
|
week = (week === 0 ? 7 : week) - 1
|
||||||
|
style.marginLeft = addUnit(week * dayWidth)
|
||||||
|
}
|
||||||
|
if (this.mode === 'range') {
|
||||||
|
// 之所以需要这么写,是因为DCloud公司的iOS客户端的开发者能力有限导致的bug
|
||||||
|
style.paddingLeft = 0
|
||||||
|
style.paddingRight = 0
|
||||||
|
style.paddingBottom = 0
|
||||||
|
style.paddingTop = 0
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
},
|
||||||
|
daySelectStyle() {
|
||||||
|
return (index1, index2, item) => {
|
||||||
|
let date = dayjs(item.date).format("YYYY-MM-DD"),
|
||||||
|
style = {}
|
||||||
|
// 判断date是否在selected数组中,因为月份可能会需要补0,所以使用dateSame判断,而不用数组的includes判断
|
||||||
|
if (this.selected.some(item => this.dateSame(item, date))) {
|
||||||
|
style.backgroundColor = this.color
|
||||||
|
}
|
||||||
|
if (this.mode === 'single') {
|
||||||
|
if (date === this.selected[0]) {
|
||||||
|
// 因为需要对nvue的兼容,只能这么写,无法缩写,也无法通过类名控制等等
|
||||||
|
style.borderTopLeftRadius = '3px'
|
||||||
|
style.borderBottomLeftRadius = '3px'
|
||||||
|
style.borderTopRightRadius = '3px'
|
||||||
|
style.borderBottomRightRadius = '3px'
|
||||||
|
}
|
||||||
|
} else if (this.mode === 'range') {
|
||||||
|
if (this.selected.length >= 2) {
|
||||||
|
const len = this.selected.length - 1
|
||||||
|
// 第一个日期设置左上角和左下角的圆角
|
||||||
|
if (this.dateSame(date, this.selected[0])) {
|
||||||
|
style.borderTopLeftRadius = '3px'
|
||||||
|
style.borderBottomLeftRadius = '3px'
|
||||||
|
}
|
||||||
|
// 最后一个日期设置右上角和右下角的圆角
|
||||||
|
if (this.dateSame(date, this.selected[len])) {
|
||||||
|
style.borderTopRightRadius = '3px'
|
||||||
|
style.borderBottomRightRadius = '3px'
|
||||||
|
}
|
||||||
|
// 处于第一和最后一个之间的日期,背景色设置为浅色,通过将对应颜色进行等分,再取其尾部的颜色值
|
||||||
|
if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
|
||||||
|
.selected[len]))) {
|
||||||
|
style.backgroundColor = colorGradient(this.color, '#ffffff', 100)[90]
|
||||||
|
// 增加一个透明度,让范围区间的背景色也能看到底部的mark水印字符
|
||||||
|
style.opacity = 0.7
|
||||||
|
}
|
||||||
|
} else if (this.selected.length === 1) {
|
||||||
|
// 之所以需要这么写,是因为DCloud公司的iOS客户端的开发者能力有限导致的bug
|
||||||
|
// 进行还原操作,否则在nvue的iOS,uni-app有bug,会导致诡异的表现
|
||||||
|
style.borderTopLeftRadius = '3px'
|
||||||
|
style.borderBottomLeftRadius = '3px'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.selected.some(item => this.dateSame(item, date))) {
|
||||||
|
style.borderTopLeftRadius = '3px'
|
||||||
|
style.borderBottomLeftRadius = '3px'
|
||||||
|
style.borderTopRightRadius = '3px'
|
||||||
|
style.borderBottomRightRadius = '3px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 某个日期是否被选中
|
||||||
|
textStyle() {
|
||||||
|
return (item) => {
|
||||||
|
const date = dayjs(item.date).format("YYYY-MM-DD"),
|
||||||
|
style = {}
|
||||||
|
// 选中的日期,提示文字设置白色
|
||||||
|
if (this.selected.some(item => this.dateSame(item, date))) {
|
||||||
|
style.color = '#ffffff'
|
||||||
|
}
|
||||||
|
if (this.mode === 'range') {
|
||||||
|
const len = this.selected.length - 1
|
||||||
|
// 如果是范围选择模式,第一个和最后一个之间的日期,文字颜色设置为高亮的主题色
|
||||||
|
if (dayjs(date).isAfter(dayjs(this.selected[0])) && dayjs(date).isBefore(dayjs(this
|
||||||
|
.selected[len]))) {
|
||||||
|
style.color = this.color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取底部的提示文字
|
||||||
|
getBottomInfo() {
|
||||||
|
return (index1, index2, item) => {
|
||||||
|
const date = dayjs(item.date).format("YYYY-MM-DD")
|
||||||
|
const bottomInfo = item.bottomInfo
|
||||||
|
// 当为日期范围模式时,且选择的日期个数大于0时
|
||||||
|
if (this.mode === 'range' && this.selected.length > 0) {
|
||||||
|
if (this.selected.length === 1) {
|
||||||
|
// 选择了一个日期时,如果当前日期为数组中的第一个日期,则显示底部文字为“开始”
|
||||||
|
if (this.dateSame(date, this.selected[0])) return this.startText
|
||||||
|
else return bottomInfo
|
||||||
|
} else {
|
||||||
|
const len = this.selected.length - 1
|
||||||
|
// 如果数组中的日期大于2个时,第一个和最后一个显示为开始和结束日期
|
||||||
|
if (this.dateSame(date, this.selected[0]) && this.dateSame(date, this.selected[1]) &&
|
||||||
|
len === 1) {
|
||||||
|
// 如果长度为2,且第一个等于第二个日期,则提示语放在同一个item中
|
||||||
|
return `${this.startText}/${this.endText}`
|
||||||
|
} else if (this.dateSame(date, this.selected[0])) {
|
||||||
|
return this.startText
|
||||||
|
} else if (this.dateSame(date, this.selected[len])) {
|
||||||
|
return this.endText
|
||||||
|
} else {
|
||||||
|
return bottomInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return bottomInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
// 初始化默认选中
|
||||||
|
this.$emit('monthSelected', this.selected)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
// 这里需要另一个延时,因为获取宽度后,会进行月份数据渲染,只有渲染完成之后,才有真正的高度
|
||||||
|
// 因为nvue下,$nextTick并不是100%可靠的
|
||||||
|
sleep(10).then(() => {
|
||||||
|
this.getWrapperWidth()
|
||||||
|
this.getMonthRect()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 判断两个日期是否相等
|
||||||
|
dateSame(date1, date2) {
|
||||||
|
return dayjs(date1).isSame(dayjs(date2))
|
||||||
|
},
|
||||||
|
// 获取月份数据区域的宽度,因为nvue不支持百分比,所以无法通过css设置每个日期item的宽度
|
||||||
|
getWrapperWidth() {
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
dom.getComponentRect(this.$refs['u-calendar-month-wrapper'], res => {
|
||||||
|
this.width = res.size.width
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.$uGetRect('.u-calendar-month-wrapper').then(size => {
|
||||||
|
this.width = size.width
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
getMonthRect() {
|
||||||
|
// 获取每个月份数据的尺寸,用于父组件在scroll-view滚动事件中,监听当前滚动到了第几个月份
|
||||||
|
const promiseAllArr = this.months.map((item, index) => this.getMonthRectByPromise(
|
||||||
|
`u-calendar-month-${index}`))
|
||||||
|
// 一次性返回
|
||||||
|
Promise.all(promiseAllArr).then(
|
||||||
|
sizes => {
|
||||||
|
let height = 1
|
||||||
|
const topArr = []
|
||||||
|
for (let i = 0; i < this.months.length; i++) {
|
||||||
|
// 添加到months数组中,供scroll-view滚动事件中,判断当前滚动到哪个月份
|
||||||
|
topArr[i] = height
|
||||||
|
height += sizes[i].height
|
||||||
|
}
|
||||||
|
// 由于微信下,无法通过this.months[i].top的形式(引用类型)去修改父组件的month的top值,所以使用事件形式对外发出
|
||||||
|
this.$emit('updateMonthTop', topArr)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获取每个月份区域的尺寸
|
||||||
|
getMonthRectByPromise(el) {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
// $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://ijry.github.io/uview-plus/js/getRect.html
|
||||||
|
// 组件内部一般用this.$uGetRect,对外的为uni.$u.getRect,二者功能一致,名称不同
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this.$uGetRect(`.${el}`).then(size => {
|
||||||
|
resolve(size)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
// nvue下,使用dom模块查询元素高度
|
||||||
|
// 返回一个promise,让调用此方法的主体能使用then回调
|
||||||
|
return new Promise(resolve => {
|
||||||
|
dom.getComponentRect(this.$refs[el][0], res => {
|
||||||
|
resolve(res.size)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
// 点击某一个日期
|
||||||
|
clickHandler(index1, index2, item) {
|
||||||
|
if (this.readonly) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.item = item
|
||||||
|
const date = dayjs(item.date).format("YYYY-MM-DD")
|
||||||
|
if (item.disabled) return
|
||||||
|
// 对上一次选择的日期数组进行深度克隆
|
||||||
|
let selected = deepClone(this.selected)
|
||||||
|
if (this.mode === 'single') {
|
||||||
|
// 单选情况下,让数组中的元素为当前点击的日期
|
||||||
|
selected = [date]
|
||||||
|
} else if (this.mode === 'multiple') {
|
||||||
|
if (selected.some(item => this.dateSame(item, date))) {
|
||||||
|
// 如果点击的日期已在数组中,则进行移除操作,也就是达到反选的效果
|
||||||
|
const itemIndex = selected.findIndex(item => item === date)
|
||||||
|
selected.splice(itemIndex, 1)
|
||||||
|
} else {
|
||||||
|
// 如果点击的日期不在数组中,且已有的长度小于总可选长度时,则添加到数组中去
|
||||||
|
if (selected.length < this.maxCount) selected.push(date)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 选择区间形式
|
||||||
|
if (selected.length === 0 || selected.length >= 2) {
|
||||||
|
// 如果原来就为0或者大于2的长度,则当前点击的日期,就是开始日期
|
||||||
|
selected = [date]
|
||||||
|
} else if (selected.length === 1) {
|
||||||
|
// 如果已经选择了开始日期
|
||||||
|
const existsDate = selected[0]
|
||||||
|
// 如果当前选择的日期小于上一次选择的日期,则当前的日期定为开始日期
|
||||||
|
if (dayjs(date).isBefore(existsDate)) {
|
||||||
|
selected = [date]
|
||||||
|
} else if (dayjs(date).isAfter(existsDate)) {
|
||||||
|
// 当前日期减去最大可选的日期天数,如果大于起始时间,则进行提示
|
||||||
|
if(dayjs(dayjs(date).subtract(this.maxRange, 'day')).isAfter(dayjs(selected[0])) && this.showRangePrompt) {
|
||||||
|
if(this.rangePrompt) {
|
||||||
|
toast(this.rangePrompt)
|
||||||
|
} else {
|
||||||
|
toast(`选择天数不能超过 ${this.maxRange} 天`)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 如果当前日期大于已有日期,将当前的添加到数组尾部
|
||||||
|
selected.push(date)
|
||||||
|
const startDate = selected[0]
|
||||||
|
const endDate = selected[1]
|
||||||
|
const arr = []
|
||||||
|
let i = 0
|
||||||
|
do {
|
||||||
|
// 将开始和结束日期之间的日期添加到数组中
|
||||||
|
arr.push(dayjs(startDate).add(i, 'day').format("YYYY-MM-DD"))
|
||||||
|
i++
|
||||||
|
// 累加的日期小于结束日期时,继续下一次的循环
|
||||||
|
} while (dayjs(startDate).add(i, 'day').isBefore(dayjs(endDate)))
|
||||||
|
// 为了一次性修改数组,避免computed中多次触发,这里才用arr变量一次性赋值的方式,同时将最后一个日期添加近来
|
||||||
|
arr.push(endDate)
|
||||||
|
selected = arr
|
||||||
|
} else {
|
||||||
|
// 选择区间时,只有一个日期的情况下,且不允许选择起止为同一天的话,不允许选择自己
|
||||||
|
if (selected[0] === date && !this.allowSameDay) return
|
||||||
|
selected.push(date)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.setSelected(selected)
|
||||||
|
},
|
||||||
|
// 设置默认日期
|
||||||
|
setDefaultDate() {
|
||||||
|
if (!this.defaultDate) {
|
||||||
|
// 如果没有设置默认日期,则将当天日期设置为默认选中的日期
|
||||||
|
const selected = [dayjs().format("YYYY-MM-DD")]
|
||||||
|
return this.setSelected(selected, false)
|
||||||
|
}
|
||||||
|
let defaultDate = []
|
||||||
|
const minDate = this.minDate || dayjs().format("YYYY-MM-DD")
|
||||||
|
const maxDate = this.maxDate || dayjs(minDate).add(this.maxMonth - 1, 'month').format("YYYY-MM-DD")
|
||||||
|
if (this.mode === 'single') {
|
||||||
|
// 单选模式,可以是字符串或数组,Date对象等
|
||||||
|
if (!test.array(this.defaultDate)) {
|
||||||
|
defaultDate = [dayjs(this.defaultDate).format("YYYY-MM-DD")]
|
||||||
|
} else {
|
||||||
|
defaultDate = [this.defaultDate[0]]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果为非数组,则不执行
|
||||||
|
if (!test.array(this.defaultDate)) return
|
||||||
|
defaultDate = this.defaultDate
|
||||||
|
}
|
||||||
|
// 过滤用户传递的默认数组,取出只在可允许最大值与最小值之间的元素
|
||||||
|
defaultDate = defaultDate.filter(item => {
|
||||||
|
return dayjs(item).isAfter(dayjs(minDate).subtract(1, 'day')) && dayjs(item).isBefore(dayjs(
|
||||||
|
maxDate).add(1, 'day'))
|
||||||
|
})
|
||||||
|
this.setSelected(defaultDate, false)
|
||||||
|
},
|
||||||
|
setSelected(selected, event = true) {
|
||||||
|
this.selected = selected
|
||||||
|
event && this.$emit('monthSelected', this.selected,'tap')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
.u-calendar-month-wrapper {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-calendar-month {
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 42px;
|
||||||
|
height: 42px;
|
||||||
|
color: $u-main-color;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__days {
|
||||||
|
position: relative;
|
||||||
|
@include flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
&__month-mark-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
@include flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
font-size: 155px;
|
||||||
|
color: rgba(231, 232, 234, 0.83);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__day {
|
||||||
|
@include flex;
|
||||||
|
padding: 2px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
// vue下使用css进行宽度计算,因为某些安卓机会无法进行js获取父元素宽度进行计算得出,会有偏移
|
||||||
|
width: calc(100% / 7);
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
&__select {
|
||||||
|
flex: 1;
|
||||||
|
@include flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&__dot {
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
border-radius: 100px;
|
||||||
|
background-color: $u-error;
|
||||||
|
position: absolute;
|
||||||
|
top: 12px;
|
||||||
|
right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__buttom-info {
|
||||||
|
color: $u-content-color;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5px;
|
||||||
|
font-size: 10px;
|
||||||
|
text-align: center;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
&--selected {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
color: #cacbcd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
&--selected {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
color: #cacbcd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--selected {
|
||||||
|
background-color: $u-primary;
|
||||||
|
@include flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--range-selected {
|
||||||
|
opacity: 0.3;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--range-start-selected {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--range-end-selected {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
145
uni_modules/uview-plus/components/u-calendar/props.js
Normal file
145
uni_modules/uview-plus/components/u-calendar/props.js
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 日历顶部标题
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.calendar.title
|
||||||
|
},
|
||||||
|
// 是否显示标题
|
||||||
|
showTitle: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.calendar.showTitle
|
||||||
|
},
|
||||||
|
// 是否显示副标题
|
||||||
|
showSubtitle: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.calendar.showSubtitle
|
||||||
|
},
|
||||||
|
// 日期类型选择,single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.calendar.mode
|
||||||
|
},
|
||||||
|
// mode=range时,第一个日期底部的提示文字
|
||||||
|
startText: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.calendar.startText
|
||||||
|
},
|
||||||
|
// mode=range时,最后一个日期底部的提示文字
|
||||||
|
endText: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.calendar.endText
|
||||||
|
},
|
||||||
|
// 自定义列表
|
||||||
|
customList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => defProps.calendar.customList
|
||||||
|
},
|
||||||
|
// 主题色,对底部按钮和选中日期有效
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.calendar.color
|
||||||
|
},
|
||||||
|
// 最小的可选日期
|
||||||
|
minDate: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.calendar.minDate
|
||||||
|
},
|
||||||
|
// 最大可选日期
|
||||||
|
maxDate: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.calendar.maxDate
|
||||||
|
},
|
||||||
|
// 默认选中的日期,mode为multiple或range是必须为数组格式
|
||||||
|
defaultDate: {
|
||||||
|
type: [Array, String, Date, null],
|
||||||
|
default: () => defProps.calendar.defaultDate
|
||||||
|
},
|
||||||
|
// mode=multiple时,最多可选多少个日期
|
||||||
|
maxCount: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.calendar.maxCount
|
||||||
|
},
|
||||||
|
// 日期行高
|
||||||
|
rowHeight: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.calendar.rowHeight
|
||||||
|
},
|
||||||
|
// 日期格式化函数
|
||||||
|
formatter: {
|
||||||
|
type: [Function, null],
|
||||||
|
default: () => defProps.calendar.formatter
|
||||||
|
},
|
||||||
|
// 是否显示农历
|
||||||
|
showLunar: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.calendar.showLunar
|
||||||
|
},
|
||||||
|
// 是否显示月份背景色
|
||||||
|
showMark: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.calendar.showMark
|
||||||
|
},
|
||||||
|
// 确定按钮的文字
|
||||||
|
confirmText: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.calendar.confirmText
|
||||||
|
},
|
||||||
|
// 确认按钮处于禁用状态时的文字
|
||||||
|
confirmDisabledText: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.calendar.confirmDisabledText
|
||||||
|
},
|
||||||
|
// 是否显示日历弹窗
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.calendar.show
|
||||||
|
},
|
||||||
|
// 是否允许点击遮罩关闭日历
|
||||||
|
closeOnClickOverlay: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.calendar.closeOnClickOverlay
|
||||||
|
},
|
||||||
|
// 是否为只读状态,只读状态下禁止选择日期
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.calendar.readonly
|
||||||
|
},
|
||||||
|
// 是否展示确认按钮
|
||||||
|
showConfirm: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.calendar.showConfirm
|
||||||
|
},
|
||||||
|
// 日期区间最多可选天数,默认无限制,mode = range时有效
|
||||||
|
maxRange: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: () => defProps.calendar.maxRange
|
||||||
|
},
|
||||||
|
// 范围选择超过最多可选天数时的提示文案,mode = range时有效
|
||||||
|
rangePrompt: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.calendar.rangePrompt
|
||||||
|
},
|
||||||
|
// 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效
|
||||||
|
showRangePrompt: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.calendar.showRangePrompt
|
||||||
|
},
|
||||||
|
// 是否允许日期范围的起止时间为同一天,mode = range时有效
|
||||||
|
allowSameDay: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.calendar.allowSameDay
|
||||||
|
},
|
||||||
|
// 圆角值
|
||||||
|
round: {
|
||||||
|
type: [Boolean, String, Number],
|
||||||
|
default: () => defProps.calendar.round
|
||||||
|
},
|
||||||
|
// 最多展示月份数量
|
||||||
|
monthNum: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
409
uni_modules/uview-plus/components/u-calendar/u-calendar.vue
Normal file
409
uni_modules/uview-plus/components/u-calendar/u-calendar.vue
Normal file
|
@ -0,0 +1,409 @@
|
||||||
|
<template>
|
||||||
|
<u-popup
|
||||||
|
:show="show"
|
||||||
|
mode="bottom"
|
||||||
|
closeable
|
||||||
|
@close="close"
|
||||||
|
:round="round"
|
||||||
|
:closeOnClickOverlay="closeOnClickOverlay"
|
||||||
|
>
|
||||||
|
<view class="u-calendar">
|
||||||
|
<uHeader
|
||||||
|
:title="title"
|
||||||
|
:subtitle="subtitle"
|
||||||
|
:showSubtitle="showSubtitle"
|
||||||
|
:showTitle="showTitle"
|
||||||
|
></uHeader>
|
||||||
|
<scroll-view
|
||||||
|
:style="{
|
||||||
|
height: addUnit(listHeight)
|
||||||
|
}"
|
||||||
|
scroll-y
|
||||||
|
@scroll="onScroll"
|
||||||
|
:scroll-top="scrollTop"
|
||||||
|
:scrollIntoView="scrollIntoView"
|
||||||
|
>
|
||||||
|
<uMonth
|
||||||
|
:color="color"
|
||||||
|
:rowHeight="rowHeight"
|
||||||
|
:showMark="showMark"
|
||||||
|
:months="months"
|
||||||
|
:mode="mode"
|
||||||
|
:maxCount="maxCount"
|
||||||
|
:startText="startText"
|
||||||
|
:endText="endText"
|
||||||
|
:defaultDate="defaultDate"
|
||||||
|
:minDate="innerMinDate"
|
||||||
|
:maxDate="innerMaxDate"
|
||||||
|
:maxMonth="monthNum"
|
||||||
|
:readonly="readonly"
|
||||||
|
:maxRange="maxRange"
|
||||||
|
:rangePrompt="rangePrompt"
|
||||||
|
:showRangePrompt="showRangePrompt"
|
||||||
|
:allowSameDay="allowSameDay"
|
||||||
|
ref="month"
|
||||||
|
@monthSelected="monthSelected"
|
||||||
|
@updateMonthTop="updateMonthTop"
|
||||||
|
></uMonth>
|
||||||
|
</scroll-view>
|
||||||
|
<slot name="footer" v-if="showConfirm">
|
||||||
|
<view class="u-calendar__confirm">
|
||||||
|
<u-button
|
||||||
|
shape="circle"
|
||||||
|
:text="
|
||||||
|
buttonDisabled ? confirmDisabledText : confirmText
|
||||||
|
"
|
||||||
|
:color="color"
|
||||||
|
@click="confirm"
|
||||||
|
:disabled="buttonDisabled"
|
||||||
|
></u-button>
|
||||||
|
</view>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import uHeader from './header.vue'
|
||||||
|
import uMonth from './month.vue'
|
||||||
|
import props from './props.js'
|
||||||
|
import util from './util.js'
|
||||||
|
import dayjs from 'dayjs/esm/index'
|
||||||
|
import Calendar from '../../libs/util/calendar.js'
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin.js'
|
||||||
|
import mixin from '../../libs/mixin/mixin.js'
|
||||||
|
import { addUnit, range, error, padZero } from '../../libs/function/index';
|
||||||
|
import test from '../../libs/function/test';
|
||||||
|
/**
|
||||||
|
* Calendar 日历
|
||||||
|
* @description 此组件用于单个选择日期,范围选择日期等,日历被包裹在底部弹起的容器中.
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/calendar.html
|
||||||
|
*
|
||||||
|
* @property {String} title 标题内容 (默认 日期选择 )
|
||||||
|
* @property {Boolean} showTitle 是否显示标题 (默认 true )
|
||||||
|
* @property {Boolean} showSubtitle 是否显示副标题 (默认 true )
|
||||||
|
* @property {String} mode 日期类型选择 single-选择单个日期,multiple-可以选择多个日期,range-选择日期范围 ( 默认 'single' )
|
||||||
|
* @property {String} startText mode=range时,第一个日期底部的提示文字 (默认 '开始' )
|
||||||
|
* @property {String} endText mode=range时,最后一个日期底部的提示文字 (默认 '结束' )
|
||||||
|
* @property {Array} customList 自定义列表
|
||||||
|
* @property {String} color 主题色,对底部按钮和选中日期有效 (默认 ‘#3c9cff' )
|
||||||
|
* @property {String | Number} minDate 最小的可选日期 (默认 0 )
|
||||||
|
* @property {String | Number} maxDate 最大可选日期 (默认 0 )
|
||||||
|
* @property {Array | String| Date} defaultDate 默认选中的日期,mode为multiple或range是必须为数组格式
|
||||||
|
* @property {String | Number} maxCount mode=multiple时,最多可选多少个日期 (默认 Number.MAX_SAFE_INTEGER )
|
||||||
|
* @property {String | Number} rowHeight 日期行高 (默认 56 )
|
||||||
|
* @property {Function} formatter 日期格式化函数
|
||||||
|
* @property {Boolean} showLunar 是否显示农历 (默认 false )
|
||||||
|
* @property {Boolean} showMark 是否显示月份背景色 (默认 true )
|
||||||
|
* @property {String} confirmText 确定按钮的文字 (默认 '确定' )
|
||||||
|
* @property {String} confirmDisabledText 确认按钮处于禁用状态时的文字 (默认 '确定' )
|
||||||
|
* @property {Boolean} show 是否显示日历弹窗 (默认 false )
|
||||||
|
* @property {Boolean} closeOnClickOverlay 是否允许点击遮罩关闭日历 (默认 false )
|
||||||
|
* @property {Boolean} readonly 是否为只读状态,只读状态下禁止选择日期 (默认 false )
|
||||||
|
* @property {String | Number} maxRange 日期区间最多可选天数,默认无限制,mode = range时有效
|
||||||
|
* @property {String} rangePrompt 范围选择超过最多可选天数时的提示文案,mode = range时有效
|
||||||
|
* @property {Boolean} showRangePrompt 范围选择超过最多可选天数时,是否展示提示文案,mode = range时有效 (默认 true )
|
||||||
|
* @property {Boolean} allowSameDay 是否允许日期范围的起止时间为同一天,mode = range时有效 (默认 false )
|
||||||
|
* @property {Number|String} round 圆角值,默认无圆角 (默认 0 )
|
||||||
|
* @property {Number|String} monthNum 最多展示的月份数量 (默认 3 )
|
||||||
|
*
|
||||||
|
* @event {Function()} confirm 点击确定按钮时触发 选择日期相关的返回参数
|
||||||
|
* @event {Function()} close 日历关闭时触发 可定义页面关闭时的回调事件
|
||||||
|
* @example <u-calendar :defaultDate="defaultDateMultiple" :show="show" mode="multiple" @confirm="confirm">
|
||||||
|
</u-calendar>
|
||||||
|
* */
|
||||||
|
export default {
|
||||||
|
name: 'u-calendar',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
components: {
|
||||||
|
uHeader,
|
||||||
|
uMonth
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 需要显示的月份的数组
|
||||||
|
months: [],
|
||||||
|
// 在月份滚动区域中,当前视图中月份的index索引
|
||||||
|
monthIndex: 0,
|
||||||
|
// 月份滚动区域的高度
|
||||||
|
listHeight: 0,
|
||||||
|
// month组件中选择的日期数组
|
||||||
|
selected: [],
|
||||||
|
scrollIntoView: '',
|
||||||
|
scrollIntoViewScroll: '',
|
||||||
|
scrollTop:0,
|
||||||
|
// 过滤处理方法
|
||||||
|
innerFormatter: (value) => value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
scrollIntoView: {
|
||||||
|
immediate: true,
|
||||||
|
handler(n) {
|
||||||
|
// console.log('scrollIntoView', n)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectedChange: {
|
||||||
|
immediate: true,
|
||||||
|
handler(n) {
|
||||||
|
this.setMonth()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 打开弹窗时,设置月份数据
|
||||||
|
show: {
|
||||||
|
immediate: true,
|
||||||
|
handler(n) {
|
||||||
|
if (n) {
|
||||||
|
this.setMonth()
|
||||||
|
} else {
|
||||||
|
// 关闭时重置scrollIntoView,否则会出现二次打开日历,当前月份数据显示不正确。
|
||||||
|
// scrollIntoView需要有一个值变动过程,才会产生作用。
|
||||||
|
this.scrollIntoView = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 由于maxDate和minDate可以为字符串(2021-10-10),或者数值(时间戳),但是dayjs如果接受字符串形式的时间戳会有问题,这里进行处理
|
||||||
|
innerMaxDate() {
|
||||||
|
return test.number(this.maxDate)
|
||||||
|
? Number(this.maxDate)
|
||||||
|
: this.maxDate
|
||||||
|
},
|
||||||
|
innerMinDate() {
|
||||||
|
return test.number(this.minDate)
|
||||||
|
? Number(this.minDate)
|
||||||
|
: this.minDate
|
||||||
|
},
|
||||||
|
// 多个条件的变化,会引起选中日期的变化,这里统一管理监听
|
||||||
|
selectedChange() {
|
||||||
|
return [this.innerMinDate, this.innerMaxDate, this.defaultDate]
|
||||||
|
},
|
||||||
|
subtitle() {
|
||||||
|
// 初始化时,this.months为空数组,所以需要特别判断处理
|
||||||
|
if (this.months.length) {
|
||||||
|
return `${this.months[this.monthIndex].year}年${
|
||||||
|
this.months[this.monthIndex].month
|
||||||
|
}月`
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buttonDisabled() {
|
||||||
|
// 如果为range类型,且选择的日期个数不足1个时,让底部的按钮出于disabled状态
|
||||||
|
if (this.mode === 'range') {
|
||||||
|
if (this.selected.length <= 1) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.start = Date.now()
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
emits: ["confirm", "close"],
|
||||||
|
methods: {
|
||||||
|
addUnit,
|
||||||
|
// 在微信小程序中,不支持将函数当做props参数,故只能通过ref形式调用
|
||||||
|
setFormatter(e) {
|
||||||
|
this.innerFormatter = e
|
||||||
|
},
|
||||||
|
// month组件内部选择日期后,通过事件通知给父组件
|
||||||
|
monthSelected(e,scene ='init') {
|
||||||
|
this.selected = e
|
||||||
|
if (!this.showConfirm) {
|
||||||
|
// 在不需要确认按钮的情况下,如果为单选,或者范围多选且已选长度大于2,则直接进行返还
|
||||||
|
if (
|
||||||
|
this.mode === 'multiple' ||
|
||||||
|
this.mode === 'single' ||
|
||||||
|
(this.mode === 'range' && this.selected.length >= 2)
|
||||||
|
) {
|
||||||
|
if( scene === 'init'){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if( scene === 'tap') {
|
||||||
|
this.$emit('confirm', this.selected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
// 校验maxDate,不能小于minDate。
|
||||||
|
if (
|
||||||
|
this.innerMaxDate &&
|
||||||
|
this.innerMinDate &&
|
||||||
|
new Date(this.innerMaxDate).getTime() < new Date(this.innerMinDate).getTime()
|
||||||
|
) {
|
||||||
|
return error('maxDate不能小于minDate时间')
|
||||||
|
}
|
||||||
|
// 滚动区域的高度
|
||||||
|
this.listHeight = this.rowHeight * 5 + 30
|
||||||
|
this.setMonth()
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.$emit('close')
|
||||||
|
},
|
||||||
|
// 点击确定按钮
|
||||||
|
confirm() {
|
||||||
|
if (!this.buttonDisabled) {
|
||||||
|
this.$emit('confirm', this.selected)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获得两个日期之间的月份数
|
||||||
|
getMonths(minDate, maxDate) {
|
||||||
|
const minYear = dayjs(minDate).year()
|
||||||
|
const minMonth = dayjs(minDate).month() + 1
|
||||||
|
const maxYear = dayjs(maxDate).year()
|
||||||
|
const maxMonth = dayjs(maxDate).month() + 1
|
||||||
|
return (maxYear - minYear) * 12 + (maxMonth - minMonth) + 1
|
||||||
|
},
|
||||||
|
// 设置月份数据
|
||||||
|
setMonth() {
|
||||||
|
// 最小日期的毫秒数
|
||||||
|
const minDate = this.innerMinDate || dayjs().valueOf()
|
||||||
|
// 如果没有指定最大日期,则往后推3个月
|
||||||
|
const maxDate =
|
||||||
|
this.innerMaxDate ||
|
||||||
|
dayjs(minDate)
|
||||||
|
.add(this.monthNum - 1, 'month')
|
||||||
|
.valueOf()
|
||||||
|
// 最大最小月份之间的共有多少个月份,
|
||||||
|
const months = range(
|
||||||
|
1,
|
||||||
|
this.monthNum,
|
||||||
|
this.getMonths(minDate, maxDate)
|
||||||
|
)
|
||||||
|
// 先清空数组
|
||||||
|
this.months = []
|
||||||
|
for (let i = 0; i < months; i++) {
|
||||||
|
this.months.push({
|
||||||
|
date: new Array(
|
||||||
|
dayjs(minDate).add(i, 'month').daysInMonth()
|
||||||
|
)
|
||||||
|
.fill(1)
|
||||||
|
.map((item, index) => {
|
||||||
|
// 日期,取值1-31
|
||||||
|
let day = index + 1
|
||||||
|
// 星期,0-6,0为周日
|
||||||
|
const week = dayjs(minDate)
|
||||||
|
.add(i, 'month')
|
||||||
|
.date(day)
|
||||||
|
.day()
|
||||||
|
const date = dayjs(minDate)
|
||||||
|
.add(i, 'month')
|
||||||
|
.date(day)
|
||||||
|
.format('YYYY-MM-DD')
|
||||||
|
let bottomInfo = ''
|
||||||
|
if (this.showLunar) {
|
||||||
|
// 将日期转为农历格式
|
||||||
|
const lunar = Calendar.solar2lunar(
|
||||||
|
dayjs(date).year(),
|
||||||
|
dayjs(date).month() + 1,
|
||||||
|
dayjs(date).date()
|
||||||
|
)
|
||||||
|
bottomInfo = lunar.IDayCn
|
||||||
|
}
|
||||||
|
let config = {
|
||||||
|
day,
|
||||||
|
week,
|
||||||
|
// 小于最小允许的日期,或者大于最大的日期,则设置为disabled状态
|
||||||
|
disabled:
|
||||||
|
dayjs(date).isBefore(
|
||||||
|
dayjs(minDate).format('YYYY-MM-DD')
|
||||||
|
) ||
|
||||||
|
dayjs(date).isAfter(
|
||||||
|
dayjs(maxDate).format('YYYY-MM-DD')
|
||||||
|
),
|
||||||
|
// 返回一个日期对象,供外部的formatter获取当前日期的年月日等信息,进行加工处理
|
||||||
|
date: new Date(date),
|
||||||
|
bottomInfo,
|
||||||
|
dot: false,
|
||||||
|
month:
|
||||||
|
dayjs(minDate).add(i, 'month').month() + 1
|
||||||
|
}
|
||||||
|
const formatter =
|
||||||
|
this.formatter || this.innerFormatter
|
||||||
|
return formatter(config)
|
||||||
|
}),
|
||||||
|
// 当前所属的月份
|
||||||
|
month: dayjs(minDate).add(i, 'month').month() + 1,
|
||||||
|
// 当前年份
|
||||||
|
year: dayjs(minDate).add(i, 'month').year()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 滚动到默认设置的月份
|
||||||
|
scrollIntoDefaultMonth(selected) {
|
||||||
|
// 查询默认日期在可选列表的下标
|
||||||
|
const _index = this.months.findIndex(({
|
||||||
|
year,
|
||||||
|
month
|
||||||
|
}) => {
|
||||||
|
month = padZero(month)
|
||||||
|
return `${year}-${month}` === selected
|
||||||
|
})
|
||||||
|
if (_index !== -1) {
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollIntoView = `month-${_index}`
|
||||||
|
this.scrollIntoViewScroll = this.scrollIntoView
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.scrollTop = this.months[_index].top || 0;
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// scroll-view滚动监听
|
||||||
|
onScroll(event) {
|
||||||
|
// 不允许小于0的滚动值,如果scroll-view到顶了,继续下拉,会出现负数值
|
||||||
|
const scrollTop = Math.max(0, event.detail.scrollTop)
|
||||||
|
// 将当前滚动条数值,除以滚动区域的高度,可以得出当前滚动到了哪一个月份的索引
|
||||||
|
for (let i = 0; i < this.months.length; i++) {
|
||||||
|
if (scrollTop >= (this.months[i].top || this.listHeight)) {
|
||||||
|
this.monthIndex = i
|
||||||
|
this.scrollIntoViewScroll = `month-${i}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 更新月份的top值
|
||||||
|
updateMonthTop(topArr = []) {
|
||||||
|
// 设置对应月份的top值,用于onScroll方法更新月份
|
||||||
|
topArr.map((item, index) => {
|
||||||
|
this.months[index].top = item
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取默认日期的下标
|
||||||
|
if (!this.defaultDate) {
|
||||||
|
// 如果没有设置默认日期,则将当天日期设置为默认选中的日期
|
||||||
|
const selected = dayjs().format("YYYY-MM")
|
||||||
|
this.scrollIntoDefaultMonth(selected)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let selected = dayjs().format("YYYY-MM");
|
||||||
|
// 单选模式,可以是字符串或数组,Date对象等
|
||||||
|
if (!test.array(this.defaultDate)) {
|
||||||
|
selected = dayjs(this.defaultDate).format("YYYY-MM")
|
||||||
|
} else {
|
||||||
|
selected = dayjs(this.defaultDate[0]).format("YYYY-MM");
|
||||||
|
}
|
||||||
|
this.scrollIntoDefaultMonth(selected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../../libs/css/components.scss';
|
||||||
|
|
||||||
|
.u-calendar {
|
||||||
|
&__confirm {
|
||||||
|
padding: 7px 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
86
uni_modules/uview-plus/components/u-calendar/util.js
Normal file
86
uni_modules/uview-plus/components/u-calendar/util.js
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
import dayjs from 'dayjs/esm/index'
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
// 设置月份数据
|
||||||
|
setMonth() {
|
||||||
|
// 月初是周几
|
||||||
|
const day = dayjs(this.date).date(1).day()
|
||||||
|
const start = day == 0 ? 6 : day - 1
|
||||||
|
|
||||||
|
// 本月天数
|
||||||
|
const days = dayjs(this.date).endOf('month').format('D')
|
||||||
|
|
||||||
|
// 上个月天数
|
||||||
|
const prevDays = dayjs(this.date).endOf('month').subtract(1, 'month').format('D')
|
||||||
|
|
||||||
|
// 日期数据
|
||||||
|
const arr = []
|
||||||
|
// 清空表格
|
||||||
|
this.month = []
|
||||||
|
|
||||||
|
// 添加上月数据
|
||||||
|
arr.push(
|
||||||
|
...new Array(start).fill(1).map((e, i) => {
|
||||||
|
const day = prevDays - start + i + 1
|
||||||
|
|
||||||
|
return {
|
||||||
|
value: day,
|
||||||
|
disabled: true,
|
||||||
|
date: dayjs(this.date).subtract(1, 'month').date(day).format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// 添加本月数据
|
||||||
|
arr.push(
|
||||||
|
...new Array(days - 0).fill(1).map((e, i) => {
|
||||||
|
const day = i + 1
|
||||||
|
|
||||||
|
return {
|
||||||
|
value: day,
|
||||||
|
date: dayjs(this.date).date(day).format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// 添加下个月
|
||||||
|
arr.push(
|
||||||
|
...new Array(42 - days - start).fill(1).map((e, i) => {
|
||||||
|
const day = i + 1
|
||||||
|
|
||||||
|
return {
|
||||||
|
value: day,
|
||||||
|
disabled: true,
|
||||||
|
date: dayjs(this.date).add(1, 'month').date(day).format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
// 分割数组
|
||||||
|
for (let n = 0; n < arr.length; n += 7) {
|
||||||
|
this.month.push(
|
||||||
|
arr.slice(n, n + 7).map((e, i) => {
|
||||||
|
e.index = i + n
|
||||||
|
|
||||||
|
// 自定义信息
|
||||||
|
const custom = this.customList.find((c) => c.date == e.date)
|
||||||
|
|
||||||
|
// 农历
|
||||||
|
if (this.lunar) {
|
||||||
|
const {
|
||||||
|
IDayCn,
|
||||||
|
IMonthCn
|
||||||
|
} = this.getLunar(e.date)
|
||||||
|
e.lunar = IDayCn == '初一' ? IMonthCn : IDayCn
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
...custom
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
uni_modules/uview-plus/components/u-car-keyboard/props.js
Normal file
15
uni_modules/uview-plus/components/u-car-keyboard/props.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 是否打乱键盘按键的顺序
|
||||||
|
random: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 输入一个中文后,是否自动切换到英文
|
||||||
|
autoChange: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,315 @@
|
||||||
|
<template>
|
||||||
|
<view
|
||||||
|
class="u-keyboard"
|
||||||
|
@touchmove.stop.prevent="noop"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
v-for="(group, i) in abc ? engKeyBoardList : areaList"
|
||||||
|
:key="i"
|
||||||
|
class="u-keyboard__button"
|
||||||
|
:index="i"
|
||||||
|
:class="[i + 1 === 4 && 'u-keyboard__button--center']"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
v-if="i === 3"
|
||||||
|
class="u-keyboard__button__inner-wrapper"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-keyboard__button__inner-wrapper__left"
|
||||||
|
hover-class="u-hover-class"
|
||||||
|
:hover-stay-time="200"
|
||||||
|
@tap="changeCarInputMode"
|
||||||
|
>
|
||||||
|
<text
|
||||||
|
class="u-keyboard__button__inner-wrapper__left__lang"
|
||||||
|
:class="[!abc && 'u-keyboard__button__inner-wrapper__left__lang--active']"
|
||||||
|
>中</text>
|
||||||
|
<text class="u-keyboard__button__inner-wrapper__left__line">/</text>
|
||||||
|
<text
|
||||||
|
class="u-keyboard__button__inner-wrapper__left__lang"
|
||||||
|
:class="[abc && 'u-keyboard__button__inner-wrapper__left__lang--active']"
|
||||||
|
>英</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="u-keyboard__button__inner-wrapper"
|
||||||
|
v-for="(item, j) in group"
|
||||||
|
:key="j"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-keyboard__button__inner-wrapper__inner"
|
||||||
|
:hover-stay-time="200"
|
||||||
|
@tap="carInputClick(i, j)"
|
||||||
|
hover-class="u-hover-class"
|
||||||
|
>
|
||||||
|
<text class="u-keyboard__button__inner-wrapper__inner__text">{{ item }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
v-if="i === 3"
|
||||||
|
@touchstart="backspaceClick"
|
||||||
|
@touchend="clearTimer"
|
||||||
|
class="u-keyboard__button__inner-wrapper"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-keyboard__button__inner-wrapper__right"
|
||||||
|
hover-class="u-hover-class"
|
||||||
|
:hover-stay-time="200"
|
||||||
|
>
|
||||||
|
<u-icon
|
||||||
|
size="28"
|
||||||
|
name="backspace"
|
||||||
|
color="#303133"
|
||||||
|
></u-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { randomArray, sleep } from '../../libs/function/index';
|
||||||
|
/**
|
||||||
|
* keyboard 键盘组件
|
||||||
|
* @description 此为uView自定义的键盘面板,内含了数字键盘,车牌号键,身份证号键盘3种模式,都有可以打乱按键顺序的选项。
|
||||||
|
* @tutorial https://uview-plus.jiangruyi.com/components/keyboard.html
|
||||||
|
* @property {Boolean} random 是否打乱键盘的顺序
|
||||||
|
* @event {Function} change 点击键盘触发
|
||||||
|
* @event {Function} backspace 点击退格键触发
|
||||||
|
* @example <u-keyboard ref="uKeyboard" mode="car" v-model="show"></u-keyboard>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: "u-keyboard",
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 车牌输入时,abc=true为输入车牌号码,bac=false为输入省份中文简称
|
||||||
|
abc: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
areaList() {
|
||||||
|
let data = [
|
||||||
|
'京',
|
||||||
|
'沪',
|
||||||
|
'粤',
|
||||||
|
'津',
|
||||||
|
'冀',
|
||||||
|
'豫',
|
||||||
|
'云',
|
||||||
|
'辽',
|
||||||
|
'黑',
|
||||||
|
'湘',
|
||||||
|
'皖',
|
||||||
|
'鲁',
|
||||||
|
'苏',
|
||||||
|
'浙',
|
||||||
|
'赣',
|
||||||
|
'鄂',
|
||||||
|
'桂',
|
||||||
|
'甘',
|
||||||
|
'晋',
|
||||||
|
'陕',
|
||||||
|
'蒙',
|
||||||
|
'吉',
|
||||||
|
'闽',
|
||||||
|
'贵',
|
||||||
|
'渝',
|
||||||
|
'川',
|
||||||
|
'青',
|
||||||
|
'琼',
|
||||||
|
'宁',
|
||||||
|
'挂',
|
||||||
|
'藏',
|
||||||
|
'港',
|
||||||
|
'澳',
|
||||||
|
'新',
|
||||||
|
'使',
|
||||||
|
'学'
|
||||||
|
];
|
||||||
|
let tmp = [];
|
||||||
|
// 打乱顺序
|
||||||
|
if (this.random) data = randomArray(data);
|
||||||
|
// 切割成二维数组
|
||||||
|
tmp[0] = data.slice(0, 10);
|
||||||
|
tmp[1] = data.slice(10, 20);
|
||||||
|
tmp[2] = data.slice(20, 30);
|
||||||
|
tmp[3] = data.slice(30, 36);
|
||||||
|
return tmp;
|
||||||
|
},
|
||||||
|
engKeyBoardList() {
|
||||||
|
let data = [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
0,
|
||||||
|
'Q',
|
||||||
|
'W',
|
||||||
|
'E',
|
||||||
|
'R',
|
||||||
|
'T',
|
||||||
|
'Y',
|
||||||
|
'U',
|
||||||
|
'I',
|
||||||
|
'O',
|
||||||
|
'P',
|
||||||
|
'A',
|
||||||
|
'S',
|
||||||
|
'D',
|
||||||
|
'F',
|
||||||
|
'G',
|
||||||
|
'H',
|
||||||
|
'J',
|
||||||
|
'K',
|
||||||
|
'L',
|
||||||
|
'Z',
|
||||||
|
'X',
|
||||||
|
'C',
|
||||||
|
'V',
|
||||||
|
'B',
|
||||||
|
'N',
|
||||||
|
'M'
|
||||||
|
];
|
||||||
|
let tmp = [];
|
||||||
|
if (this.random) data = randomArray(data);
|
||||||
|
tmp[0] = data.slice(0, 10);
|
||||||
|
tmp[1] = data.slice(10, 20);
|
||||||
|
tmp[2] = data.slice(20, 30);
|
||||||
|
tmp[3] = data.slice(30, 36);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ["change", "backspace"],
|
||||||
|
methods: {
|
||||||
|
// 点击键盘按钮
|
||||||
|
carInputClick(i, j) {
|
||||||
|
let value = '';
|
||||||
|
// 不同模式,获取不同数组的值
|
||||||
|
if (this.abc) value = this.engKeyBoardList[i][j];
|
||||||
|
else value = this.areaList[i][j];
|
||||||
|
// 如果允许自动切换,则将中文状态切换为英文
|
||||||
|
if (!this.abc && this.autoChange) sleep(200).then(() => this.abc = true)
|
||||||
|
this.$emit('change', value);
|
||||||
|
},
|
||||||
|
// 修改汽车牌键盘的输入模式,中文|英文
|
||||||
|
changeCarInputMode() {
|
||||||
|
this.abc = !this.abc;
|
||||||
|
},
|
||||||
|
// 点击退格键
|
||||||
|
backspaceClick() {
|
||||||
|
this.$emit('backspace');
|
||||||
|
clearInterval(this.timer); //再次清空定时器,防止重复注册定时器
|
||||||
|
this.timer = null;
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
this.$emit('backspace');
|
||||||
|
}, 250);
|
||||||
|
},
|
||||||
|
clearTimer() {
|
||||||
|
clearInterval(this.timer);
|
||||||
|
this.timer = null;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
$u-car-keyboard-background-color: rgb(224, 228, 230) !default;
|
||||||
|
$u-car-keyboard-padding:6px 0 6px !default;
|
||||||
|
$u-car-keyboard-button-inner-width:64rpx !default;
|
||||||
|
$u-car-keyboard-button-inner-background-color:#FFFFFF !default;
|
||||||
|
$u-car-keyboard-button-height:80rpx !default;
|
||||||
|
$u-car-keyboard-button-inner-box-shadow:0 1px 0px #999992 !default;
|
||||||
|
$u-car-keyboard-button-border-radius:4px !default;
|
||||||
|
$u-car-keyboard-button-inner-margin:8rpx 5rpx !default;
|
||||||
|
$u-car-keyboard-button-text-font-size:16px !default;
|
||||||
|
$u-car-keyboard-button-text-color:$u-main-color !default;
|
||||||
|
$u-car-keyboard-center-inner-margin: 0 4rpx !default;
|
||||||
|
$u-car-keyboard-special-button-width:134rpx !default;
|
||||||
|
$u-car-keyboard-lang-font-size:16px !default;
|
||||||
|
$u-car-keyboard-lang-color:$u-main-color !default;
|
||||||
|
$u-car-keyboard-active-color:$u-primary !default;
|
||||||
|
$u-car-keyboard-line-font-size:15px !default;
|
||||||
|
$u-car-keyboard-line-color:$u-main-color !default;
|
||||||
|
$u-car-keyboard-line-margin:0 1px !default;
|
||||||
|
$u-car-keyboard-u-hover-class-background-color:#BBBCC6 !default;
|
||||||
|
|
||||||
|
.u-keyboard {
|
||||||
|
@include flex(column);
|
||||||
|
justify-content: space-around;
|
||||||
|
background-color: $u-car-keyboard-background-color;
|
||||||
|
align-items: stretch;
|
||||||
|
padding: $u-car-keyboard-padding;
|
||||||
|
|
||||||
|
&__button {
|
||||||
|
@include flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 1;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
&__inner-wrapper {
|
||||||
|
box-shadow: $u-car-keyboard-button-inner-box-shadow;
|
||||||
|
margin: $u-car-keyboard-button-inner-margin;
|
||||||
|
border-radius: $u-car-keyboard-button-border-radius;
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
@include flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: $u-car-keyboard-button-inner-width;
|
||||||
|
background-color: $u-car-keyboard-button-inner-background-color;
|
||||||
|
height: $u-car-keyboard-button-height;
|
||||||
|
border-radius: $u-car-keyboard-button-border-radius;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
font-size: $u-car-keyboard-button-text-font-size;
|
||||||
|
color: $u-car-keyboard-button-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__left,
|
||||||
|
&__right {
|
||||||
|
border-radius: $u-car-keyboard-button-border-radius;
|
||||||
|
width: $u-car-keyboard-special-button-width;
|
||||||
|
height: $u-car-keyboard-button-height;
|
||||||
|
background-color: $u-car-keyboard-u-hover-class-background-color;
|
||||||
|
@include flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: $u-car-keyboard-button-inner-box-shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__left {
|
||||||
|
&__line {
|
||||||
|
font-size: $u-car-keyboard-line-font-size;
|
||||||
|
color: $u-car-keyboard-line-color;
|
||||||
|
margin: $u-car-keyboard-line-margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__lang {
|
||||||
|
font-size: $u-car-keyboard-lang-font-size;
|
||||||
|
color: $u-car-keyboard-lang-color;
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
color: $u-car-keyboard-active-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-hover-class {
|
||||||
|
background-color: $u-car-keyboard-u-hover-class-background-color;
|
||||||
|
}
|
||||||
|
</style>
|
15
uni_modules/uview-plus/components/u-cell-group/props.js
Normal file
15
uni_modules/uview-plus/components/u-cell-group/props.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 分组标题
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.cellGroup.title
|
||||||
|
},
|
||||||
|
// 是否显示外边框
|
||||||
|
border: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.cellGroup.border
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
<template>
|
||||||
|
<view :style="[addStyle(customStyle)]" :class="[customClass]" class="u-cell-group">
|
||||||
|
<view v-if="title" class="u-cell-group__title">
|
||||||
|
<slot name="title">
|
||||||
|
<text class="u-cell-group__title__text">{{ title }}</text>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<view class="u-cell-group__wrapper">
|
||||||
|
<u-line v-if="border"></u-line>
|
||||||
|
<slot />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addStyle } from '../../libs/function/index';
|
||||||
|
/**
|
||||||
|
* cellGroup 单元格
|
||||||
|
* @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。
|
||||||
|
* @tutorial https://uview-plus.jiangruyi.com/components/cell.html
|
||||||
|
*
|
||||||
|
* @property {String} title 分组标题
|
||||||
|
* @property {Boolean} border 是否显示外边框 (默认 true )
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
*
|
||||||
|
* @event {Function} click 点击cell列表时触发
|
||||||
|
* @example <u-cell-group title="设置喜好">
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-cell-group',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
methods: {
|
||||||
|
addStyle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
$u-cell-group-title-padding: 16px 16px 8px !default;
|
||||||
|
$u-cell-group-title-font-size: 15px !default;
|
||||||
|
$u-cell-group-title-line-height: 16px !default;
|
||||||
|
$u-cell-group-title-color: $u-main-color !default;
|
||||||
|
|
||||||
|
.u-cell-group {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
padding: $u-cell-group-title-padding;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
font-size: $u-cell-group-title-font-size;
|
||||||
|
line-height: $u-cell-group-title-line-height;
|
||||||
|
color: $u-cell-group-title-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
111
uni_modules/uview-plus/components/u-cell/props.js
Normal file
111
uni_modules/uview-plus/components/u-cell/props.js
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 标题
|
||||||
|
title: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.cell.title
|
||||||
|
},
|
||||||
|
// 标题下方的描述信息
|
||||||
|
label: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.cell.label
|
||||||
|
},
|
||||||
|
// 右侧的内容
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.cell.value
|
||||||
|
},
|
||||||
|
// 左侧图标名称,或者图片链接(本地文件建议使用绝对地址)
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.cell.icon
|
||||||
|
},
|
||||||
|
// 是否禁用cell
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.cell.disabled
|
||||||
|
},
|
||||||
|
// 是否显示下边框
|
||||||
|
border: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.cell.border
|
||||||
|
},
|
||||||
|
// 内容是否垂直居中(主要是针对右侧的value部分)
|
||||||
|
center: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.cell.center
|
||||||
|
},
|
||||||
|
// 点击后跳转的URL地址
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.cell.url
|
||||||
|
},
|
||||||
|
// 链接跳转的方式,内部使用的是uView封装的route方法,可能会进行拦截操作
|
||||||
|
linkType: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.cell.linkType
|
||||||
|
},
|
||||||
|
// 是否开启点击反馈(表现为点击时加上灰色背景)
|
||||||
|
clickable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.cell.clickable
|
||||||
|
},
|
||||||
|
// 是否展示右侧箭头并开启点击反馈
|
||||||
|
isLink: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.cell.isLink
|
||||||
|
},
|
||||||
|
// 是否显示表单状态下的必填星号(此组件可能会内嵌入input组件)
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.cell.required
|
||||||
|
},
|
||||||
|
// 右侧的图标箭头
|
||||||
|
rightIcon: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.cell.rightIcon
|
||||||
|
},
|
||||||
|
// 右侧箭头的方向,可选值为:left,up,down
|
||||||
|
arrowDirection: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.cell.arrowDirection
|
||||||
|
},
|
||||||
|
// 左侧图标样式
|
||||||
|
iconStyle: {
|
||||||
|
type: [Object, String],
|
||||||
|
default: () => {
|
||||||
|
return defProps.cell.iconStyle
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 右侧箭头图标的样式
|
||||||
|
rightIconStyle: {
|
||||||
|
type: [Object, String],
|
||||||
|
default: () => {
|
||||||
|
return defProps.cell.rightIconStyle
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 标题的样式
|
||||||
|
titleStyle: {
|
||||||
|
type: [Object, String],
|
||||||
|
default: () => {
|
||||||
|
return defProps.cell.titleStyle
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 单位元的大小,可选值为large
|
||||||
|
size: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.cell.size
|
||||||
|
},
|
||||||
|
// 点击cell是否阻止事件传播
|
||||||
|
stop: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.cell.stop
|
||||||
|
},
|
||||||
|
// 标识符,cell被点击时返回
|
||||||
|
name: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: () => defProps.cell.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
247
uni_modules/uview-plus/components/u-cell/u-cell.vue
Normal file
247
uni_modules/uview-plus/components/u-cell/u-cell.vue
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
<template>
|
||||||
|
<view class="u-cell" :class="[customClass]" :style="[addStyle(customStyle)]"
|
||||||
|
:hover-class="(!disabled && (clickable || isLink)) ? 'u-cell--clickable' : ''" :hover-stay-time="250"
|
||||||
|
@tap="clickHandler">
|
||||||
|
<view class="u-cell__body" :class="[ center && 'u-cell--center', size === 'large' && 'u-cell__body--large']">
|
||||||
|
<view class="u-cell__body__content">
|
||||||
|
<view class="u-cell__left-icon-wrap" v-if="$slots.icon || icon">
|
||||||
|
<slot name="icon" v-if="$slots.icon">
|
||||||
|
</slot>
|
||||||
|
<u-icon v-else :name="icon"
|
||||||
|
:custom-style="iconStyle"
|
||||||
|
:size="size === 'large' ? 22 : 18"></u-icon>
|
||||||
|
</view>
|
||||||
|
<view class="u-cell__title">
|
||||||
|
<!-- 将slot与默认内容用if/else分开主要是因为微信小程序不支持slot嵌套传递,这样才能解决collapse组件的slot不失效问题,label暂时未用到。 -->
|
||||||
|
<slot name="title" v-if="$slots.title || !title">
|
||||||
|
</slot>
|
||||||
|
<text v-else class="u-cell__title-text" :style="[titleTextStyle]"
|
||||||
|
:class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__title-text--large']">{{ title }}</text>
|
||||||
|
<slot name="label">
|
||||||
|
<text class="u-cell__label" v-if="label"
|
||||||
|
:class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__label--large']">{{ label }}</text>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<slot name="value">
|
||||||
|
<text class="u-cell__value"
|
||||||
|
:class="[disabled && 'u-cell--disabled', size === 'large' && 'u-cell__value--large']"
|
||||||
|
v-if="!testEmpty(value)">{{ value }}</text>
|
||||||
|
</slot>
|
||||||
|
<view class="u-cell__right-icon-wrap" v-if="$slots['right-icon'] || isLink"
|
||||||
|
:class="[`u-cell__right-icon-wrap--${arrowDirection}`]">
|
||||||
|
<u-icon v-if="rightIcon && !$slots['right-icon']" :name="rightIcon"
|
||||||
|
:custom-style="rightIconStyle" :color="disabled ? '#c8c9cc' : 'info'"
|
||||||
|
:size="size === 'large' ? 18 : 16"></u-icon>
|
||||||
|
<slot v-else name="right-icon">
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<view class="u-cell__right-icon-wrap" v-if="$slots['righticon']"
|
||||||
|
:class="[`u-cell__right-icon-wrap--${arrowDirection}`]">
|
||||||
|
<slot name="righticon">
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<u-line v-if="border"></u-line>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addStyle } from '../../libs/function/index';
|
||||||
|
import test from '../../libs/function/test';
|
||||||
|
/**
|
||||||
|
* cell 单元格
|
||||||
|
* @description cell单元格一般用于一组列表的情况,比如个人中心页,设置页等。
|
||||||
|
* @tutorial https://uview-plus.jiangruyi.com/components/cell.html
|
||||||
|
* @property {String | Number} title 标题
|
||||||
|
* @property {String | Number} label 标题下方的描述信息
|
||||||
|
* @property {String | Number} value 右侧的内容
|
||||||
|
* @property {String} icon 左侧图标名称,或者图片链接(本地文件建议使用绝对地址)
|
||||||
|
* @property {Boolean} disabled 是否禁用cell
|
||||||
|
* @property {Boolean} border 是否显示下边框 (默认 true )
|
||||||
|
* @property {Boolean} center 内容是否垂直居中(主要是针对右侧的value部分) (默认 false )
|
||||||
|
* @property {String} url 点击后跳转的URL地址
|
||||||
|
* @property {String} linkType 链接跳转的方式,内部使用的是uView封装的route方法,可能会进行拦截操作 (默认 'navigateTo' )
|
||||||
|
* @property {Boolean} clickable 是否开启点击反馈(表现为点击时加上灰色背景) (默认 false )
|
||||||
|
* @property {Boolean} isLink 是否展示右侧箭头并开启点击反馈 (默认 false )
|
||||||
|
* @property {Boolean} required 是否显示表单状态下的必填星号(此组件可能会内嵌入input组件) (默认 false )
|
||||||
|
* @property {String} rightIcon 右侧的图标箭头 (默认 'arrow-right')
|
||||||
|
* @property {String} arrowDirection 右侧箭头的方向,可选值为:left,up,down
|
||||||
|
* @property {Object | String} rightIconStyle 右侧箭头图标的样式
|
||||||
|
* @property {Object | String} titleStyle 标题的样式
|
||||||
|
* @property {Object | String} iconStyle 左侧图标样式
|
||||||
|
* @property {String} size 单位元的大小,可选值为 large,normal,mini
|
||||||
|
* @property {Boolean} stop 点击cell是否阻止事件传播 (默认 true )
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
*
|
||||||
|
* @event {Function} click 点击cell列表时触发
|
||||||
|
* @example 该组件需要搭配cell-group组件使用,见官方文档示例
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-cell',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
computed: {
|
||||||
|
titleTextStyle() {
|
||||||
|
return addStyle(this.titleStyle)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ['click'],
|
||||||
|
methods: {
|
||||||
|
addStyle,
|
||||||
|
testEmpty: test.empty,
|
||||||
|
// 点击cell
|
||||||
|
clickHandler(e) {
|
||||||
|
if (this.disabled) return
|
||||||
|
this.$emit('click', {
|
||||||
|
name: this.name
|
||||||
|
})
|
||||||
|
// 如果配置了url(此props参数通过mixin引入)参数,跳转页面
|
||||||
|
this.openPage()
|
||||||
|
// 是否阻止事件传播
|
||||||
|
this.stop && this.preventEvent(e)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
$u-cell-padding: 13px 15px !default;
|
||||||
|
$u-cell-font-size: 15px !default;
|
||||||
|
$u-cell-line-height: 24px !default;
|
||||||
|
$u-cell-color: $u-main-color !default;
|
||||||
|
$u-cell-icon-size: 16px !default;
|
||||||
|
$u-cell-title-font-size: 15px !default;
|
||||||
|
$u-cell-title-line-height: 22px !default;
|
||||||
|
$u-cell-title-color: $u-main-color !default;
|
||||||
|
$u-cell-label-font-size: 12px !default;
|
||||||
|
$u-cell-label-color: $u-tips-color !default;
|
||||||
|
$u-cell-label-line-height: 18px !default;
|
||||||
|
$u-cell-value-font-size: 14px !default;
|
||||||
|
$u-cell-value-color: $u-content-color !default;
|
||||||
|
$u-cell-clickable-color: $u-bg-color !default;
|
||||||
|
$u-cell-disabled-color: #c8c9cc !default;
|
||||||
|
$u-cell-padding-top-large: 13px !default;
|
||||||
|
$u-cell-padding-bottom-large: 13px !default;
|
||||||
|
$u-cell-value-font-size-large: 15px !default;
|
||||||
|
$u-cell-label-font-size-large: 14px !default;
|
||||||
|
$u-cell-title-font-size-large: 16px !default;
|
||||||
|
$u-cell-left-icon-wrap-margin-right: 4px !default;
|
||||||
|
$u-cell-right-icon-wrap-margin-left: 4px !default;
|
||||||
|
$u-cell-title-flex:1 !default;
|
||||||
|
$u-cell-label-margin-top:5px !default;
|
||||||
|
|
||||||
|
|
||||||
|
.u-cell {
|
||||||
|
&__body {
|
||||||
|
@include flex();
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
padding: $u-cell-padding;
|
||||||
|
font-size: $u-cell-font-size;
|
||||||
|
color: $u-cell-color;
|
||||||
|
// line-height: $u-cell-line-height;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
@include flex(row);
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--large {
|
||||||
|
padding-top: $u-cell-padding-top-large;
|
||||||
|
padding-bottom: $u-cell-padding-bottom-large;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__left-icon-wrap,
|
||||||
|
&__right-icon-wrap {
|
||||||
|
@include flex();
|
||||||
|
align-items: center;
|
||||||
|
// height: $u-cell-line-height;
|
||||||
|
font-size: $u-cell-icon-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__left-icon-wrap {
|
||||||
|
margin-right: $u-cell-left-icon-wrap-margin-right;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__right-icon-wrap {
|
||||||
|
margin-left: $u-cell-right-icon-wrap-margin-left;
|
||||||
|
transition: transform 0.3s;
|
||||||
|
|
||||||
|
&--up {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--down {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
flex: $u-cell-title-flex;
|
||||||
|
|
||||||
|
&-text {
|
||||||
|
font-size: $u-cell-title-font-size;
|
||||||
|
line-height: $u-cell-title-line-height;
|
||||||
|
color: $u-cell-title-color;
|
||||||
|
|
||||||
|
&--large {
|
||||||
|
font-size: $u-cell-title-font-size-large;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&__label {
|
||||||
|
margin-top: $u-cell-label-margin-top;
|
||||||
|
font-size: $u-cell-label-font-size;
|
||||||
|
color: $u-cell-label-color;
|
||||||
|
line-height: $u-cell-label-line-height;
|
||||||
|
|
||||||
|
&--large {
|
||||||
|
font-size: $u-cell-label-font-size-large;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__value {
|
||||||
|
text-align: right;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
margin-left: auto;
|
||||||
|
/* #endif */
|
||||||
|
font-size: $u-cell-value-font-size;
|
||||||
|
line-height: $u-cell-line-height;
|
||||||
|
color: $u-cell-value-color;
|
||||||
|
&--large {
|
||||||
|
font-size: $u-cell-value-font-size-large;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--clickable {
|
||||||
|
background-color: $u-cell-clickable-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
color: $u-cell-disabled-color;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
cursor: not-allowed;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
&--center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
92
uni_modules/uview-plus/components/u-checkbox-group/props.js
Normal file
92
uni_modules/uview-plus/components/u-checkbox-group/props.js
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 标识符
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkboxGroup.name
|
||||||
|
},
|
||||||
|
// #ifdef VUE3
|
||||||
|
// 绑定的值
|
||||||
|
modelValue: {
|
||||||
|
type: Array,
|
||||||
|
default: () => defProps.checkboxGroup.value
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE2
|
||||||
|
// 绑定的值
|
||||||
|
value: {
|
||||||
|
type: Array,
|
||||||
|
default: () => defProps.checkboxGroup.value
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// 形状,circle-圆形,square-方形
|
||||||
|
shape: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkboxGroup.shape
|
||||||
|
},
|
||||||
|
// 是否禁用全部checkbox
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.checkboxGroup.disabled
|
||||||
|
},
|
||||||
|
|
||||||
|
// 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
|
||||||
|
activeColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkboxGroup.activeColor
|
||||||
|
},
|
||||||
|
// 未选中的颜色
|
||||||
|
inactiveColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkboxGroup.inactiveColor
|
||||||
|
},
|
||||||
|
|
||||||
|
// 整个组件的尺寸,默认px
|
||||||
|
size: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.checkboxGroup.size
|
||||||
|
},
|
||||||
|
// 布局方式,row-横向,column-纵向
|
||||||
|
placement: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkboxGroup.placement
|
||||||
|
},
|
||||||
|
// label的字体大小,px单位
|
||||||
|
labelSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.checkboxGroup.labelSize
|
||||||
|
},
|
||||||
|
// label的字体颜色
|
||||||
|
labelColor: {
|
||||||
|
type: [String],
|
||||||
|
default: () => defProps.checkboxGroup.labelColor
|
||||||
|
},
|
||||||
|
// 是否禁止点击文本操作
|
||||||
|
labelDisabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.checkboxGroup.labelDisabled
|
||||||
|
},
|
||||||
|
// 图标颜色
|
||||||
|
iconColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkboxGroup.iconColor
|
||||||
|
},
|
||||||
|
// 图标的大小,单位px
|
||||||
|
iconSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.checkboxGroup.iconSize
|
||||||
|
},
|
||||||
|
// 勾选图标的对齐方式,left-左边,right-右边
|
||||||
|
iconPlacement: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkboxGroup.iconPlacement
|
||||||
|
},
|
||||||
|
// 竖向配列时,是否显示下划线
|
||||||
|
borderBottom: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.checkboxGroup.borderBottom
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
<template>
|
||||||
|
<view
|
||||||
|
class="u-checkbox-group"
|
||||||
|
:class="bemClass"
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
/**
|
||||||
|
* checkboxGroup 复选框组
|
||||||
|
* @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/checkbox.html
|
||||||
|
* @property {String} name 标识符
|
||||||
|
* @property {Array} value 绑定的值
|
||||||
|
* @property {String} shape 形状,circle-圆形,square-方形 (默认 'square' )
|
||||||
|
* @property {Boolean} disabled 是否禁用全部checkbox (默认 false )
|
||||||
|
* @property {String} activeColor 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 (默认 '#2979ff' )
|
||||||
|
* @property {String} inactiveColor 未选中的颜色 (默认 '#c8c9cc' )
|
||||||
|
* @property {String | Number} size 整个组件的尺寸 单位px (默认 18 )
|
||||||
|
* @property {String} placement 布局方式,row-横向,column-纵向 (默认 'row' )
|
||||||
|
* @property {String | Number} labelSize label的字体大小,px单位 (默认 14 )
|
||||||
|
* @property {String} labelColor label的字体颜色 (默认 '#303133' )
|
||||||
|
* @property {Boolean} labelDisabled 是否禁止点击文本操作 (默认 false )
|
||||||
|
* @property {String} iconColor 图标颜色 (默认 '#ffffff' )
|
||||||
|
* @property {String | Number} iconSize 图标的大小,单位px (默认 12 )
|
||||||
|
* @property {String} iconPlacement 勾选图标的对齐方式,left-左边,right-右边 (默认 'left' )
|
||||||
|
* @property {Boolean} borderBottom placement为row时,是否显示下边框 (默认 false )
|
||||||
|
* @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
|
||||||
|
* @event {Function} input 修改通过v-model绑定的值时触发,回调为一个对象
|
||||||
|
* @example <u-checkbox-group></u-checkbox-group>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-checkbox-group',
|
||||||
|
mixins: [mpMixin, mixin,props],
|
||||||
|
computed: {
|
||||||
|
// 这里computed的变量,都是子组件u-checkbox需要用到的,由于头条小程序的兼容性差异,子组件无法实时监听父组件参数的变化
|
||||||
|
// 所以需要手动通知子组件,这里返回一个parentData变量,供watch监听,在其中去通知每一个子组件重新从父组件(u-checkbox-group)
|
||||||
|
// 拉取父组件新的变化后的参数
|
||||||
|
parentData() {
|
||||||
|
return [
|
||||||
|
// #ifdef VUE2
|
||||||
|
this.value,
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
this.modelValue,
|
||||||
|
// #endif
|
||||||
|
this.disabled,
|
||||||
|
this.inactiveColor,
|
||||||
|
this.activeColor,
|
||||||
|
this.size,
|
||||||
|
this.labelDisabled,
|
||||||
|
this.shape,
|
||||||
|
this.iconSize,
|
||||||
|
this.borderBottom,
|
||||||
|
this.placement,
|
||||||
|
];
|
||||||
|
},
|
||||||
|
bemClass() {
|
||||||
|
// this.bem为一个computed变量,在mixin中
|
||||||
|
return this.bem('checkbox-group', ['placement'])
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件
|
||||||
|
parentData: {
|
||||||
|
handler() {
|
||||||
|
if (this.children.length) {
|
||||||
|
this.children.map((child) => {
|
||||||
|
// 判断子组件(u-checkbox)如果有init方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
|
||||||
|
typeof child.init === "function" && child.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.children = []
|
||||||
|
},
|
||||||
|
// #ifdef VUE3
|
||||||
|
emits: ['update:modelValue', 'change'],
|
||||||
|
// #endif
|
||||||
|
methods: {
|
||||||
|
// 将其他的checkbox设置为未选中的状态
|
||||||
|
unCheckedOther(childInstance) {
|
||||||
|
const values = []
|
||||||
|
this.children.map(child => {
|
||||||
|
// 将被选中的checkbox,放到数组中返回
|
||||||
|
if (child.isChecked) {
|
||||||
|
values.push(child.name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 发出事件
|
||||||
|
this.$emit('change', values)
|
||||||
|
// 修改通过v-model绑定的值
|
||||||
|
// #ifdef VUE3
|
||||||
|
this.$emit("update:modelValue", values);
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE2
|
||||||
|
this.$emit("input", values);
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
.u-checkbox-group {
|
||||||
|
|
||||||
|
&--row {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-flow: row wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--column {
|
||||||
|
@include flex(column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
75
uni_modules/uview-plus/components/u-checkbox/props.js
Normal file
75
uni_modules/uview-plus/components/u-checkbox/props.js
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// checkbox的名称
|
||||||
|
name: {
|
||||||
|
type: [String, Number, Boolean],
|
||||||
|
default: () => defProps.checkbox.name
|
||||||
|
},
|
||||||
|
// 形状,square为方形,circle为圆型
|
||||||
|
shape: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkbox.shape
|
||||||
|
},
|
||||||
|
// 整体的大小
|
||||||
|
size: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.checkbox.size
|
||||||
|
},
|
||||||
|
// 是否默认选中
|
||||||
|
checked: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.checkbox.checked
|
||||||
|
},
|
||||||
|
// 是否禁用
|
||||||
|
disabled: {
|
||||||
|
type: [String, Boolean],
|
||||||
|
default: () => defProps.checkbox.disabled
|
||||||
|
},
|
||||||
|
// 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
|
||||||
|
activeColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkbox.activeColor
|
||||||
|
},
|
||||||
|
// 未选中的颜色
|
||||||
|
inactiveColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkbox.inactiveColor
|
||||||
|
},
|
||||||
|
// 图标的大小,单位px
|
||||||
|
iconSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.checkbox.iconSize
|
||||||
|
},
|
||||||
|
// 图标颜色
|
||||||
|
iconColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkbox.iconColor
|
||||||
|
},
|
||||||
|
// label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式
|
||||||
|
label: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.checkbox.label
|
||||||
|
},
|
||||||
|
// label的字体大小,px单位
|
||||||
|
labelSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.checkbox.labelSize
|
||||||
|
},
|
||||||
|
// label的颜色
|
||||||
|
labelColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.checkbox.labelColor
|
||||||
|
},
|
||||||
|
// 是否禁止点击提示语选中复选框
|
||||||
|
labelDisabled: {
|
||||||
|
type: [String, Boolean],
|
||||||
|
default: () => defProps.checkbox.labelDisabled
|
||||||
|
},
|
||||||
|
// 是否独立使用
|
||||||
|
usedAlone: {
|
||||||
|
type: [Boolean],
|
||||||
|
default: () => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
374
uni_modules/uview-plus/components/u-checkbox/u-checkbox.vue
Normal file
374
uni_modules/uview-plus/components/u-checkbox/u-checkbox.vue
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
<template>
|
||||||
|
<view
|
||||||
|
class="u-checkbox cursor-pointer"
|
||||||
|
:style="[checkboxStyle]"
|
||||||
|
@tap.stop="wrapperClickHandler"
|
||||||
|
:class="[`u-checkbox-label--${parentData.iconPlacement}`, parentData.borderBottom && parentData.placement === 'column' && 'u-border-bottom']"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-checkbox__icon-wrap cursor-pointer"
|
||||||
|
@tap.stop="iconClickHandler"
|
||||||
|
:class="iconClasses"
|
||||||
|
:style="[iconWrapStyle]"
|
||||||
|
>
|
||||||
|
<slot name="icon">
|
||||||
|
<u-icon
|
||||||
|
class="u-checkbox__icon-wrap__icon"
|
||||||
|
name="checkbox-mark"
|
||||||
|
:size="elIconSize"
|
||||||
|
:color="elIconColor"
|
||||||
|
/>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<text
|
||||||
|
@tap.stop="labelClickHandler"
|
||||||
|
:style="{
|
||||||
|
color: elDisabled ? elInactiveColor : elLabelColor,
|
||||||
|
fontSize: elLabelSize,
|
||||||
|
lineHeight: elLabelSize
|
||||||
|
}"
|
||||||
|
>{{label}}</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addStyle, addUnit, deepMerge, formValidate, error } from '../../libs/function/index';
|
||||||
|
import test from '../../libs/function/test';
|
||||||
|
/**
|
||||||
|
* checkbox 复选框
|
||||||
|
* @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
|
||||||
|
* @tutorial https://uview-plus.jiangruyi.com/components/checkbox.html
|
||||||
|
* @property {String | Number | Boolean} name checkbox组件的标示符
|
||||||
|
* @property {String} shape 形状,square为方形,circle为圆型
|
||||||
|
* @property {String | Number} size 整体的大小
|
||||||
|
* @property {Boolean} checked 是否默认选中
|
||||||
|
* @property {String | Boolean} disabled 是否禁用
|
||||||
|
* @property {String} activeColor 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
|
||||||
|
* @property {String} inactiveColor 未选中的颜色
|
||||||
|
* @property {String | Number} iconSize 图标的大小,单位px
|
||||||
|
* @property {String} iconColor 图标颜色
|
||||||
|
* @property {String | Number} label label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式
|
||||||
|
* @property {String} labelColor label的颜色
|
||||||
|
* @property {String | Number} labelSize label的字体大小,px单位
|
||||||
|
* @property {String | Boolean} labelDisabled 是否禁止点击提示语选中复选框
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
*
|
||||||
|
* @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
|
||||||
|
* @example <u-checkbox v-model="checked" :disabled="false">天涯</u-checkbox>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: "u-checkbox",
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isChecked: false,
|
||||||
|
// 父组件的默认值,因为头条小程序不支持在computed中使用this.parent.shape的形式
|
||||||
|
// 故只能使用如此方法
|
||||||
|
parentData: {
|
||||||
|
iconSize: 12,
|
||||||
|
labelDisabled: null,
|
||||||
|
disabled: null,
|
||||||
|
shape: 'square',
|
||||||
|
activeColor: null,
|
||||||
|
inactiveColor: null,
|
||||||
|
size: 18,
|
||||||
|
// #ifdef VUE2
|
||||||
|
value: null,
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue: null,
|
||||||
|
// #endif
|
||||||
|
iconColor: null,
|
||||||
|
placement: 'row',
|
||||||
|
borderBottom: false,
|
||||||
|
iconPlacement: 'left'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 是否禁用,如果父组件u-raios-group禁用的话,将会忽略子组件的配置
|
||||||
|
elDisabled() {
|
||||||
|
return this.disabled !== '' ? this.disabled : this.parentData.disabled !== null ? this.parentData.disabled : false;
|
||||||
|
},
|
||||||
|
// 是否禁用label点击
|
||||||
|
elLabelDisabled() {
|
||||||
|
return this.labelDisabled !== '' ? this.labelDisabled : this.parentData.labelDisabled !== null ? this.parentData.labelDisabled :
|
||||||
|
false;
|
||||||
|
},
|
||||||
|
// 组件尺寸,对应size的值,默认值为21px
|
||||||
|
elSize() {
|
||||||
|
return this.size ? this.size : (this.parentData.size ? this.parentData.size : 21);
|
||||||
|
},
|
||||||
|
// 组件的勾选图标的尺寸,默认12px
|
||||||
|
elIconSize() {
|
||||||
|
return this.iconSize ? this.iconSize : (this.parentData.iconSize ? this.parentData.iconSize : 12);
|
||||||
|
},
|
||||||
|
// 组件选中激活时的颜色
|
||||||
|
elActiveColor() {
|
||||||
|
return this.activeColor ? this.activeColor : (this.parentData.activeColor ? this.parentData.activeColor : '#2979ff');
|
||||||
|
},
|
||||||
|
// 组件选未中激活时的颜色
|
||||||
|
elInactiveColor() {
|
||||||
|
return this.inactiveColor ? this.inactiveColor : (this.parentData.inactiveColor ? this.parentData.inactiveColor :
|
||||||
|
'#c8c9cc');
|
||||||
|
},
|
||||||
|
// label的颜色
|
||||||
|
elLabelColor() {
|
||||||
|
return this.labelColor ? this.labelColor : (this.parentData.labelColor ? this.parentData.labelColor : '#606266')
|
||||||
|
},
|
||||||
|
// 组件的形状
|
||||||
|
elShape() {
|
||||||
|
return this.shape ? this.shape : (this.parentData.shape ? this.parentData.shape : 'circle');
|
||||||
|
},
|
||||||
|
// label大小
|
||||||
|
elLabelSize() {
|
||||||
|
return addUnit(this.labelSize ? this.labelSize : (this.parentData.labelSize ? this.parentData.labelSize :
|
||||||
|
'15'))
|
||||||
|
},
|
||||||
|
elIconColor() {
|
||||||
|
const iconColor = this.iconColor ? this.iconColor : (this.parentData.iconColor ? this.parentData.iconColor :
|
||||||
|
'#ffffff');
|
||||||
|
// 图标的颜色
|
||||||
|
if (this.elDisabled) {
|
||||||
|
// disabled状态下,已勾选的checkbox图标改为elInactiveColor
|
||||||
|
return this.isChecked ? this.elInactiveColor : 'transparent'
|
||||||
|
} else {
|
||||||
|
return this.isChecked ? iconColor : 'transparent'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
iconClasses() {
|
||||||
|
let classes = []
|
||||||
|
// 组件的形状
|
||||||
|
classes.push('u-checkbox__icon-wrap--' + this.elShape)
|
||||||
|
if (this.elDisabled) {
|
||||||
|
classes.push('u-checkbox__icon-wrap--disabled')
|
||||||
|
}
|
||||||
|
if (this.isChecked && this.elDisabled) {
|
||||||
|
classes.push('u-checkbox__icon-wrap--disabled--checked')
|
||||||
|
}
|
||||||
|
// 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
|
||||||
|
// #ifdef MP-ALIPAY || MP-TOUTIAO
|
||||||
|
classes = classes.join(' ')
|
||||||
|
// #endif
|
||||||
|
return classes
|
||||||
|
},
|
||||||
|
iconWrapStyle() {
|
||||||
|
// checkbox的整体样式
|
||||||
|
const style = {}
|
||||||
|
style.backgroundColor = this.isChecked && !this.elDisabled ? this.elActiveColor : '#ffffff'
|
||||||
|
style.borderColor = this.isChecked && !this.elDisabled ? this.elActiveColor : this.elInactiveColor
|
||||||
|
style.width = addUnit(this.elSize)
|
||||||
|
style.height = addUnit(this.elSize)
|
||||||
|
// 如果是图标在右边的话,移除它的右边距
|
||||||
|
if (!this.usedAlone) {
|
||||||
|
if (this.parentData.iconPlacement === 'right') {
|
||||||
|
style.marginRight = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
},
|
||||||
|
checkboxStyle() {
|
||||||
|
const style = {}
|
||||||
|
if (!this.usedAlone) {
|
||||||
|
if (this.parentData.borderBottom && this.parentData.placement === 'row') {
|
||||||
|
error('检测到您将borderBottom设置为true,需要同时将u-checkbox-group的placement设置为column才有效')
|
||||||
|
}
|
||||||
|
// 当父组件设置了显示下边框并且排列形式为纵向时,给内容和边框之间加上一定间隔
|
||||||
|
if (this.parentData.borderBottom && this.parentData.placement === 'column') {
|
||||||
|
style.paddingBottom = '8px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deepMerge(style, addStyle(this.customStyle))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
emits: ["change"],
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
if (!this.usedAlone) {
|
||||||
|
// 支付宝小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环引用
|
||||||
|
this.updateParentData()
|
||||||
|
if (!this.parent) {
|
||||||
|
error('u-checkbox必须搭配u-checkbox-group组件使用')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #ifdef VUE2
|
||||||
|
const value = this.parentData.value
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
const value = this.parentData.modelValue
|
||||||
|
// #endif
|
||||||
|
// 设置初始化时,是否默认选中的状态,父组件u-checkbox-group的value可能是array,所以额外判断
|
||||||
|
if (this.checked) {
|
||||||
|
this.isChecked = true
|
||||||
|
} else if (!this.usedAlone && test.array(value)) {
|
||||||
|
// 查找数组是是否存在this.name元素值
|
||||||
|
this.isChecked = value.some(item => {
|
||||||
|
return item === this.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateParentData() {
|
||||||
|
this.getParentData('u-checkbox-group')
|
||||||
|
},
|
||||||
|
// 横向两端排列时,点击组件即可触发选中事件
|
||||||
|
wrapperClickHandler(e) {
|
||||||
|
if (!this.usedAlone) {
|
||||||
|
this.parentData.iconPlacement === 'right' && this.iconClickHandler(e)
|
||||||
|
} else {
|
||||||
|
this.iconClickHandler(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 点击图标
|
||||||
|
iconClickHandler(e) {
|
||||||
|
this.preventEvent(e)
|
||||||
|
// 如果整体被禁用,不允许被点击
|
||||||
|
if (!this.elDisabled) {
|
||||||
|
this.setRadioCheckedStatus()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 点击label
|
||||||
|
labelClickHandler(e) {
|
||||||
|
this.preventEvent(e)
|
||||||
|
// 如果按钮整体被禁用或者label被禁用,则不允许点击文字修改状态
|
||||||
|
if (!this.elLabelDisabled && !this.elDisabled) {
|
||||||
|
this.setRadioCheckedStatus()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emitEvent() {
|
||||||
|
this.$emit('change', this.isChecked)
|
||||||
|
// 尝试调用u-form的验证方法,进行一定延迟,否则微信小程序更新可能会不及时
|
||||||
|
this.$nextTick(() => {
|
||||||
|
formValidate(this, 'change')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 改变组件选中状态
|
||||||
|
// 这里的改变的依据是,更改本组件的checked值为true,同时通过父组件遍历所有u-checkbox实例
|
||||||
|
// 将本组件外的其他u-checkbox的checked都设置为false(都被取消选中状态),因而只剩下一个为选中状态
|
||||||
|
setRadioCheckedStatus() {
|
||||||
|
// 将本组件标记为与原来相反的状态
|
||||||
|
this.isChecked = !this.isChecked
|
||||||
|
this.emitEvent()
|
||||||
|
if (!this.usedAlone) {
|
||||||
|
typeof this.parent.unCheckedOther === 'function' && this.parent.unCheckedOther(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
checked(){
|
||||||
|
this.isChecked = this.checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
$u-checkbox-icon-wrap-margin-right:6px !default;
|
||||||
|
$u-checkbox-icon-wrap-font-size:6px !default;
|
||||||
|
$u-checkbox-icon-wrap-border-width:1px !default;
|
||||||
|
$u-checkbox-icon-wrap-border-color:#c8c9cc !default;
|
||||||
|
$u-checkbox-icon-wrap-icon-line-height:0 !default;
|
||||||
|
$u-checkbox-icon-wrap-circle-border-radius:100% !default;
|
||||||
|
$u-checkbox-icon-wrap-square-border-radius:3px !default;
|
||||||
|
$u-checkbox-icon-wrap-checked-color:#fff !default;
|
||||||
|
$u-checkbox-icon-wrap-checked-background-color:red !default;
|
||||||
|
$u-checkbox-icon-wrap-checked-border-color:#2979ff !default;
|
||||||
|
$u-checkbox-icon-wrap-disabled-background-color:#ebedf0 !default;
|
||||||
|
$u-checkbox-icon-wrap-disabled-checked-color:#c8c9cc !default;
|
||||||
|
$u-checkbox-label-margin-left:5px !default;
|
||||||
|
$u-checkbox-label-margin-right:12px !default;
|
||||||
|
$u-checkbox-label-color:$u-content-color !default;
|
||||||
|
$u-checkbox-label-font-size:15px !default;
|
||||||
|
$u-checkbox-label-disabled-color:#c8c9cc !default;
|
||||||
|
|
||||||
|
.u-checkbox {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
@include flex(row);
|
||||||
|
/* #endif */
|
||||||
|
overflow: hidden;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
|
||||||
|
&-label--left {
|
||||||
|
flex-direction: row
|
||||||
|
}
|
||||||
|
|
||||||
|
&-label--right {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
justify-content: space-between
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon-wrap {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
box-sizing: border-box;
|
||||||
|
// nvue下,border-color过渡有问题
|
||||||
|
transition-property: border-color, background-color, color;
|
||||||
|
transition-duration: 0.2s;
|
||||||
|
/* #endif */
|
||||||
|
color: $u-content-color;
|
||||||
|
@include flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: transparent;
|
||||||
|
text-align: center;
|
||||||
|
margin-right: $u-checkbox-icon-wrap-margin-right;
|
||||||
|
|
||||||
|
font-size: $u-checkbox-icon-wrap-font-size;
|
||||||
|
border-width: $u-checkbox-icon-wrap-border-width;
|
||||||
|
border-color: $u-checkbox-icon-wrap-border-color;
|
||||||
|
border-style: solid;
|
||||||
|
|
||||||
|
/* #ifdef MP-TOUTIAO */
|
||||||
|
// 头条小程序兼容性问题,需要设置行高为0,否则图标偏下
|
||||||
|
&__icon {
|
||||||
|
line-height: $u-checkbox-icon-wrap-icon-line-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
&--circle {
|
||||||
|
border-radius: $u-checkbox-icon-wrap-circle-border-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--square {
|
||||||
|
border-radius: $u-checkbox-icon-wrap-square-border-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--checked {
|
||||||
|
color: $u-checkbox-icon-wrap-checked-color;
|
||||||
|
background-color: $u-checkbox-icon-wrap-checked-background-color;
|
||||||
|
border-color: $u-checkbox-icon-wrap-checked-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
background-color: $u-checkbox-icon-wrap-disabled-background-color !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled--checked {
|
||||||
|
color: $u-checkbox-icon-wrap-disabled-checked-color !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__label {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
word-wrap: break-word;
|
||||||
|
/* #endif */
|
||||||
|
margin-left: $u-checkbox-label-margin-left;
|
||||||
|
margin-right: $u-checkbox-label-margin-right;
|
||||||
|
color: $u-checkbox-label-color;
|
||||||
|
font-size: $u-checkbox-label-font-size;
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
color: $u-checkbox-label-disabled-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,9 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
percentage: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.circleProgress.percentage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,201 @@
|
||||||
|
<template>
|
||||||
|
<view class="u-circle-progress">
|
||||||
|
<view class="u-circle-progress__left">
|
||||||
|
<view
|
||||||
|
class="u-circle-progress__left__circle"
|
||||||
|
:style="[leftSyle]"
|
||||||
|
ref="left-circle"
|
||||||
|
>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="u-circle-progress__right"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-circle-progress__right__circle"
|
||||||
|
ref="right-circle"
|
||||||
|
:style="[rightSyle]"
|
||||||
|
>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="u-circle-progress__circle">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import {sleep } from '../../libs/function/index';
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
const animation = uni.requireNativePlugin('animation')
|
||||||
|
// #endif
|
||||||
|
/**
|
||||||
|
* CircleProgress 圆形进度条 TODO: 待完善
|
||||||
|
* @description 展示操作或任务的当前进度,比如上传文件,是一个圆形的进度环。
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/circleProgress.html
|
||||||
|
* @property {String | Number} percentage 圆环进度百分比值,为数值类型,0-100 (默认 30 )
|
||||||
|
* @example
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-circle-progress',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
leftBorderColor: 'rgb(200, 200, 200)',
|
||||||
|
rightBorderColor: 'rgb(200, 200, 200)',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
leftSyle() {
|
||||||
|
const style = {}
|
||||||
|
style.borderTopColor = this.leftBorderColor
|
||||||
|
style.borderRightColor = this.leftBorderColor
|
||||||
|
return style
|
||||||
|
},
|
||||||
|
rightSyle() {
|
||||||
|
const style = {}
|
||||||
|
style.borderLeftColor = this.rightBorderColor
|
||||||
|
style.borderBottomColor = this.rightBorderColor
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
sleep().then(() => {
|
||||||
|
this.rightBorderColor = 'rgb(66, 185, 131)'
|
||||||
|
// this.init()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
animation.transition(this.$refs['right-circle'].ref, {
|
||||||
|
styles: {
|
||||||
|
transform: 'rotate(45deg)',
|
||||||
|
transformOrigin: 'center center'
|
||||||
|
},
|
||||||
|
}, () => {
|
||||||
|
this.rightBorderColor = 'rgb(66, 185, 131)'
|
||||||
|
// animation.transition(this.$refs['right-circle'].ref, {
|
||||||
|
// styles: {
|
||||||
|
// transform: 'rotate(225deg)',
|
||||||
|
// transformOrigin: 'center center'
|
||||||
|
// },
|
||||||
|
// duration: 3000,
|
||||||
|
// }, () => {
|
||||||
|
// animation.transition(this.$refs['left-circle'].ref, {
|
||||||
|
// styles: {
|
||||||
|
// transform: 'rotate(45deg)',
|
||||||
|
// transformOrigin: 'center center'
|
||||||
|
// },
|
||||||
|
// }, () => {
|
||||||
|
// this.leftBorderColor = 'rgb(66, 185, 131)'
|
||||||
|
// animation.transition(this.$refs['left-circle'].ref, {
|
||||||
|
// styles: {
|
||||||
|
// transform: 'rotate(225deg)',
|
||||||
|
// transformOrigin: 'center center'
|
||||||
|
// },
|
||||||
|
// duration: 1500,
|
||||||
|
// }, () => {
|
||||||
|
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
.u-circle-progress {
|
||||||
|
@include flex(row);
|
||||||
|
position: relative;
|
||||||
|
border-radius: 100px;
|
||||||
|
height: 100px;
|
||||||
|
width: 100px;
|
||||||
|
// transform: rotate(0deg);
|
||||||
|
// background-color: rgb(66, 185, 131);
|
||||||
|
background-color: rgb(200, 200, 200);
|
||||||
|
overflow: hidden;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
&__circle {
|
||||||
|
border-radius: 100px;
|
||||||
|
height: 90px;
|
||||||
|
width: 90px;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: rgb(255, 255, 255);
|
||||||
|
left: 50px;
|
||||||
|
top: 50px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__left {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 50px;
|
||||||
|
height: 100px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
// background-color: rgb(66, 185, 131);
|
||||||
|
// background-color: rgb(200, 200, 200);
|
||||||
|
// transform-origin: left center;
|
||||||
|
|
||||||
|
&__circle {
|
||||||
|
box-sizing: border-box;
|
||||||
|
// background-color: red;
|
||||||
|
border-left-color: transparent;
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
border-top-left-radius: 50px;
|
||||||
|
border-top-right-radius: 50px;
|
||||||
|
border-bottom-right-radius: 50px;
|
||||||
|
// border-left-color: rgb(66, 185, 131);
|
||||||
|
// border-bottom-color: rgb(66, 185, 131);
|
||||||
|
border-top-color: rgb(66, 185, 131);
|
||||||
|
border-right-color: rgb(66, 185, 131);
|
||||||
|
border-width: 5px;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
transform: rotate(225deg);
|
||||||
|
// border-radius: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__right {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
width: 50px;
|
||||||
|
height: 100px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&__circle {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
// background-color: red;
|
||||||
|
border-top-color: transparent;
|
||||||
|
border-right-color: transparent;
|
||||||
|
border-top-left-radius: 50px;
|
||||||
|
border-bottom-left-radius: 50px;
|
||||||
|
border-bottom-right-radius: 50px;
|
||||||
|
// border-left-color: rgb(66, 185, 131);
|
||||||
|
// border-bottom-color: rgb(66, 185, 131);
|
||||||
|
border-left-color: rgb(200, 200, 200);
|
||||||
|
border-bottom-color: rgb(200, 200, 200);
|
||||||
|
border-width: 5px;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
transform-origin: center center;
|
||||||
|
// border-radius: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
89
uni_modules/uview-plus/components/u-code-input/props.js
Normal file
89
uni_modules/uview-plus/components/u-code-input/props.js
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 键盘弹起时,是否自动上推页面
|
||||||
|
adjustPosition: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.codeInput.adjustPosition
|
||||||
|
},
|
||||||
|
// 最大输入长度
|
||||||
|
maxlength: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.codeInput.maxlength
|
||||||
|
},
|
||||||
|
// 是否用圆点填充
|
||||||
|
dot: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.codeInput.dot
|
||||||
|
},
|
||||||
|
// 显示模式,box-盒子模式,line-底部横线模式
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.codeInput.mode
|
||||||
|
},
|
||||||
|
// 是否细边框
|
||||||
|
hairline: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.codeInput.hairline
|
||||||
|
},
|
||||||
|
// 字符间的距离
|
||||||
|
space: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.codeInput.space
|
||||||
|
},
|
||||||
|
// #ifdef VUE3
|
||||||
|
// 预置值
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.codeInput.value
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE2
|
||||||
|
// 预置值
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.codeInput.value
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// 是否自动获取焦点
|
||||||
|
focus: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.codeInput.focus
|
||||||
|
},
|
||||||
|
// 字体是否加粗
|
||||||
|
bold: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.codeInput.bold
|
||||||
|
},
|
||||||
|
// 字体颜色
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.codeInput.color
|
||||||
|
},
|
||||||
|
// 字体大小
|
||||||
|
fontSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.codeInput.fontSize
|
||||||
|
},
|
||||||
|
// 输入框的大小,宽等于高
|
||||||
|
size: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.codeInput.size
|
||||||
|
},
|
||||||
|
// 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true
|
||||||
|
disabledKeyboard: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.codeInput.disabledKeyboard
|
||||||
|
},
|
||||||
|
// 边框和线条颜色
|
||||||
|
borderColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.codeInput.borderColor
|
||||||
|
},
|
||||||
|
// 是否禁止输入"."符号
|
||||||
|
disabledDot: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.codeInput.disabledDot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
266
uni_modules/uview-plus/components/u-code-input/u-code-input.vue
Normal file
266
uni_modules/uview-plus/components/u-code-input/u-code-input.vue
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
<template>
|
||||||
|
<view class="u-code-input">
|
||||||
|
<view
|
||||||
|
class="u-code-input__item"
|
||||||
|
:style="[itemStyle(index)]"
|
||||||
|
v-for="(item, index) in codeLength"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-code-input__item__dot"
|
||||||
|
v-if="dot && codeArray.length > index"
|
||||||
|
></view>
|
||||||
|
<text
|
||||||
|
v-else
|
||||||
|
:style="{
|
||||||
|
fontSize: addUnit(fontSize),
|
||||||
|
fontWeight: bold ? 'bold' : 'normal',
|
||||||
|
color: color
|
||||||
|
}"
|
||||||
|
>{{codeArray[index]}}</text>
|
||||||
|
<view
|
||||||
|
class="u-code-input__item__line"
|
||||||
|
v-if="mode === 'line'"
|
||||||
|
:style="[lineStyle]"
|
||||||
|
></view>
|
||||||
|
<!-- #ifndef APP-PLUS -->
|
||||||
|
<view v-if="isFocus && codeArray.length === index" :style="{backgroundColor: color}" class="u-code-input__item__cursor"></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
<input
|
||||||
|
:disabled="disabledKeyboard"
|
||||||
|
type="number"
|
||||||
|
:focus="focus"
|
||||||
|
:value="inputValue"
|
||||||
|
:maxlength="maxlength"
|
||||||
|
:adjustPosition="adjustPosition"
|
||||||
|
class="u-code-input__input"
|
||||||
|
@input="inputHandler"
|
||||||
|
:style="{
|
||||||
|
height: addUnit(size)
|
||||||
|
}"
|
||||||
|
@focus="isFocus = true"
|
||||||
|
@blur="isFocus = false"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addUnit, getPx } from '../../libs/function/index';
|
||||||
|
/**
|
||||||
|
* CodeInput 验证码输入
|
||||||
|
* @description 该组件一般用于验证用户短信验证码的场景,也可以结合uview-plus的键盘组件使用
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/codeInput.html
|
||||||
|
* @property {String | Number} maxlength 最大输入长度 (默认 6 )
|
||||||
|
* @property {Boolean} dot 是否用圆点填充 (默认 false )
|
||||||
|
* @property {String} mode 显示模式,box-盒子模式,line-底部横线模式 (默认 'box' )
|
||||||
|
* @property {Boolean} hairline 是否细边框 (默认 false )
|
||||||
|
* @property {String | Number} space 字符间的距离 (默认 10 )
|
||||||
|
* @property {String | Number} value 预置值
|
||||||
|
* @property {Boolean} focus 是否自动获取焦点 (默认 false )
|
||||||
|
* @property {Boolean} bold 字体和输入横线是否加粗 (默认 false )
|
||||||
|
* @property {String} color 字体颜色 (默认 '#606266' )
|
||||||
|
* @property {String | Number} fontSize 字体大小,单位px (默认 18 )
|
||||||
|
* @property {String | Number} size 输入框的大小,宽等于高 (默认 35 )
|
||||||
|
* @property {Boolean} disabledKeyboard 是否隐藏原生键盘,如果想用自定义键盘的话,需设置此参数为true (默认 false )
|
||||||
|
* @property {String} borderColor 边框和线条颜色 (默认 '#c9cacc' )
|
||||||
|
* @property {Boolean} disabledDot 是否禁止输入"."符号 (默认 true )
|
||||||
|
*
|
||||||
|
* @event {Function} change 输入内容发生改变时触发,具体见上方说明 value:当前输入的值
|
||||||
|
* @event {Function} finish 输入字符个数达maxlength值时触发,见上方说明 value:当前输入的值
|
||||||
|
* @example <u-code-input v-model="value4" :focus="true"></u-code-input>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-code-input',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
inputValue: '',
|
||||||
|
isFocus: this.focus
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// #ifdef VUE2
|
||||||
|
value: {
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue: {
|
||||||
|
// #endif
|
||||||
|
immediate: true,
|
||||||
|
handler(val) {
|
||||||
|
// 转为字符串,超出部分截掉
|
||||||
|
this.inputValue = String(val).substring(0, this.maxlength)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 根据长度,循环输入框的个数,因为头条小程序数值不能用于v-for
|
||||||
|
codeLength() {
|
||||||
|
return new Array(Number(this.maxlength))
|
||||||
|
},
|
||||||
|
// 循环item的样式
|
||||||
|
itemStyle() {
|
||||||
|
return index => {
|
||||||
|
const style = {
|
||||||
|
width: addUnit(this.size),
|
||||||
|
height: addUnit(this.size)
|
||||||
|
}
|
||||||
|
// 盒子模式下,需要额外进行处理
|
||||||
|
if (this.mode === 'box') {
|
||||||
|
// 设置盒子的边框,如果是细边框,则设置为0.5px宽度
|
||||||
|
style.border = `${this.hairline ? 0.5 : 1}px solid ${this.borderColor}`
|
||||||
|
// 如果盒子间距为0的话
|
||||||
|
if (getPx(this.space) === 0) {
|
||||||
|
// 给第一和最后一个盒子设置圆角
|
||||||
|
if (index === 0) {
|
||||||
|
style.borderTopLeftRadius = '3px'
|
||||||
|
style.borderBottomLeftRadius = '3px'
|
||||||
|
}
|
||||||
|
if (index === this.codeLength.length - 1) {
|
||||||
|
style.borderTopRightRadius = '3px'
|
||||||
|
style.borderBottomRightRadius = '3px'
|
||||||
|
}
|
||||||
|
// 最后一个盒子的右边框需要保留
|
||||||
|
if (index !== this.codeLength.length - 1) {
|
||||||
|
style.borderRight = 'none'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index !== this.codeLength.length - 1) {
|
||||||
|
// 设置验证码字符之间的距离,通过margin-right设置,最后一个字符,无需右边框
|
||||||
|
style.marginRight = addUnit(this.space)
|
||||||
|
} else {
|
||||||
|
// 最后一个盒子的有边框需要保留
|
||||||
|
style.marginRight = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 将输入的值,转为数组,给item历遍时,根据当前的索引显示数组的元素
|
||||||
|
codeArray() {
|
||||||
|
return String(this.inputValue).split('')
|
||||||
|
},
|
||||||
|
// 下划线模式下,横线的样式
|
||||||
|
lineStyle() {
|
||||||
|
const style = {}
|
||||||
|
style.height = this.hairline ? '2px' : '4px'
|
||||||
|
style.width = addUnit(this.size)
|
||||||
|
// 线条模式下,背景色即为边框颜色
|
||||||
|
style.backgroundColor = this.borderColor
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ["change", 'finish', "update:modelValue"],
|
||||||
|
methods: {
|
||||||
|
addUnit,
|
||||||
|
// 监听输入框的值发生变化
|
||||||
|
inputHandler(e) {
|
||||||
|
const value = e.detail.value
|
||||||
|
this.inputValue = value
|
||||||
|
// 是否允许输入“.”符号
|
||||||
|
if(this.disabledDot) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.inputValue = value.replace('.', '')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 未达到maxlength之前,发送change事件,达到后发送finish事件
|
||||||
|
this.$emit('change', value)
|
||||||
|
// 修改通过v-model双向绑定的值
|
||||||
|
// #ifdef VUE3
|
||||||
|
this.$emit("update:modelValue", value);
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE2
|
||||||
|
this.$emit("input", value);
|
||||||
|
// #endif
|
||||||
|
// 达到用户指定输入长度时,发出完成事件
|
||||||
|
if (String(value).length >= Number(this.maxlength)) {
|
||||||
|
this.$emit('finish', value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
$u-code-input-cursor-width: 1px;
|
||||||
|
$u-code-input-cursor-height: 40%;
|
||||||
|
$u-code-input-cursor-animation-duration: 1s;
|
||||||
|
$u-code-input-cursor-animation-name: u-cursor-flicker;
|
||||||
|
|
||||||
|
.u-code-input {
|
||||||
|
@include flex;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
@include flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
font-size: 15px;
|
||||||
|
color: $u-content-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__dot {
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
border-radius: 100px;
|
||||||
|
background-color: $u-content-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__line {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
height: 4px;
|
||||||
|
border-radius: 100px;
|
||||||
|
width: 40px;
|
||||||
|
background-color: $u-content-color;
|
||||||
|
}
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
&__cursor {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%,-50%);
|
||||||
|
width: $u-code-input-cursor-width;
|
||||||
|
height: $u-code-input-cursor-height;
|
||||||
|
animation: $u-code-input-cursor-animation-duration u-cursor-flicker infinite;
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input {
|
||||||
|
// 之所以需要input输入框,是因为有它才能唤起键盘
|
||||||
|
// 这里将它设置为两倍的屏幕宽度,再将左边的一半移出屏幕,为了不让用户看到输入的内容
|
||||||
|
position: absolute;
|
||||||
|
left: -750rpx;
|
||||||
|
width: 1500rpx;
|
||||||
|
top: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #ifndef APP-PLUS */
|
||||||
|
@keyframes u-cursor-flicker {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
</style>
|
35
uni_modules/uview-plus/components/u-code/props.js
Normal file
35
uni_modules/uview-plus/components/u-code/props.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 倒计时总秒数
|
||||||
|
seconds: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.code.seconds
|
||||||
|
},
|
||||||
|
// 尚未开始时提示
|
||||||
|
startText: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.code.startText
|
||||||
|
},
|
||||||
|
// 正在倒计时中的提示
|
||||||
|
changeText: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.code.changeText
|
||||||
|
},
|
||||||
|
// 倒计时结束时的提示
|
||||||
|
endText: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.code.endText
|
||||||
|
},
|
||||||
|
// 是否在H5刷新或各端返回再进入时继续倒计时
|
||||||
|
keepRunning: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.code.keepRunning
|
||||||
|
},
|
||||||
|
// 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
|
||||||
|
uniqueKey: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.code.uniqueKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
137
uni_modules/uview-plus/components/u-code/u-code.vue
Normal file
137
uni_modules/uview-plus/components/u-code/u-code.vue
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
<template>
|
||||||
|
<view class="u-code">
|
||||||
|
<!-- 此组件功能由js完成,无需写html逻辑 -->
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
/**
|
||||||
|
* Code 验证码输入框
|
||||||
|
* @description 考虑到用户实际发送验证码的场景,可能是一个按钮,也可能是一段文字,提示语各有不同,所以本组件 不提供界面显示,只提供提示语,由用户将提示语嵌入到具体的场景
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/code.html
|
||||||
|
* @property {String | Number} seconds 倒计时所需的秒数(默认 60 )
|
||||||
|
* @property {String} startText 开始前的提示语,见官网说明(默认 '获取验证码' )
|
||||||
|
* @property {String} changeText 倒计时期间的提示语,必须带有字母"x",见官网说明(默认 'X秒重新获取' )
|
||||||
|
* @property {String} endText 倒计结束的提示语,见官网说明(默认 '重新获取' )
|
||||||
|
* @property {Boolean} keepRunning 是否在H5刷新或各端返回再进入时继续倒计时( 默认false )
|
||||||
|
* @property {String} uniqueKey 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
|
||||||
|
*
|
||||||
|
* @event {Function} change 倒计时期间,每秒触发一次
|
||||||
|
* @event {Function} start 开始倒计时触发
|
||||||
|
* @event {Function} end 结束倒计时触发
|
||||||
|
* @example <u-code ref="uCode" @change="codeChange" seconds="20"></u-code>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: "u-code",
|
||||||
|
mixins: [mpMixin, mixin,props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
secNum: this.seconds,
|
||||||
|
timer: null,
|
||||||
|
canGetCode: true, // 是否可以执行验证码操作
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.checkKeepRunning()
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
seconds: {
|
||||||
|
immediate: true,
|
||||||
|
handler(n) {
|
||||||
|
this.secNum = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ["start", "end", "change"],
|
||||||
|
methods: {
|
||||||
|
checkKeepRunning() {
|
||||||
|
// 获取上一次退出页面(H5还包括刷新)时的时间戳,如果没有上次的保存,此值可能为空
|
||||||
|
let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$uCountDownTimestamp'))
|
||||||
|
if(!lastTimestamp) return this.changeEvent(this.startText)
|
||||||
|
// 当前秒的时间戳
|
||||||
|
let nowTimestamp = Math.floor((+ new Date()) / 1000)
|
||||||
|
// 判断当前的时间戳,是否小于上一次的本该按设定结束,却提前结束的时间戳
|
||||||
|
if(this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {
|
||||||
|
// 剩余尚未执行完的倒计秒数
|
||||||
|
this.secNum = lastTimestamp - nowTimestamp
|
||||||
|
// 清除本地保存的变量
|
||||||
|
uni.removeStorageSync(this.uniqueKey + '_$uCountDownTimestamp')
|
||||||
|
// 开始倒计时
|
||||||
|
this.start()
|
||||||
|
} else {
|
||||||
|
// 如果不存在需要继续上一次的倒计时,执行正常的逻辑
|
||||||
|
this.changeEvent(this.startText)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 开始倒计时
|
||||||
|
start() {
|
||||||
|
// 防止快速点击获取验证码的按钮而导致内部产生多个定时器导致混乱
|
||||||
|
if(this.timer) {
|
||||||
|
clearInterval(this.timer)
|
||||||
|
this.timer = null
|
||||||
|
}
|
||||||
|
this.$emit('start')
|
||||||
|
this.canGetCode = false
|
||||||
|
// 这里放这句,是为了一开始时就提示,否则要等setInterval的1秒后才会有提示
|
||||||
|
this.changeEvent(this.changeText.replace(/x|X/, this.secNum))
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
if (--this.secNum) {
|
||||||
|
// 用当前倒计时的秒数替换提示字符串中的"x"字母
|
||||||
|
this.changeEvent(this.changeText.replace(/x|X/, this.secNum))
|
||||||
|
} else {
|
||||||
|
clearInterval(this.timer)
|
||||||
|
this.timer = null
|
||||||
|
this.changeEvent(this.endText)
|
||||||
|
this.secNum = this.seconds
|
||||||
|
this.$emit('end')
|
||||||
|
this.canGetCode = true
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
this.setTimeToStorage()
|
||||||
|
},
|
||||||
|
// 重置,可以让用户再次获取验证码
|
||||||
|
reset() {
|
||||||
|
this.canGetCode = true
|
||||||
|
clearInterval(this.timer)
|
||||||
|
this.secNum = this.seconds
|
||||||
|
this.changeEvent(this.endText)
|
||||||
|
},
|
||||||
|
changeEvent(text) {
|
||||||
|
this.$emit('change', text)
|
||||||
|
},
|
||||||
|
// 保存时间戳,为了防止倒计时尚未结束,H5刷新或者各端的右上角返回上一页再进来
|
||||||
|
setTimeToStorage() {
|
||||||
|
if(!this.keepRunning || !this.timer) return
|
||||||
|
// 记录当前的时间戳,为了下次进入页面,如果还在倒计时内的话,继续倒计时
|
||||||
|
// 倒计时尚未结束,结果大于0;倒计时已经开始,就会小于初始值,如果等于初始值,说明没有开始倒计时,无需处理
|
||||||
|
if(this.secNum > 0 && this.secNum < this.seconds) {
|
||||||
|
// 获取当前时间戳(+ new Date()为特殊写法),除以1000变成秒,再去除小数部分
|
||||||
|
let nowTimestamp = Math.floor((+ new Date()) / 1000)
|
||||||
|
// 将本该结束时候的时间戳保存起来 => 当前时间戳 + 剩余的秒数
|
||||||
|
uni.setStorage({
|
||||||
|
key: this.uniqueKey + '_$uCountDownTimestamp',
|
||||||
|
data: nowTimestamp + Number(this.secNum)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 组件销毁的时候,清除定时器,否则定时器会继续存在,系统不会自动清除
|
||||||
|
// #ifdef VUE2
|
||||||
|
beforeDestroy() {
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
beforeUnmount() {
|
||||||
|
// #endif
|
||||||
|
this.setTimeToStorage()
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
this.timer = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
</style>
|
30
uni_modules/uview-plus/components/u-col/props.js
Normal file
30
uni_modules/uview-plus/components/u-col/props.js
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 占父容器宽度的多少等分,总分为12份
|
||||||
|
span: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.col.span
|
||||||
|
},
|
||||||
|
// 指定栅格左侧的间隔数(总12栏)
|
||||||
|
offset: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.col.offset
|
||||||
|
},
|
||||||
|
// 水平排列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`)
|
||||||
|
justify: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.col.justify
|
||||||
|
},
|
||||||
|
// 垂直对齐方式,可选值为top、center、bottom、stretch
|
||||||
|
align: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.col.align
|
||||||
|
},
|
||||||
|
// 文字对齐方式
|
||||||
|
textAlign: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.col.textAlign
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
170
uni_modules/uview-plus/components/u-col/u-col.vue
Normal file
170
uni_modules/uview-plus/components/u-col/u-col.vue
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
<template>
|
||||||
|
<view
|
||||||
|
class="u-col"
|
||||||
|
ref="u-col"
|
||||||
|
:class="[
|
||||||
|
'u-col-' + span
|
||||||
|
]"
|
||||||
|
:style="[colStyle]"
|
||||||
|
@tap="clickHandler"
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addStyle, addUnit, deepMerge, getPx } from '../../libs/function/index';
|
||||||
|
/**
|
||||||
|
* CodeInput 栅格系统的列
|
||||||
|
* @description 该组件一般用于Layout 布局 通过基础的 12 分栏,迅速简便地创建布局
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/Layout.html
|
||||||
|
* @property {String | Number} span 栅格占据的列数,总12等份 (默认 12 )
|
||||||
|
* @property {String | Number} offset 分栏左边偏移,计算方式与span相同 (默认 0 )
|
||||||
|
* @property {String} justify 水平排列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`) (默认 'start' )
|
||||||
|
* @property {String} align 垂直对齐方式,可选值为top、center、bottom、stretch (默认 'stretch' )
|
||||||
|
* @property {String} textAlign 文字水平对齐方式 (默认 'left' )
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
* @event {Function} click col被点击,会阻止事件冒泡到row
|
||||||
|
* @example <u-col span="3" offset="3" > <view class="demo-layout bg-purple"></view> </u-col>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-col',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
width: 0,
|
||||||
|
parentData: {
|
||||||
|
gutter: 0
|
||||||
|
},
|
||||||
|
gridNum: 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 微信小程序中 options 选项
|
||||||
|
options: {
|
||||||
|
virtualHost: true // 将自定义节点设置成虚拟的,更加接近Vue组件的表现。我们不希望自定义组件的这个节点本身可以设置样式、响应 flex 布局等
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
uJustify() {
|
||||||
|
if (this.justify == 'end' || this.justify == 'start') return 'flex-' + this.justify
|
||||||
|
else if (this.justify == 'around' || this.justify == 'between') return 'space-' + this.justify
|
||||||
|
else return this.justify
|
||||||
|
},
|
||||||
|
uAlignItem() {
|
||||||
|
if (this.align == 'top') return 'flex-start'
|
||||||
|
if (this.align == 'bottom') return 'flex-end'
|
||||||
|
else return this.align
|
||||||
|
},
|
||||||
|
colStyle() {
|
||||||
|
const style = {
|
||||||
|
// 这里写成"padding: 0 10px"的形式是因为nvue的需要
|
||||||
|
paddingLeft: addUnit(getPx(this.parentData.gutter)/2),
|
||||||
|
paddingRight: addUnit(getPx(this.parentData.gutter)/2),
|
||||||
|
alignItems: this.uAlignItem,
|
||||||
|
justifyContent: this.uJustify,
|
||||||
|
textAlign: this.textAlign,
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
// 在非nvue上,使用百分比形式
|
||||||
|
flex: `0 0 ${100 / this.gridNum * this.span}%`,
|
||||||
|
marginLeft: 100 / 12 * this.offset + '%',
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
// 在nvue上,由于无法使用百分比单位,这里需要获取父组件的宽度,再计算得出该有对应的百分比尺寸
|
||||||
|
width: addUnit(Math.floor(this.width / this.gridNum * Number(this.span))),
|
||||||
|
marginLeft: addUnit(Math.floor(this.width / this.gridNum * Number(this.offset))),
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
return deepMerge(style, addStyle(this.customStyle))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
emits: ["click"],
|
||||||
|
methods: {
|
||||||
|
async init() {
|
||||||
|
// 支付宝小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环引用
|
||||||
|
this.updateParentData()
|
||||||
|
this.width = await this.parent.getComponentWidth()
|
||||||
|
},
|
||||||
|
updateParentData() {
|
||||||
|
this.getParentData('u-row')
|
||||||
|
},
|
||||||
|
clickHandler(e) {
|
||||||
|
this.$emit('click');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
.u-col {
|
||||||
|
padding: 0;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
box-sizing:border-box;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifdef MP */
|
||||||
|
display: block;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
// nvue下百分比无效
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
.u-col-0 {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-1 {
|
||||||
|
width: calc(100%/12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-2 {
|
||||||
|
width: calc(100%/12 * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-3 {
|
||||||
|
width: calc(100%/12 * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-4 {
|
||||||
|
width: calc(100%/12 * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-5 {
|
||||||
|
width: calc(100%/12 * 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-6 {
|
||||||
|
width: calc(100%/12 * 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-7 {
|
||||||
|
width: calc(100%/12 * 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-8 {
|
||||||
|
width: calc(100%/12 * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-9 {
|
||||||
|
width: calc(100%/12 * 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-10 {
|
||||||
|
width: calc(100%/12 * 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-11 {
|
||||||
|
width: calc(100%/12 * 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-col-12 {
|
||||||
|
width: calc(100%/12 * 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
</style>
|
60
uni_modules/uview-plus/components/u-collapse-item/props.js
Normal file
60
uni_modules/uview-plus/components/u-collapse-item/props.js
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 标题
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.collapseItem.title
|
||||||
|
},
|
||||||
|
// 标题右侧内容
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.collapseItem.value
|
||||||
|
},
|
||||||
|
// 标题下方的描述信息
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.collapseItem.label
|
||||||
|
},
|
||||||
|
// 是否禁用折叠面板
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.collapseItem.disabled
|
||||||
|
},
|
||||||
|
// 是否展示右侧箭头并开启点击反馈
|
||||||
|
isLink: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.collapseItem.isLink
|
||||||
|
},
|
||||||
|
// 是否开启点击反馈
|
||||||
|
clickable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.collapseItem.clickable
|
||||||
|
},
|
||||||
|
// 是否显示内边框
|
||||||
|
border: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.collapseItem.border
|
||||||
|
},
|
||||||
|
// 标题的对齐方式
|
||||||
|
align: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.collapseItem.align
|
||||||
|
},
|
||||||
|
// 唯一标识符
|
||||||
|
name: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.collapseItem.name
|
||||||
|
},
|
||||||
|
// 标题左侧图片,可为绝对路径的图片或内置图标
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.collapseItem.icon
|
||||||
|
},
|
||||||
|
// 面板展开收起的过渡时间,单位ms
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
default: () => defProps.collapseItem.duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,240 @@
|
||||||
|
<template>
|
||||||
|
<view class="u-collapse-item">
|
||||||
|
<u-cell
|
||||||
|
:title="$slots.title ? '' : title"
|
||||||
|
:value="value"
|
||||||
|
:label="label"
|
||||||
|
:icon="icon"
|
||||||
|
:isLink="isLink"
|
||||||
|
:clickable="clickable"
|
||||||
|
:border="parentData.border && showBorder"
|
||||||
|
@click="clickHandler"
|
||||||
|
:arrowDirection="expanded ? 'up' : 'down'"
|
||||||
|
:disabled="disabled"
|
||||||
|
>
|
||||||
|
<!-- 微信小程序不支持,因为微信中不支持 <slot name="title" #title />的写法 -->
|
||||||
|
<template #title>
|
||||||
|
<slot name="title">
|
||||||
|
<text v-if="!$slots.title && title">
|
||||||
|
{{title}}
|
||||||
|
</text>
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
<template #icon>
|
||||||
|
<slot name="icon">
|
||||||
|
<u-icon v-if="!$slots.icon && icon" :size="22" :name="icon"></u-icon>
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
<template #value>
|
||||||
|
<slot name="value">
|
||||||
|
<text v-if="!$slots.value && value">
|
||||||
|
{{value}}
|
||||||
|
</text>
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
<template #right-icon>
|
||||||
|
<u-icon v-if="!$slots['right-icon']" :size="16" name="arrow-right"></u-icon>
|
||||||
|
<slot name="right-icon">
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
</u-cell>
|
||||||
|
<view
|
||||||
|
class="u-collapse-item__content"
|
||||||
|
:animation="animationData"
|
||||||
|
ref="animation"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-collapse-item__content__text content-class"
|
||||||
|
:id="elId"
|
||||||
|
:ref="elId"
|
||||||
|
><slot /></view>
|
||||||
|
</view>
|
||||||
|
<u-line v-if="parentData.border"></u-line>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props.js';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { nextTick } from 'vue';
|
||||||
|
import { guid, sleep, error } from '../../libs/function/index';
|
||||||
|
import test from '../../libs/function/test';
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
const animation = uni.requireNativePlugin('animation')
|
||||||
|
const dom = uni.requireNativePlugin('dom')
|
||||||
|
// #endif
|
||||||
|
/**
|
||||||
|
* collapseItem 折叠面板Item
|
||||||
|
* @description 通过折叠面板收纳内容区域(搭配u-collapse使用)
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/collapse.html
|
||||||
|
* @property {String} title 标题
|
||||||
|
* @property {String} value 标题右侧内容
|
||||||
|
* @property {String} label 标题下方的描述信息
|
||||||
|
* @property {Boolean} disbled 是否禁用折叠面板 ( 默认 false )
|
||||||
|
* @property {Boolean} isLink 是否展示右侧箭头并开启点击反馈 ( 默认 true )
|
||||||
|
* @property {Boolean} clickable 是否开启点击反馈 ( 默认 true )
|
||||||
|
* @property {Boolean} border 是否显示内边框 ( 默认 true )
|
||||||
|
* @property {String} align 标题的对齐方式 ( 默认 'left' )
|
||||||
|
* @property {String | Number} name 唯一标识符
|
||||||
|
* @property {String} icon 标题左侧图片,可为绝对路径的图片或内置图标
|
||||||
|
* @event {Function} change 某个item被打开或者收起时触发
|
||||||
|
* @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: "u-collapse-item",
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
elId: guid(),
|
||||||
|
// uni.createAnimation的导出数据
|
||||||
|
animationData: {},
|
||||||
|
// 是否展开状态
|
||||||
|
expanded: false,
|
||||||
|
// 根据expanded确定是否显示border,为了控制展开时,cell的下划线更好的显示效果,进行一定时间的延时
|
||||||
|
showBorder: false,
|
||||||
|
// 是否动画中,如果是则不允许继续触发点击
|
||||||
|
animating: false,
|
||||||
|
// 父组件u-collapse的参数
|
||||||
|
parentData: {
|
||||||
|
accordion: false,
|
||||||
|
border: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
expanded(n) {
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
this.timer = null
|
||||||
|
// 这里根据expanded的值来进行一定的延时,是为了cell的下划线更好的显示效果
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
this.showBorder = n
|
||||||
|
}, n ? 10 : 290)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
// console.log('$slots', this.$slots)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 异步获取内容,或者动态修改了内容时,需要重新初始化
|
||||||
|
async init() {
|
||||||
|
// 初始化数据
|
||||||
|
this.updateParentData()
|
||||||
|
if (!this.parent) {
|
||||||
|
return error('u-collapse-item必须要搭配u-collapse组件使用')
|
||||||
|
}
|
||||||
|
const {
|
||||||
|
value,
|
||||||
|
accordion,
|
||||||
|
children = []
|
||||||
|
} = this.parent
|
||||||
|
|
||||||
|
if (accordion) {
|
||||||
|
if (test.array(value)) {
|
||||||
|
return error('手风琴模式下,u-collapse组件的value参数不能为数组')
|
||||||
|
}
|
||||||
|
this.expanded = this.name == value
|
||||||
|
} else {
|
||||||
|
if (!test.array(value) && value !== null) {
|
||||||
|
return error('非手风琴模式下,u-collapse组件的value参数必须为数组')
|
||||||
|
}
|
||||||
|
this.expanded = (value || []).some(item => item == this.name)
|
||||||
|
}
|
||||||
|
// 设置组件的展开或收起状态
|
||||||
|
await nextTick()
|
||||||
|
this.setContentAnimate()
|
||||||
|
},
|
||||||
|
updateParentData() {
|
||||||
|
// 此方法在mixin中
|
||||||
|
this.getParentData('u-collapse')
|
||||||
|
},
|
||||||
|
async setContentAnimate() {
|
||||||
|
// 每次面板打开或者收起时,都查询元素尺寸
|
||||||
|
// 好处是,父组件从服务端获取内容后,变更折叠面板后可以获得最新的高度
|
||||||
|
const rect = await this.queryRect()
|
||||||
|
const height = this.expanded ? rect.height : 0
|
||||||
|
this.animating = true
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
const ref = this.$refs['animation'].ref
|
||||||
|
animation.transition(ref, {
|
||||||
|
styles: {
|
||||||
|
height: height + 'px'
|
||||||
|
},
|
||||||
|
duration: this.duration,
|
||||||
|
// 必须设置为true,否则会到面板收起或展开时,页面其他元素不会随之调整它们的布局
|
||||||
|
needLayout: true,
|
||||||
|
timingFunction: 'ease-in-out',
|
||||||
|
}, () => {
|
||||||
|
this.animating = false
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
const animation = uni.createAnimation({
|
||||||
|
timingFunction: 'ease-in-out',
|
||||||
|
});
|
||||||
|
animation
|
||||||
|
.height(height)
|
||||||
|
.step({
|
||||||
|
duration: this.duration,
|
||||||
|
})
|
||||||
|
.step()
|
||||||
|
// 导出动画数据给面板的animationData值
|
||||||
|
this.animationData = animation.export()
|
||||||
|
// 标识动画结束
|
||||||
|
sleep(this.duration).then(() => {
|
||||||
|
this.animating = false
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
// 点击collapsehead头部
|
||||||
|
clickHandler() {
|
||||||
|
if (this.disabled && this.animating) return
|
||||||
|
// 设置本组件为相反的状态
|
||||||
|
this.parent && this.parent.onChange(this)
|
||||||
|
},
|
||||||
|
// 查询内容高度
|
||||||
|
queryRect() {
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
// $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://ijry.github.io/uview-plus/js/getRect.html
|
||||||
|
// 组件内部一般用this.$uGetRect,对外的为uni.$u.getRect,二者功能一致,名称不同
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this.$uGetRect(`#${this.elId}`).then(size => {
|
||||||
|
resolve(size)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
// nvue下,使用dom模块查询元素高度
|
||||||
|
// 返回一个promise,让调用此方法的主体能使用then回调
|
||||||
|
return new Promise(resolve => {
|
||||||
|
dom.getComponentRect(this.$refs[this.elId], res => {
|
||||||
|
resolve(res.size)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
.u-collapse-item {
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
overflow: hidden;
|
||||||
|
height: 0;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
padding: 12px 15px;
|
||||||
|
color: $u-content-color;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
20
uni_modules/uview-plus/components/u-collapse/props.js
Normal file
20
uni_modules/uview-plus/components/u-collapse/props.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 当前展开面板的name,非手风琴模式:[<string | number>],手风琴模式:string | number
|
||||||
|
value: {
|
||||||
|
type: [String, Number, Array, null],
|
||||||
|
default: () => defProps.collapse.value
|
||||||
|
},
|
||||||
|
// 是否手风琴模式
|
||||||
|
accordion: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.collapse.accordion
|
||||||
|
},
|
||||||
|
// 是否显示外边框
|
||||||
|
border: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.collapse.border
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
91
uni_modules/uview-plus/components/u-collapse/u-collapse.vue
Normal file
91
uni_modules/uview-plus/components/u-collapse/u-collapse.vue
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<template>
|
||||||
|
<view class="u-collapse">
|
||||||
|
<u-line v-if="border"></u-line>
|
||||||
|
<slot />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
/**
|
||||||
|
* collapse 折叠面板
|
||||||
|
* @description 通过折叠面板收纳内容区域
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/collapse.html
|
||||||
|
* @property {String | Number | Array} value 当前展开面板的name,非手风琴模式:[<string | number>],手风琴模式:string | number
|
||||||
|
* @property {Boolean} accordion 是否手风琴模式( 默认 false )
|
||||||
|
* @property {Boolean} border 是否显示外边框 ( 默认 true )
|
||||||
|
* @event {Function} change 当前激活面板展开时触发(如果是手风琴模式,参数activeNames类型为String,否则为Array)
|
||||||
|
* @example <u-collapse></u-collapse>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: "u-collapse",
|
||||||
|
mixins: [mpMixin, mixin,props],
|
||||||
|
watch: {
|
||||||
|
needInit() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
// 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件
|
||||||
|
parentData() {
|
||||||
|
if (this.children.length) {
|
||||||
|
this.children.map(child => {
|
||||||
|
// 判断子组件(u-checkbox)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
|
||||||
|
typeof(child.updateParentData) === 'function' && child.updateParentData()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.children = []
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
needInit() {
|
||||||
|
// 通过computed,同时监听accordion和value值的变化
|
||||||
|
// 再通过watch去执行init()方法,进行再一次的初始化
|
||||||
|
return [this.accordion, this.value]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ["open", "close", "change"],
|
||||||
|
methods: {
|
||||||
|
// 重新初始化一次内部的所有子元素
|
||||||
|
init() {
|
||||||
|
this.children.map(child => {
|
||||||
|
child.init()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* collapse-item被点击时触发,由collapse统一处理各子组件的状态
|
||||||
|
* @param {Object} target 被操作的面板的实例
|
||||||
|
*/
|
||||||
|
onChange(target) {
|
||||||
|
let changeArr = []
|
||||||
|
this.children.map((child, index) => {
|
||||||
|
// 如果是手风琴模式,将其他的折叠面板收起来
|
||||||
|
if (this.accordion) {
|
||||||
|
child.expanded = child === target ? !target.expanded : false
|
||||||
|
child.setContentAnimate()
|
||||||
|
} else {
|
||||||
|
if(child === target) {
|
||||||
|
child.expanded = !child.expanded
|
||||||
|
child.setContentAnimate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 拼接change事件中,数组元素的状态
|
||||||
|
changeArr.push({
|
||||||
|
// 如果没有定义name属性,则默认返回组件的index索引
|
||||||
|
name: child.name || index,
|
||||||
|
status: child.expanded ? 'open' : 'close'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$emit('change', changeArr)
|
||||||
|
this.$emit(target.expanded ? 'open' : 'close', target.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
</style>
|
56
uni_modules/uview-plus/components/u-column-notice/props.js
Normal file
56
uni_modules/uview-plus/components/u-column-notice/props.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 显示的内容,字符串
|
||||||
|
text: {
|
||||||
|
type: [Array],
|
||||||
|
default: () => defProps.columnNotice.text
|
||||||
|
},
|
||||||
|
// 是否显示左侧的音量图标
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.columnNotice.icon
|
||||||
|
},
|
||||||
|
// 通告模式,link-显示右箭头,closable-显示右侧关闭图标
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.columnNotice.mode
|
||||||
|
},
|
||||||
|
// 文字颜色,各图标也会使用文字颜色
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.columnNotice.color
|
||||||
|
},
|
||||||
|
// 背景颜色
|
||||||
|
bgColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.columnNotice.bgColor
|
||||||
|
},
|
||||||
|
// 字体大小,单位px
|
||||||
|
fontSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.columnNotice.fontSize
|
||||||
|
},
|
||||||
|
// 水平滚动时的滚动速度,即每秒滚动多少px(px),这有利于控制文字无论多少时,都能有一个恒定的速度
|
||||||
|
speed: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.columnNotice.speed
|
||||||
|
},
|
||||||
|
// direction = row时,是否使用步进形式滚动
|
||||||
|
step: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.columnNotice.step
|
||||||
|
},
|
||||||
|
// 滚动一个周期的时间长,单位ms
|
||||||
|
duration: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.columnNotice.duration
|
||||||
|
},
|
||||||
|
// 是否禁止用手滑动切换
|
||||||
|
// 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序
|
||||||
|
disableTouch: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.columnNotice.disableTouch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
<template>
|
||||||
|
<view
|
||||||
|
class="u-notice"
|
||||||
|
@tap="clickHandler"
|
||||||
|
>
|
||||||
|
<slot name="icon">
|
||||||
|
<view
|
||||||
|
class="u-notice__left-icon"
|
||||||
|
v-if="icon"
|
||||||
|
>
|
||||||
|
<u-icon
|
||||||
|
:name="icon"
|
||||||
|
:color="color"
|
||||||
|
size="19"
|
||||||
|
></u-icon>
|
||||||
|
</view>
|
||||||
|
</slot>
|
||||||
|
<swiper
|
||||||
|
:disable-touch="disableTouch"
|
||||||
|
:vertical="step ? false : true"
|
||||||
|
circular
|
||||||
|
:interval="duration"
|
||||||
|
:autoplay="true"
|
||||||
|
class="u-notice__swiper"
|
||||||
|
@change="noticeChange"
|
||||||
|
>
|
||||||
|
<swiper-item
|
||||||
|
v-for="(item, index) in text"
|
||||||
|
:key="index"
|
||||||
|
class="u-notice__swiper__item"
|
||||||
|
>
|
||||||
|
<text
|
||||||
|
class="u-notice__swiper__item__text u-line-1"
|
||||||
|
:style="[textStyle]"
|
||||||
|
>{{ item }}</text>
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
<view
|
||||||
|
class="u-notice__right-icon"
|
||||||
|
v-if="['link', 'closable'].includes(mode)"
|
||||||
|
>
|
||||||
|
<u-icon
|
||||||
|
v-if="mode === 'link'"
|
||||||
|
name="arrow-right"
|
||||||
|
:size="17"
|
||||||
|
:color="color"
|
||||||
|
></u-icon>
|
||||||
|
<u-icon
|
||||||
|
v-if="mode === 'closable'"
|
||||||
|
name="close"
|
||||||
|
:size="16"
|
||||||
|
:color="color"
|
||||||
|
@click="close"
|
||||||
|
></u-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addUnit, error } from '../../libs/function/index';
|
||||||
|
import test from '../../libs/function/test';
|
||||||
|
/**
|
||||||
|
* ColumnNotice 滚动通知中的垂直滚动 内部组件
|
||||||
|
* @description 该组件用于滚动通告场景,是其中的垂直滚动方式
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/noticeBar.html
|
||||||
|
* @property {Array} text 显示的内容,字符串
|
||||||
|
* @property {String} icon 是否显示左侧的音量图标 ( 默认 'volume' )
|
||||||
|
* @property {String} mode 通告模式,link-显示右箭头,closable-显示右侧关闭图标
|
||||||
|
* @property {String} color 文字颜色,各图标也会使用文字颜色 ( 默认 '#f9ae3d' )
|
||||||
|
* @property {String} bgColor 背景颜色 ( 默认 '#fdf6ec' )
|
||||||
|
* @property {String | Number} fontSize 字体大小,单位px ( 默认 14 )
|
||||||
|
* @property {String | Number} speed 水平滚动时的滚动速度,即每秒滚动多少px(rpx),这有利于控制文字无论多少时,都能有一个恒定的速度 ( 默认 80 )
|
||||||
|
* @property {Boolean} step direction = row时,是否使用步进形式滚动 ( 默认 false )
|
||||||
|
* @property {String | Number} duration 滚动一个周期的时间长,单位ms ( 默认 1500 )
|
||||||
|
* @property {Boolean} disableTouch 是否禁止用手滑动切换 目前HX2.6.11,只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序 ( 默认 true )
|
||||||
|
* @example
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
watch: {
|
||||||
|
text: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newValue, oldValue) {
|
||||||
|
if(!test.array(newValue)) {
|
||||||
|
error('noticebar组件direction为column时,要求text参数为数组形式')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 文字内容的样式
|
||||||
|
textStyle() {
|
||||||
|
let style = {}
|
||||||
|
style.color = this.color
|
||||||
|
style.fontSize = addUnit(this.fontSize)
|
||||||
|
return style
|
||||||
|
},
|
||||||
|
// 垂直或者水平滚动
|
||||||
|
vertical() {
|
||||||
|
if (this.mode == 'horizontal') return false
|
||||||
|
else return true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
index:0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ["click", "close"],
|
||||||
|
methods: {
|
||||||
|
noticeChange(e){
|
||||||
|
this.index = e.detail.current
|
||||||
|
},
|
||||||
|
// 点击通告栏
|
||||||
|
clickHandler() {
|
||||||
|
this.$emit('click', this.index)
|
||||||
|
},
|
||||||
|
// 点击关闭按钮
|
||||||
|
close() {
|
||||||
|
this.$emit('close')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
.u-notice {
|
||||||
|
@include flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
&__left-icon {
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__right-icon {
|
||||||
|
margin-left: 5px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__swiper {
|
||||||
|
height: 16px;
|
||||||
|
@include flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
@include flex;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: $u-warning;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
70
uni_modules/uview-plus/components/u-copy/u-copy.vue
Normal file
70
uni_modules/uview-plus/components/u-copy/u-copy.vue
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
<template>
|
||||||
|
<view @click="handleClick">
|
||||||
|
<slot>复制</slot>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "xy-copy",
|
||||||
|
props: {
|
||||||
|
content: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
alertStyle: {
|
||||||
|
type: String,
|
||||||
|
default: 'toast'
|
||||||
|
},
|
||||||
|
notice: {
|
||||||
|
type: String,
|
||||||
|
default: '复制成功'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: ['success'],
|
||||||
|
methods: {
|
||||||
|
handleClick() {
|
||||||
|
let content = this.content;
|
||||||
|
if (!content) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '暂无',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
content = typeof content === 'string' ? content : content.toString() // 复制内容,必须字符串,数字需要转换为字符串
|
||||||
|
/**
|
||||||
|
* 小程序端 和 app端的复制逻辑
|
||||||
|
*/
|
||||||
|
let that = this;
|
||||||
|
uni.setClipboardData({
|
||||||
|
data: content,
|
||||||
|
success: function() {
|
||||||
|
if (that.alertStyle == 'modal') {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: that.notice
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: that.notice,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
that.$emit('success');
|
||||||
|
},
|
||||||
|
fail:function(){
|
||||||
|
uni.showToast({
|
||||||
|
title: '复制失败',
|
||||||
|
icon: 'none',
|
||||||
|
duration:3000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
25
uni_modules/uview-plus/components/u-count-down/props.js
Normal file
25
uni_modules/uview-plus/components/u-count-down/props.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 倒计时时长,单位ms
|
||||||
|
time: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.countDown.time
|
||||||
|
},
|
||||||
|
// 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒
|
||||||
|
format: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.countDown.format
|
||||||
|
},
|
||||||
|
// 是否自动开始倒计时
|
||||||
|
autoStart: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.countDown.autoStart
|
||||||
|
},
|
||||||
|
// 是否展示毫秒倒计时
|
||||||
|
millisecond: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.countDown.millisecond
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
171
uni_modules/uview-plus/components/u-count-down/u-count-down.vue
Normal file
171
uni_modules/uview-plus/components/u-count-down/u-count-down.vue
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
<template>
|
||||||
|
<view class="u-count-down">
|
||||||
|
<slot>
|
||||||
|
<text class="u-count-down__text">{{ formattedTime }}</text>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import {
|
||||||
|
isSameSecond,
|
||||||
|
parseFormat,
|
||||||
|
parseTimeData
|
||||||
|
} from './utils';
|
||||||
|
/**
|
||||||
|
* u-count-down 倒计时
|
||||||
|
* @description 该组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。
|
||||||
|
* @tutorial https://uview-plus.jiangruyi.com/components/countDown.html
|
||||||
|
* @property {String | Number} time 倒计时时长,单位ms (默认 0 )
|
||||||
|
* @property {String} format 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒 (默认 'HH:mm:ss' )
|
||||||
|
* @property {Boolean} autoStart 是否自动开始倒计时 (默认 true )
|
||||||
|
* @property {Boolean} millisecond 是否展示毫秒倒计时 (默认 false )
|
||||||
|
* @event {Function} finish 倒计时结束时触发
|
||||||
|
* @event {Function} change 倒计时变化时触发
|
||||||
|
* @event {Function} start 开始倒计时
|
||||||
|
* @event {Function} pause 暂停倒计时
|
||||||
|
* @event {Function} reset 重设倒计时,若 auto-start 为 true,重设后会自动开始倒计时
|
||||||
|
* @example <u-count-down :time="time"></u-count-down>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-count-down',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
timer: null,
|
||||||
|
// 各单位(天,时,分等)剩余时间
|
||||||
|
timeData: parseTimeData(0),
|
||||||
|
// 格式化后的时间,如"03:23:21"
|
||||||
|
formattedTime: '0',
|
||||||
|
// 倒计时是否正在进行中
|
||||||
|
runing: false,
|
||||||
|
endTime: 0, // 结束的毫秒时间戳
|
||||||
|
remainTime: 0, // 剩余的毫秒时间
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
time(n) {
|
||||||
|
this.reset()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
emits: ["change", "finish"],
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.reset()
|
||||||
|
},
|
||||||
|
// 开始倒计时
|
||||||
|
start() {
|
||||||
|
if (this.runing) return
|
||||||
|
// 标识为进行中
|
||||||
|
this.runing = true
|
||||||
|
// 结束时间戳 = 此刻时间戳 + 剩余的时间
|
||||||
|
this.endTime = Date.now() + this.remainTime
|
||||||
|
this.toTick()
|
||||||
|
},
|
||||||
|
// 根据是否展示毫秒,执行不同操作函数
|
||||||
|
toTick() {
|
||||||
|
if (this.millisecond) {
|
||||||
|
this.microTick()
|
||||||
|
} else {
|
||||||
|
this.macroTick()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
macroTick() {
|
||||||
|
this.clearTimeout()
|
||||||
|
// 每隔一定时间,更新一遍定时器的值
|
||||||
|
// 同时此定时器的作用也能带来毫秒级的更新
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
// 获取剩余时间
|
||||||
|
const remain = this.getRemainTime()
|
||||||
|
// 重设剩余时间
|
||||||
|
if (!isSameSecond(remain, this.remainTime) || remain === 0) {
|
||||||
|
this.setRemainTime(remain)
|
||||||
|
}
|
||||||
|
// 如果剩余时间不为0,则继续检查更新倒计时
|
||||||
|
if (this.remainTime !== 0) {
|
||||||
|
this.macroTick()
|
||||||
|
}
|
||||||
|
}, 30)
|
||||||
|
},
|
||||||
|
microTick() {
|
||||||
|
this.clearTimeout()
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
this.setRemainTime(this.getRemainTime())
|
||||||
|
if (this.remainTime !== 0) {
|
||||||
|
this.microTick()
|
||||||
|
}
|
||||||
|
}, 50)
|
||||||
|
},
|
||||||
|
// 获取剩余的时间
|
||||||
|
getRemainTime() {
|
||||||
|
// 取最大值,防止出现小于0的剩余时间值
|
||||||
|
return Math.max(this.endTime - Date.now(), 0)
|
||||||
|
},
|
||||||
|
// 设置剩余的时间
|
||||||
|
setRemainTime(remain) {
|
||||||
|
this.remainTime = remain
|
||||||
|
// 根据剩余的毫秒时间,得出该有天,小时,分钟等的值,返回一个对象
|
||||||
|
const timeData = parseTimeData(remain)
|
||||||
|
this.$emit('change', timeData)
|
||||||
|
// 得出格式化后的时间
|
||||||
|
this.formattedTime = parseFormat(this.format, timeData)
|
||||||
|
// 如果时间已到,停止倒计时
|
||||||
|
if (remain <= 0) {
|
||||||
|
this.pause()
|
||||||
|
this.$emit('finish')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 重置倒计时
|
||||||
|
reset() {
|
||||||
|
this.pause()
|
||||||
|
this.remainTime = this.time
|
||||||
|
this.setRemainTime(this.remainTime)
|
||||||
|
if (this.autoStart) {
|
||||||
|
this.start()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 暂停倒计时
|
||||||
|
pause() {
|
||||||
|
this.runing = false;
|
||||||
|
this.clearTimeout()
|
||||||
|
},
|
||||||
|
// 清空定时器
|
||||||
|
clearTimeout() {
|
||||||
|
clearTimeout(this.timer)
|
||||||
|
this.timer = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #ifdef VUE2
|
||||||
|
beforeDestroy() {
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
beforeUnmount() {
|
||||||
|
// #endif
|
||||||
|
this.clearTimeout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style
|
||||||
|
lang="scss"
|
||||||
|
scoped
|
||||||
|
>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
$u-count-down-text-color:$u-content-color !default;
|
||||||
|
$u-count-down-text-font-size:15px !default;
|
||||||
|
$u-count-down-text-line-height:22px !default;
|
||||||
|
|
||||||
|
.u-count-down {
|
||||||
|
&__text {
|
||||||
|
color: $u-count-down-text-color;
|
||||||
|
font-size: $u-count-down-text-font-size;
|
||||||
|
line-height: $u-count-down-text-line-height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
62
uni_modules/uview-plus/components/u-count-down/utils.js
Normal file
62
uni_modules/uview-plus/components/u-count-down/utils.js
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// 补0,如1 -> 01
|
||||||
|
function padZero(num, targetLength = 2) {
|
||||||
|
let str = `${num}`
|
||||||
|
while (str.length < targetLength) {
|
||||||
|
str = `0${str}`
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
const SECOND = 1000
|
||||||
|
const MINUTE = 60 * SECOND
|
||||||
|
const HOUR = 60 * MINUTE
|
||||||
|
const DAY = 24 * HOUR
|
||||||
|
export function parseTimeData(time) {
|
||||||
|
const days = Math.floor(time / DAY)
|
||||||
|
const hours = Math.floor((time % DAY) / HOUR)
|
||||||
|
const minutes = Math.floor((time % HOUR) / MINUTE)
|
||||||
|
const seconds = Math.floor((time % MINUTE) / SECOND)
|
||||||
|
const milliseconds = Math.floor(time % SECOND)
|
||||||
|
return {
|
||||||
|
days,
|
||||||
|
hours,
|
||||||
|
minutes,
|
||||||
|
seconds,
|
||||||
|
milliseconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export function parseFormat(format, timeData) {
|
||||||
|
let {
|
||||||
|
days,
|
||||||
|
hours,
|
||||||
|
minutes,
|
||||||
|
seconds,
|
||||||
|
milliseconds
|
||||||
|
} = timeData
|
||||||
|
// 如果格式化字符串中不存在DD(天),则将天的时间转为小时中去
|
||||||
|
if (format.indexOf('DD') === -1) {
|
||||||
|
hours += days * 24
|
||||||
|
} else {
|
||||||
|
// 对天补0
|
||||||
|
format = format.replace('DD', padZero(days))
|
||||||
|
}
|
||||||
|
// 其他同理于DD的格式化处理方式
|
||||||
|
if (format.indexOf('HH') === -1) {
|
||||||
|
minutes += hours * 60
|
||||||
|
} else {
|
||||||
|
format = format.replace('HH', padZero(hours))
|
||||||
|
}
|
||||||
|
if (format.indexOf('mm') === -1) {
|
||||||
|
seconds += minutes * 60
|
||||||
|
} else {
|
||||||
|
format = format.replace('mm', padZero(minutes))
|
||||||
|
}
|
||||||
|
if (format.indexOf('ss') === -1) {
|
||||||
|
milliseconds += seconds * 1000
|
||||||
|
} else {
|
||||||
|
format = format.replace('ss', padZero(seconds))
|
||||||
|
}
|
||||||
|
return format.replace('SSS', padZero(milliseconds, 3))
|
||||||
|
}
|
||||||
|
export function isSameSecond(time1, time2) {
|
||||||
|
return Math.floor(time1 / 1000) === Math.floor(time2 / 1000)
|
||||||
|
}
|
60
uni_modules/uview-plus/components/u-count-to/props.js
Normal file
60
uni_modules/uview-plus/components/u-count-to/props.js
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 开始的数值,默认从0增长到某一个数
|
||||||
|
startVal: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.countTo.startVal
|
||||||
|
},
|
||||||
|
// 要滚动的目标数值,必须
|
||||||
|
endVal: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.countTo.endVal
|
||||||
|
},
|
||||||
|
// 滚动到目标数值的动画持续时间,单位为毫秒(ms)
|
||||||
|
duration: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.countTo.duration
|
||||||
|
},
|
||||||
|
// 设置数值后是否自动开始滚动
|
||||||
|
autoplay: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.countTo.autoplay
|
||||||
|
},
|
||||||
|
// 要显示的小数位数
|
||||||
|
decimals: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.countTo.decimals
|
||||||
|
},
|
||||||
|
// 是否在即将到达目标数值的时候,使用缓慢滚动的效果
|
||||||
|
useEasing: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.countTo.useEasing
|
||||||
|
},
|
||||||
|
// 十进制分割
|
||||||
|
decimal: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.countTo.decimal
|
||||||
|
},
|
||||||
|
// 字体颜色
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.countTo.color
|
||||||
|
},
|
||||||
|
// 字体大小
|
||||||
|
fontSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.countTo.fontSize
|
||||||
|
},
|
||||||
|
// 是否加粗字体
|
||||||
|
bold: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.countTo.bold
|
||||||
|
},
|
||||||
|
// 千位分隔符,类似金额的分割(¥23,321.05中的",")
|
||||||
|
separator: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.countTo.separator
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
189
uni_modules/uview-plus/components/u-count-to/u-count-to.vue
Normal file
189
uni_modules/uview-plus/components/u-count-to/u-count-to.vue
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
<template>
|
||||||
|
<text
|
||||||
|
class="u-count-num"
|
||||||
|
:style="{
|
||||||
|
fontSize: addUnit(fontSize),
|
||||||
|
fontWeight: bold ? 'bold' : 'normal',
|
||||||
|
color: color
|
||||||
|
}"
|
||||||
|
>{{ displayValue }}</text>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import { addUnit } from '../../libs/function/index';
|
||||||
|
/**
|
||||||
|
* countTo 数字滚动
|
||||||
|
* @description 该组件一般用于需要滚动数字到某一个值的场景,目标要求是一个递增的值。
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/countTo.html
|
||||||
|
* @property {String | Number} startVal 开始的数值,默认从0增长到某一个数(默认 0 )
|
||||||
|
* @property {String | Number} endVal 要滚动的目标数值,必须 (默认 0 )
|
||||||
|
* @property {String | Number} duration 滚动到目标数值的动画持续时间,单位为毫秒(ms) (默认 2000 )
|
||||||
|
* @property {Boolean} autoplay 设置数值后是否自动开始滚动 (默认 true )
|
||||||
|
* @property {String | Number} decimals 要显示的小数位数,见官网说明(默认 0 )
|
||||||
|
* @property {Boolean} useEasing 滚动结束时,是否缓动结尾,见官网说明(默认 true )
|
||||||
|
* @property {String} decimal 十进制分割 ( 默认 "." )
|
||||||
|
* @property {String} color 字体颜色( 默认 '#606266' )
|
||||||
|
* @property {String | Number} fontSize 字体大小,单位px( 默认 22 )
|
||||||
|
* @property {Boolean} bold 字体是否加粗(默认 false )
|
||||||
|
* @property {String} separator 千位分隔符,见官网说明
|
||||||
|
* @event {Function} end 数值滚动到目标值时触发
|
||||||
|
* @example <u-count-to ref="uCountTo" :end-val="endVal" :autoplay="autoplay"></u-count-to>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'u-count-to',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
localStartVal: this.startVal,
|
||||||
|
displayValue: this.formatNumber(this.startVal),
|
||||||
|
printVal: null,
|
||||||
|
paused: false, // 是否暂停
|
||||||
|
localDuration: Number(this.duration),
|
||||||
|
startTime: null, // 开始的时间
|
||||||
|
timestamp: null, // 时间戳
|
||||||
|
remaining: null, // 停留的时间
|
||||||
|
rAF: null,
|
||||||
|
lastTime: 0 // 上一次的时间
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mixins: [mpMixin, mixin,props],
|
||||||
|
computed: {
|
||||||
|
countDown() {
|
||||||
|
return this.startVal > this.endVal;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
startVal() {
|
||||||
|
this.autoplay && this.start();
|
||||||
|
},
|
||||||
|
endVal() {
|
||||||
|
this.autoplay && this.start();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.autoplay && this.start();
|
||||||
|
},
|
||||||
|
emits: ["end"],
|
||||||
|
methods: {
|
||||||
|
addUnit,
|
||||||
|
easingFn(t, b, c, d) {
|
||||||
|
return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;
|
||||||
|
},
|
||||||
|
requestAnimationFrame(callback) {
|
||||||
|
const currTime = new Date().getTime();
|
||||||
|
// 为了使setTimteout的尽可能的接近每秒60帧的效果
|
||||||
|
const timeToCall = Math.max(0, 16 - (currTime - this.lastTime));
|
||||||
|
const id = setTimeout(() => {
|
||||||
|
callback(currTime + timeToCall);
|
||||||
|
}, timeToCall);
|
||||||
|
this.lastTime = currTime + timeToCall;
|
||||||
|
return id;
|
||||||
|
},
|
||||||
|
cancelAnimationFrame(id) {
|
||||||
|
clearTimeout(id);
|
||||||
|
},
|
||||||
|
// 开始滚动数字
|
||||||
|
start() {
|
||||||
|
this.localStartVal = this.startVal;
|
||||||
|
this.startTime = null;
|
||||||
|
this.localDuration = this.duration;
|
||||||
|
this.paused = false;
|
||||||
|
this.rAF = this.requestAnimationFrame(this.count);
|
||||||
|
},
|
||||||
|
// 暂定状态,重新再开始滚动;或者滚动状态下,暂停
|
||||||
|
reStart() {
|
||||||
|
if (this.paused) {
|
||||||
|
this.resume();
|
||||||
|
this.paused = false;
|
||||||
|
} else {
|
||||||
|
this.stop();
|
||||||
|
this.paused = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 暂停
|
||||||
|
stop() {
|
||||||
|
this.cancelAnimationFrame(this.rAF);
|
||||||
|
},
|
||||||
|
// 重新开始(暂停的情况下)
|
||||||
|
resume() {
|
||||||
|
if (!this.remaining) return
|
||||||
|
this.startTime = 0;
|
||||||
|
this.localDuration = this.remaining;
|
||||||
|
this.localStartVal = this.printVal;
|
||||||
|
this.requestAnimationFrame(this.count);
|
||||||
|
},
|
||||||
|
// 重置
|
||||||
|
reset() {
|
||||||
|
this.startTime = null;
|
||||||
|
this.cancelAnimationFrame(this.rAF);
|
||||||
|
this.displayValue = this.formatNumber(this.startVal);
|
||||||
|
},
|
||||||
|
count(timestamp) {
|
||||||
|
if (!this.startTime) this.startTime = timestamp;
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
const progress = timestamp - this.startTime;
|
||||||
|
this.remaining = this.localDuration - progress;
|
||||||
|
if (this.useEasing) {
|
||||||
|
if (this.countDown) {
|
||||||
|
this.printVal = this.localStartVal - this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration);
|
||||||
|
} else {
|
||||||
|
this.printVal = this.easingFn(progress, this.localStartVal, this.endVal - this.localStartVal, this.localDuration);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.countDown) {
|
||||||
|
this.printVal = this.localStartVal - (this.localStartVal - this.endVal) * (progress / this.localDuration);
|
||||||
|
} else {
|
||||||
|
this.printVal = this.localStartVal + (this.endVal - this.localStartVal) * (progress / this.localDuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.countDown) {
|
||||||
|
this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal;
|
||||||
|
} else {
|
||||||
|
this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal;
|
||||||
|
}
|
||||||
|
this.displayValue = this.formatNumber(this.printVal) || 0;
|
||||||
|
if (progress < this.localDuration) {
|
||||||
|
this.rAF = this.requestAnimationFrame(this.count);
|
||||||
|
} else {
|
||||||
|
this.$emit('end');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 判断是否数字
|
||||||
|
isNumber(val) {
|
||||||
|
return !isNaN(parseFloat(val));
|
||||||
|
},
|
||||||
|
formatNumber(num) {
|
||||||
|
// 将num转为Number类型,因为其值可能为字符串数值,调用toFixed会报错
|
||||||
|
num = Number(num);
|
||||||
|
num = num.toFixed(Number(this.decimals));
|
||||||
|
num += '';
|
||||||
|
const x = num.split('.');
|
||||||
|
let x1 = x[0];
|
||||||
|
const x2 = x.length > 1 ? this.decimal + x[1] : '';
|
||||||
|
const rgx = /(\d+)(\d{3})/;
|
||||||
|
if (this.separator && !this.isNumber(this.separator)) {
|
||||||
|
while (rgx.test(x1)) {
|
||||||
|
x1 = x1.replace(rgx, '$1' + this.separator + '$2');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return x1 + x2;
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.cancelAnimationFrame(this.rAF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../../libs/css/components.scss";
|
||||||
|
|
||||||
|
.u-count-num {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: inline-flex;
|
||||||
|
/* #endif */
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
144
uni_modules/uview-plus/components/u-datetime-picker/props.js
Normal file
144
uni_modules/uview-plus/components/u-datetime-picker/props.js
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 是否显示input
|
||||||
|
hasInput: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => false
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: () => '请选择'
|
||||||
|
},
|
||||||
|
format: {
|
||||||
|
type: String,
|
||||||
|
default: () => ''
|
||||||
|
},
|
||||||
|
// 是否打开组件
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.datetimePicker.show
|
||||||
|
},
|
||||||
|
// 弹出的方向,可选值为 top bottom right left center
|
||||||
|
popupMode: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.picker.popupMode
|
||||||
|
},
|
||||||
|
// 是否展示顶部的操作栏
|
||||||
|
showToolbar: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.datetimePicker.showToolbar
|
||||||
|
},
|
||||||
|
// #ifdef VUE2
|
||||||
|
// 绑定值
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.datetimePicker.value
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
// 绑定值
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.datetimePicker.value
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// 顶部标题
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.datetimePicker.title
|
||||||
|
},
|
||||||
|
// 展示格式,mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.datetimePicker.mode
|
||||||
|
},
|
||||||
|
// 可选的最大时间
|
||||||
|
maxDate: {
|
||||||
|
type: Number,
|
||||||
|
// 最大默认值为后10年
|
||||||
|
default: () => defProps.datetimePicker.maxDate
|
||||||
|
},
|
||||||
|
// 可选的最小时间
|
||||||
|
minDate: {
|
||||||
|
type: Number,
|
||||||
|
// 最小默认值为前10年
|
||||||
|
default: () => defProps.datetimePicker.minDate
|
||||||
|
},
|
||||||
|
// 可选的最小小时,仅mode=time有效
|
||||||
|
minHour: {
|
||||||
|
type: Number,
|
||||||
|
default: () => defProps.datetimePicker.minHour
|
||||||
|
},
|
||||||
|
// 可选的最大小时,仅mode=time有效
|
||||||
|
maxHour: {
|
||||||
|
type: Number,
|
||||||
|
default: () => defProps.datetimePicker.maxHour
|
||||||
|
},
|
||||||
|
// 可选的最小分钟,仅mode=time有效
|
||||||
|
minMinute: {
|
||||||
|
type: Number,
|
||||||
|
default: () => defProps.datetimePicker.minMinute
|
||||||
|
},
|
||||||
|
// 可选的最大分钟,仅mode=time有效
|
||||||
|
maxMinute: {
|
||||||
|
type: Number,
|
||||||
|
default: () => defProps.datetimePicker.maxMinute
|
||||||
|
},
|
||||||
|
// 选项过滤函数
|
||||||
|
filter: {
|
||||||
|
type: [Function, null],
|
||||||
|
default: () => defProps.datetimePicker.filter
|
||||||
|
},
|
||||||
|
// 选项格式化函数
|
||||||
|
formatter: {
|
||||||
|
type: [Function, null],
|
||||||
|
default: () => defProps.datetimePicker.formatter
|
||||||
|
},
|
||||||
|
// 是否显示加载中状态
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.datetimePicker.loading
|
||||||
|
},
|
||||||
|
// 各列中,单个选项的高度
|
||||||
|
itemHeight: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.datetimePicker.itemHeight
|
||||||
|
},
|
||||||
|
// 取消按钮的文字
|
||||||
|
cancelText: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.datetimePicker.cancelText
|
||||||
|
},
|
||||||
|
// 确认按钮的文字
|
||||||
|
confirmText: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.datetimePicker.confirmText
|
||||||
|
},
|
||||||
|
// 取消按钮的颜色
|
||||||
|
cancelColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.datetimePicker.cancelColor
|
||||||
|
},
|
||||||
|
// 确认按钮的颜色
|
||||||
|
confirmColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.datetimePicker.confirmColor
|
||||||
|
},
|
||||||
|
// 每列中可见选项的数量
|
||||||
|
visibleItemCount: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.datetimePicker.visibleItemCount
|
||||||
|
},
|
||||||
|
// 是否允许点击遮罩关闭选择器
|
||||||
|
closeOnClickOverlay: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.datetimePicker.closeOnClickOverlay
|
||||||
|
},
|
||||||
|
// 各列的默认索引
|
||||||
|
defaultIndex: {
|
||||||
|
type: Array,
|
||||||
|
default: () => defProps.datetimePicker.defaultIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,455 @@
|
||||||
|
<template>
|
||||||
|
<view v-if="hasInput" class="u-datetime-picker">
|
||||||
|
<u-input
|
||||||
|
:placeholder="placeholder"
|
||||||
|
border="surround"
|
||||||
|
v-model="inputValue"
|
||||||
|
@click="showByClickInput = !showByClickInput"
|
||||||
|
></u-input>
|
||||||
|
</view>
|
||||||
|
<u-picker
|
||||||
|
ref="picker"
|
||||||
|
:show="show || (hasInput && showByClickInput)"
|
||||||
|
:popupMode="popupMode"
|
||||||
|
:closeOnClickOverlay="closeOnClickOverlay"
|
||||||
|
:columns="columns"
|
||||||
|
:title="title"
|
||||||
|
:itemHeight="itemHeight"
|
||||||
|
:showToolbar="showToolbar"
|
||||||
|
:visibleItemCount="visibleItemCount"
|
||||||
|
:defaultIndex="innerDefaultIndex"
|
||||||
|
:cancelText="cancelText"
|
||||||
|
:confirmText="confirmText"
|
||||||
|
:cancelColor="cancelColor"
|
||||||
|
:confirmColor="confirmColor"
|
||||||
|
@close="close"
|
||||||
|
@cancel="cancel"
|
||||||
|
@confirm="confirm"
|
||||||
|
@change="change"
|
||||||
|
>
|
||||||
|
</u-picker>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function times(n, iteratee) {
|
||||||
|
let index = -1
|
||||||
|
const result = Array(n < 0 ? 0 : n)
|
||||||
|
while (++index < n) {
|
||||||
|
result[index] = iteratee(index)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
import props from './props';
|
||||||
|
import mpMixin from '../../libs/mixin/mpMixin';
|
||||||
|
import mixin from '../../libs/mixin/mixin';
|
||||||
|
import dayjs from 'dayjs/esm/index';
|
||||||
|
import { range, error, padZero } from '../../libs/function/index';
|
||||||
|
import test from '../../libs/function/test';
|
||||||
|
/**
|
||||||
|
* DatetimePicker 时间日期选择器
|
||||||
|
* @description 此选择器用于时间日期
|
||||||
|
* @tutorial https://ijry.github.io/uview-plus/components/datetimePicker.html
|
||||||
|
* @property {Boolean} show 用于控制选择器的弹出与收起 ( 默认 false )
|
||||||
|
* @property {Boolean} showToolbar 是否显示顶部的操作栏 ( 默认 true )
|
||||||
|
* @property {String | Number} modelValue 绑定值
|
||||||
|
* @property {String} title 顶部标题
|
||||||
|
* @property {String} mode 展示格式 mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择 ( 默认 ‘datetime )
|
||||||
|
* @property {Number} maxDate 可选的最大时间 默认值为后10年
|
||||||
|
* @property {Number} minDate 可选的最小时间 默认值为前10年
|
||||||
|
* @property {Number} minHour 可选的最小小时,仅mode=time有效 ( 默认 0 )
|
||||||
|
* @property {Number} maxHour 可选的最大小时,仅mode=time有效 ( 默认 23 )
|
||||||
|
* @property {Number} minMinute 可选的最小分钟,仅mode=time有效 ( 默认 0 )
|
||||||
|
* @property {Number} maxMinute 可选的最大分钟,仅mode=time有效 ( 默认 59 )
|
||||||
|
* @property {Function} filter 选项过滤函数
|
||||||
|
* @property {Function} formatter 选项格式化函数
|
||||||
|
* @property {Boolean} loading 是否显示加载中状态 ( 默认 false )
|
||||||
|
* @property {String | Number} itemHeight 各列中,单个选项的高度 ( 默认 44 )
|
||||||
|
* @property {String} cancelText 取消按钮的文字 ( 默认 '取消' )
|
||||||
|
* @property {String} confirmText 确认按钮的文字 ( 默认 '确认' )
|
||||||
|
* @property {String} cancelColor 取消按钮的颜色 ( 默认 '#909193' )
|
||||||
|
* @property {String} confirmColor 确认按钮的颜色 ( 默认 '#3c9cff' )
|
||||||
|
* @property {String | Number} visibleItemCount 每列中可见选项的数量 ( 默认 5 )
|
||||||
|
* @property {Boolean} closeOnClickOverlay 是否允许点击遮罩关闭选择器 ( 默认 false )
|
||||||
|
* @property {Array} defaultIndex 各列的默认索引
|
||||||
|
* @event {Function} close 关闭选择器时触发
|
||||||
|
* @event {Function} confirm 点击确定按钮,返回当前选择的值
|
||||||
|
* @event {Function} change 当选择值变化时触发
|
||||||
|
* @event {Function} cancel 点击取消按钮
|
||||||
|
* @example <u-datetime-picker :show="show" :value="value1" mode="datetime" ></u-datetime-picker>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'datetime-picker',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 原来的日期选择器不方便,这里增加一个hasInput选项支持类似element的自带输入框的功能。
|
||||||
|
inputValue: '', // 表单显示值
|
||||||
|
showByClickInput: false, // 是否在hasInput模式下显示日期选择弹唱
|
||||||
|
columns: [],
|
||||||
|
innerDefaultIndex: [],
|
||||||
|
innerFormatter: (type, value) => value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
show(newValue, oldValue) {
|
||||||
|
if (newValue) {
|
||||||
|
this.updateColumnValue(this.innerValue)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue(newValue) {
|
||||||
|
this.init()
|
||||||
|
// this.getInputValue(newValue)
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE2
|
||||||
|
value(newValue) {
|
||||||
|
this.init()
|
||||||
|
// this.getInputValue(newValue)
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
propsChange() {
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 如果以下这些变量发生了变化,意味着需要重新初始化各列的值
|
||||||
|
propsChange() {
|
||||||
|
return [this.mode, this.maxDate, this.minDate, this.minHour, this.maxHour, this.minMinute, this.maxMinute, this.filter, ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
// #ifdef VUE3
|
||||||
|
emits: ['close', 'cancel', 'confirm', 'change', 'update:modelValue'],
|
||||||
|
// #endif
|
||||||
|
methods: {
|
||||||
|
getInputValue(newValue) {
|
||||||
|
if (newValue == '' || !newValue || newValue == undefined) {
|
||||||
|
this.inputValue = ''
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.mode == 'time') {
|
||||||
|
this.inputValue = newValue
|
||||||
|
} else {
|
||||||
|
if (this.format) {
|
||||||
|
this.inputValue = dayjs(newValue).format(this.format)
|
||||||
|
} else {
|
||||||
|
let format = ''
|
||||||
|
switch (this.mode) {
|
||||||
|
case 'date':
|
||||||
|
format = 'YYYY-MM-DD'
|
||||||
|
break;
|
||||||
|
case 'year-month':
|
||||||
|
format = 'YYYY-MM'
|
||||||
|
break;
|
||||||
|
case 'datetime':
|
||||||
|
format = 'YYYY-MM-DD HH:mm'
|
||||||
|
break;
|
||||||
|
case 'time':
|
||||||
|
format = 'HH:mm'
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.inputValue = dayjs(newValue).format(format)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
// #ifdef VUE3
|
||||||
|
this.innerValue = this.correctValue(this.modelValue)
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE2
|
||||||
|
this.innerValue = this.correctValue(this.value)
|
||||||
|
// #endif
|
||||||
|
this.updateColumnValue(this.innerValue)
|
||||||
|
|
||||||
|
// 初始化hasInput展示
|
||||||
|
this.getInputValue(this.innerValue)
|
||||||
|
},
|
||||||
|
// 在微信小程序中,不支持将函数当做props参数,故只能通过ref形式调用
|
||||||
|
setFormatter(e) {
|
||||||
|
this.innerFormatter = e
|
||||||
|
},
|
||||||
|
// 关闭选择器
|
||||||
|
close() {
|
||||||
|
if (this.closeOnClickOverlay) {
|
||||||
|
this.$emit('close')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 点击工具栏的取消按钮
|
||||||
|
cancel() {
|
||||||
|
if (this.hasInput) {
|
||||||
|
this.showByClickInput = false
|
||||||
|
}
|
||||||
|
this.$emit('cancel')
|
||||||
|
},
|
||||||
|
// 点击工具栏的确定按钮
|
||||||
|
confirm() {
|
||||||
|
// #ifdef VUE3
|
||||||
|
this.$emit('update:modelValue', this.innerValue)
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE2
|
||||||
|
this.$emit('input', this.innerValue)
|
||||||
|
// #endif
|
||||||
|
if (this.hasInput) {
|
||||||
|
this.getInputValue(this.innerValue)
|
||||||
|
this.showByClickInput = false
|
||||||
|
}
|
||||||
|
this.$emit('confirm', {
|
||||||
|
value: this.innerValue,
|
||||||
|
mode: this.mode
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//用正则截取输出值,当出现多组数字时,抛出错误
|
||||||
|
intercept(e,type){
|
||||||
|
let judge = e.match(/\d+/g)
|
||||||
|
//判断是否掺杂数字
|
||||||
|
if(judge.length>1){
|
||||||
|
error("请勿在过滤或格式化函数时添加数字")
|
||||||
|
return 0
|
||||||
|
}else if(type&&judge[0].length==4){//判断是否是年份
|
||||||
|
return judge[0]
|
||||||
|
}else if(judge[0].length>2){
|
||||||
|
error("请勿在过滤或格式化函数时添加数字")
|
||||||
|
return 0
|
||||||
|
}else{
|
||||||
|
return judge[0]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 列发生变化时触发
|
||||||
|
change(e) {
|
||||||
|
const { indexs, values } = e
|
||||||
|
let selectValue = ''
|
||||||
|
if(this.mode === 'time') {
|
||||||
|
// 根据value各列索引,从各列数组中,取出当前时间的选中值
|
||||||
|
selectValue = `${this.intercept(values[0][indexs[0]])}:${this.intercept(values[1][indexs[1]])}`
|
||||||
|
} else {
|
||||||
|
// 将选择的值转为数值,比如'03'转为数值的3,'2019'转为数值的2019
|
||||||
|
const year = parseInt(this.intercept(values[0][indexs[0]],'year'))
|
||||||
|
const month = parseInt(this.intercept(values[1][indexs[1]]))
|
||||||
|
let date = parseInt(values[2] ? this.intercept(values[2][indexs[2]]) : 1)
|
||||||
|
let hour = 0, minute = 0
|
||||||
|
// 此月份的最大天数
|
||||||
|
const maxDate = dayjs(`${year}-${month}`).daysInMonth()
|
||||||
|
// year-month模式下,date不会出现在列中,设置为1,为了符合后边需要减1的需求
|
||||||
|
if (this.mode === 'year-month') {
|
||||||
|
date = 1
|
||||||
|
}
|
||||||
|
// 不允许超过maxDate值
|
||||||
|
date = Math.min(maxDate, date)
|
||||||
|
if (this.mode === 'datetime') {
|
||||||
|
hour = parseInt(this.intercept(values[3][indexs[3]]))
|
||||||
|
minute = parseInt(this.intercept(values[4][indexs[4]]))
|
||||||
|
}
|
||||||
|
// 转为时间模式
|
||||||
|
selectValue = Number(new Date(year, month - 1, date, hour, minute))
|
||||||
|
}
|
||||||
|
// 取出准确的合法值,防止超越边界的情况
|
||||||
|
selectValue = this.correctValue(selectValue)
|
||||||
|
this.innerValue = selectValue
|
||||||
|
this.updateColumnValue(selectValue)
|
||||||
|
// 发出change时间,value为当前选中的时间戳
|
||||||
|
this.$emit('change', {
|
||||||
|
value: selectValue,
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
// 微信小程序不能传递this实例,会因为循环引用而报错
|
||||||
|
// picker: this.$refs.picker,
|
||||||
|
// #endif
|
||||||
|
mode: this.mode
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 更新各列的值,进行补0、格式化等操作
|
||||||
|
updateColumnValue(value) {
|
||||||
|
this.innerValue = value
|
||||||
|
this.updateColumns()
|
||||||
|
// 延迟执行,等待u-picker组件列数据更新完后再设置选中值索引
|
||||||
|
setTimeout(() => {
|
||||||
|
this.updateIndexs(value)
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
// 更新索引
|
||||||
|
updateIndexs(value) {
|
||||||
|
let values = []
|
||||||
|
const formatter = this.formatter || this.innerFormatter
|
||||||
|
if (this.mode === 'time') {
|
||||||
|
// 将time模式的时间用:分隔成数组
|
||||||
|
const timeArr = value.split(':')
|
||||||
|
// 使用formatter格式化方法进行管道处理
|
||||||
|
values = [formatter('hour', timeArr[0]), formatter('minute', timeArr[1])]
|
||||||
|
} else {
|
||||||
|
const date = new Date(value)
|
||||||
|
values = [
|
||||||
|
formatter('year', `${dayjs(value).year()}`),
|
||||||
|
// 月份补0
|
||||||
|
formatter('month', padZero(dayjs(value).month() + 1))
|
||||||
|
]
|
||||||
|
if (this.mode === 'date') {
|
||||||
|
// date模式,需要添加天列
|
||||||
|
values.push(formatter('day', padZero(dayjs(value).date())))
|
||||||
|
}
|
||||||
|
if (this.mode === 'datetime') {
|
||||||
|
// 数组的push方法,可以写入多个参数
|
||||||
|
values.push(formatter('day', padZero(dayjs(value).date())), formatter('hour', padZero(dayjs(value).hour())), formatter('minute', padZero(dayjs(value).minute())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据当前各列的所有值,从各列默认值中找到默认值在各列中的索引
|
||||||
|
const indexs = this.columns.map((column, index) => {
|
||||||
|
// 通过取大值,可以保证不会出现找不到索引的-1情况
|
||||||
|
return Math.max(0, column.findIndex(item => item === values[index]))
|
||||||
|
})
|
||||||
|
this.innerDefaultIndex = indexs
|
||||||
|
},
|
||||||
|
// 更新各列的值
|
||||||
|
updateColumns() {
|
||||||
|
const formatter = this.formatter || this.innerFormatter
|
||||||
|
// 获取各列的值,并且map后,对各列的具体值进行补0操作
|
||||||
|
const results = this.getOriginColumns().map((column) => column.values.map((value) => formatter(column.type, value)))
|
||||||
|
this.columns = results
|
||||||
|
},
|
||||||
|
getOriginColumns() {
|
||||||
|
// 生成各列的值
|
||||||
|
const results = this.getRanges().map(({ type, range }) => {
|
||||||
|
let values = times(range[1] - range[0] + 1, (index) => {
|
||||||
|
let value = range[0] + index
|
||||||
|
value = type === 'year' ? `${value}` : padZero(value)
|
||||||
|
return value
|
||||||
|
})
|
||||||
|
// 进行过滤
|
||||||
|
if (this.filter) {
|
||||||
|
values = this.filter(type, values)
|
||||||
|
if (!values || (values && values.length == 0)) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '日期filter结果不能为空',
|
||||||
|
icon: 'error',
|
||||||
|
mask: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { type, values }
|
||||||
|
})
|
||||||
|
return results
|
||||||
|
},
|
||||||
|
// 通过最大值和最小值生成数组
|
||||||
|
generateArray(start, end) {
|
||||||
|
return Array.from(new Array(end + 1).keys()).slice(start)
|
||||||
|
},
|
||||||
|
// 得出合法的时间
|
||||||
|
correctValue(value) {
|
||||||
|
const isDateMode = this.mode !== 'time'
|
||||||
|
if (isDateMode && !test.date(value)) {
|
||||||
|
// 如果是日期类型,但是又没有设置合法的当前时间的话,使用最小时间为当前时间
|
||||||
|
value = this.minDate
|
||||||
|
} else if (!isDateMode && !value) {
|
||||||
|
// 如果是时间类型,而又没有默认值的话,就用最小时间
|
||||||
|
value = `${padZero(this.minHour)}:${padZero(this.minMinute)}`
|
||||||
|
}
|
||||||
|
// 时间类型
|
||||||
|
if (!isDateMode) {
|
||||||
|
if (String(value).indexOf(':') === -1) return error('时间错误,请传递如12:24的格式')
|
||||||
|
let [hour, minute] = value.split(':')
|
||||||
|
// 对时间补零,同时控制在最小值和最大值之间
|
||||||
|
hour = padZero(range(this.minHour, this.maxHour, Number(hour)))
|
||||||
|
minute = padZero(range(this.minMinute, this.maxMinute, Number(minute)))
|
||||||
|
return `${ hour }:${ minute }`
|
||||||
|
} else {
|
||||||
|
// 如果是日期格式,控制在最小日期和最大日期之间
|
||||||
|
value = dayjs(value).isBefore(dayjs(this.minDate)) ? this.minDate : value
|
||||||
|
value = dayjs(value).isAfter(dayjs(this.maxDate)) ? this.maxDate : value
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取每列的最大和最小值
|
||||||
|
getRanges() {
|
||||||
|
if (this.mode === 'time') {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'hour',
|
||||||
|
range: [this.minHour, this.maxHour],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'minute',
|
||||||
|
range: [this.minMinute, this.maxMinute],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
const { maxYear, maxDate, maxMonth, maxHour, maxMinute, } = this.getBoundary('max', this.innerValue);
|
||||||
|
const { minYear, minDate, minMonth, minHour, minMinute, } = this.getBoundary('min', this.innerValue);
|
||||||
|
const result = [
|
||||||
|
{
|
||||||
|
type: 'year',
|
||||||
|
range: [minYear, maxYear],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'month',
|
||||||
|
range: [minMonth, maxMonth],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'day',
|
||||||
|
range: [minDate, maxDate],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'hour',
|
||||||
|
range: [minHour, maxHour],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'minute',
|
||||||
|
range: [minMinute, maxMinute],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
if (this.mode === 'date')
|
||||||
|
result.splice(3, 2);
|
||||||
|
if (this.mode === 'year-month')
|
||||||
|
result.splice(2, 3);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
// 根据minDate、maxDate、minHour、maxHour等边界值,判断各列的开始和结束边界值
|
||||||
|
getBoundary(type, innerValue) {
|
||||||
|
const value = new Date(innerValue)
|
||||||
|
const boundary = new Date(this[`${type}Date`])
|
||||||
|
const year = dayjs(boundary).year()
|
||||||
|
let month = 1
|
||||||
|
let date = 1
|
||||||
|
let hour = 0
|
||||||
|
let minute = 0
|
||||||
|
if (type === 'max') {
|
||||||
|
month = 12
|
||||||
|
// 月份的天数
|
||||||
|
date = dayjs(value).daysInMonth()
|
||||||
|
hour = 23
|
||||||
|
minute = 59
|
||||||
|
}
|
||||||
|
// 获取边界值,逻辑是:当年达到了边界值(最大或最小年),就检查月允许的最大和最小值,以此类推
|
||||||
|
if (dayjs(value).year() === year) {
|
||||||
|
month = dayjs(boundary).month() + 1
|
||||||
|
if (dayjs(value).month() + 1 === month) {
|
||||||
|
date = dayjs(boundary).date()
|
||||||
|
if (dayjs(value).date() === date) {
|
||||||
|
hour = dayjs(boundary).hour()
|
||||||
|
if (dayjs(value).hour() === hour) {
|
||||||
|
minute = dayjs(boundary).minute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
[`${type}Year`]: year,
|
||||||
|
[`${type}Month`]: month,
|
||||||
|
[`${type}Date`]: date,
|
||||||
|
[`${type}Hour`]: hour,
|
||||||
|
[`${type}Minute`]: minute
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '../../libs/css/components.scss';
|
||||||
|
.u-datetime-picker {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
45
uni_modules/uview-plus/components/u-divider/props.js
Normal file
45
uni_modules/uview-plus/components/u-divider/props.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import defProps from '../../libs/config/props.js';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 是否虚线
|
||||||
|
dashed: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.divider.dashed
|
||||||
|
},
|
||||||
|
// 是否细线
|
||||||
|
hairline: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.divider.hairline
|
||||||
|
},
|
||||||
|
// 是否以点替代文字,优先于text字段起作用
|
||||||
|
dot: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => defProps.divider.dot
|
||||||
|
},
|
||||||
|
// 内容文本的位置,left-左边,center-中间,right-右边
|
||||||
|
textPosition: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.divider.textPosition
|
||||||
|
},
|
||||||
|
// 文本内容
|
||||||
|
text: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.divider.text
|
||||||
|
},
|
||||||
|
// 文本大小
|
||||||
|
textSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: () => defProps.divider.textSize
|
||||||
|
},
|
||||||
|
// 文本颜色
|
||||||
|
textColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.divider.textColor
|
||||||
|
},
|
||||||
|
// 线条颜色
|
||||||
|
lineColor: {
|
||||||
|
type: String,
|
||||||
|
default: () => defProps.divider.lineColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user