DaMowang 2 gadi atpakaļ
vecāks
revīzija
c469a0171d

+ 135 - 0
src/components/jarvis-picker/README.md

@@ -0,0 +1,135 @@
+### 使用组件
+
+<m-picker mode="bottom" :show.sync="show" :range="list" @confirm="confirm"></m-picker>
+
+### 引入组件
+
+import mPicker from '@/components/m-picker/m-picker.vue';
+
+### 注册组件
+
+export default {
+    components: { mPicker },
+    data() {
+        return {
+            show: true,
+            list: [
+                [
+                    {
+                        label: '男',
+                        value: 0
+                    },
+                    {
+                        label: '女',
+                        value: 1
+                    },
+                    {
+                        label: '未知',
+                        value: 2
+                    }
+                ]
+            ]
+        }
+    },
+    methods: {
+        confirm(e) {
+            console.log(e);
+        }
+    }
+}
+
+### 参数
+
+是否显示遮罩
+mark: {
+    type: Boolean,
+    default() {
+        return true
+    }
+},
+点击遮罩是否关闭
+markClose: {
+    type: Boolean,
+    default() {
+        return true
+    }
+},
+点击按钮是否关闭
+btnClose: {
+    type: Boolean,
+    default() {
+        return true
+    }
+},
+是否显示弹窗
+show: {
+    type: Boolean,
+    default() {
+        return false
+    }
+},
+数据
+range: {
+    type: Array,
+    default: []
+},
+picker-item显示内容的key
+rangeKey: {
+    type: String,
+    default: 'label'
+},
+设置选择器中间选中框的样式
+indicatorStyle: {
+    type: String,
+    default: 'height: 50px;'
+},
+设置选择器中间选中框的类名,注意页面或组件的style中写了scoped时,需要在类名前写/deep/
+indicatorClass: {
+    type: String,
+    default: ''
+},
+cancel文字
+cancelText: {
+    type: String,
+    default: '取消'
+},
+confirm文字
+confirmText: {
+    type: String,
+    default: '确定'
+},
+cancel样式style
+cancelStyle: {
+    type: Object,
+    default: {}
+},
+confirm样式style
+confirmStyle: {
+    type: Object,
+    default: {}
+},
+内容高度 rpx
+height: {
+    type: Number,
+    default: 500
+},
+圆角 rpx
+borderRadius: {
+    type: Number,
+    default: 16
+},
+背景颜色
+bgColor: {
+    type: String,
+    default: '#FFFFFF'
+},
+mark 背景颜色
+markBgColor: {
+    type: String,
+    default: '#00000080'
+},
+方向 top/bottom/center
+mode: {
+    type: String,
+    default: 'bottom'
+}

+ 219 - 0
src/components/jarvis-picker/m-picker.vue

@@ -0,0 +1,219 @@
+<template>
+	<view class="pricke">
+		<uni-transition v-if="mark" ref="aniMark" custom-class="transition" mode-class="fade" :styles="stylesMark" :show="show" @click="clickMark"></uni-transition>
+		<uni-transition ref="ani" custom-class="transition" :mode-class="modeClass" :styles="styles" :show="show">
+			<view class="m-picker">
+				<view class="m-picker__case" :style="{
+					background: bgColor,
+					borderTopLeftRadius: radius[0] + 'rpx',
+					borderTopRightRadius: radius[1] + 'rpx',
+					borderBottomLeftRadius: radius[2] + 'rpx',
+					borderBottomRightRadius: radius[3] + 'rpx',
+					paddingBottom: model == 'bottom' ? 'calc(constant(safe-area-inset-bottom) + 30rpx)' : '30rpx',
+					paddingBottom: model == 'bottom' ? 'calc(env(safe-area-inset-bottom) + 30rpx)' : '30rpx'
+				}">
+					<slot v-if="model == 'bottom'" name="handle">
+						<view class="handle">
+							<view class="button cancel" @click="cancel">{{cancelText}}</view>
+							<view class="button confirm" @click="confirm">{{confirmText}}</view>
+						</view>
+					</slot>
+					<slot>
+						<view class="content" :style="{height: `${height}rpx`}">
+							<picker-view class="picker-view" :indicator-class="indicatorClass" :indicator-style="indicatorStyle" :value="pickerValue" @change="bindChange" @pickstart="pickstart" @pickend="pickend">
+								<picker-view-column v-for="(rangeItem, rangeIndex) in range" :key="rangeIndex">
+									<view class="picker-view__item" v-for="(item, index) in rangeItem" :key="index">
+										{{ item[rangeKey] }}
+									</view>
+								</picker-view-column>
+							</picker-view>
+						</view>
+					</slot>
+					<slot v-if="model != 'bottom'" name="handle">
+						<view class="handle">
+							<view class="button cancel" @click="cancel">{{cancelText}}</view>
+							<view class="button confirm" @click="confirm">{{confirmText}}</view>
+						</view>
+					</slot>
+				</view>
+			</view>
+		</uni-transition>
+	</view>
+</template>
+
+<script>
+	import props from './props.js'
+	export default {
+		name:"jarvis-picker",
+		props,
+		data() {
+			return {
+				pickerValue: [],
+				pickMove: false,
+			};
+		},
+		computed: {
+			model() {
+				if (this.mode == 'top') return 'top';
+				else if (this.mode == 'bottom') return 'bottom';
+				else if (this.mode == 'center') return 'center';
+				else return 'bottom';
+			},
+			stylesMark() {
+				return {
+					position: 'fixed',
+					top: 0,
+					left: 0,
+					right: 0,
+					bottom: 0,
+					zIndex: 99,
+					backgroundColor: this.markBgColor,
+				}
+			},
+			styles() {
+				const top = {
+					position: 'fixed',
+					left: 0,
+					right: 0,
+					top: 0,
+					zIndex: 100
+				}
+				const bottom = {
+					position: 'fixed',
+					left: 0,
+					right: 0,
+					bottom: 0,
+					zIndex: 100
+				}
+				const center = {
+					position: 'fixed',
+					left: '50%',
+					top: '50%',
+					width: '90vw',
+					transform: 'translate(-50%, -50%)',
+					zIndex: 100
+				}
+				if (this.model == 'top') return top;
+				else if (this.model == 'bottom') return bottom;
+				else if (this.model == 'center') return center;
+				else return bottom;
+			},
+			radius() {
+				const borderRadius = this.borderRadius;
+				if (this.model == 'top') return [0, 0, borderRadius, borderRadius];
+				else if (this.model == 'bottom') return [borderRadius, borderRadius, 0, 0];
+				else if (this.model == 'center') return [borderRadius, borderRadius, borderRadius, borderRadius];
+				else return [0, 0, 0, 0];
+			},
+			modeClass() {
+				if (this.model == 'top') return ['fade', 'slide-top'];
+				else if (this.model == 'bottom') return ['fade', 'slide-bottom'];
+				else if (this.model == 'center') return 'fade';
+				else return ['fade', 'slide-bottom'];
+			}
+		},
+		watch: {
+			range(val) {
+				if (val.length) {
+					let arr = []
+					for (let index in this.range) {
+						arr.push(0);
+					}
+					this.pickerValue = arr;
+				}
+			}
+		},
+		created() {
+			if (this.range && this.range.length) {
+				this.pickerValue = [];
+				for (let index in this.range) {
+					this.pickerValue.push(0)
+				}
+			}
+		},
+		methods: {
+			// 关闭
+			close() {
+				if (!this.pickMove) this.$emit('update:show', false)
+			},
+			// 取消
+			cancel() {
+				this.$emit('cancel')
+				if (this.btnClose) this.close()
+			},
+			// 确定
+			confirm() {
+				this.$emit('confirm', this.pickerValue);
+				if (this.btnClose) this.close()
+			},
+			// 点击遮罩
+			clickMark() {
+				if (this.markClose) this.close()
+			},
+			bindChange (e) {
+				const val = e.detail.value;
+				this.pickerValue = val;
+			},
+			pickstart() {
+				this.pickMove = true;
+			},
+			pickend() {
+				this.pickMove = false;
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+.m-picker {
+	width: 100%;
+	height: 100%;
+	
+	&__case {
+		padding-left: 56rpx;
+		padding-right: 56rpx;
+		padding-top: 30rpx;
+		padding-bottom: 30rpx;
+		
+		.handle {
+			width: 100%;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			
+			.button {
+				font-size: 36rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333;
+				
+				&.cancel {
+					
+				}
+				
+				&.confirm {
+					color: #17bb87;
+				}
+			}
+		}
+		
+		.content {
+			width: 100%;
+			height: 400rpx;
+		}
+		
+	}
+}
+
+.picker-view {
+	width: 100%;
+	height: 100%;
+	
+	&__item {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		font-size: 40rpx;
+	}
+}
+</style>

+ 97 - 0
src/components/jarvis-picker/props.js

@@ -0,0 +1,97 @@
+const props = {
+	// 是否显示遮罩
+	mark: {
+		type: Boolean,
+		default() {
+			return true
+		}
+	},
+	// 点击遮罩是否关闭
+	markClose: {
+		type: Boolean,
+		default() {
+			return true
+		}
+	},
+	// 点击按钮是否关闭
+	btnClose: {
+		type: Boolean,
+		default() {
+			return true
+		}
+	},
+	// 是否显示弹窗
+	show: {
+		type: Boolean,
+		default() {
+			return false
+		}
+	},
+	// 数据
+	range: {
+		type: Array,
+		default: []
+	},
+	// picker-item显示内容的key
+	rangeKey: {
+		type: String,
+		default: 'label'
+	},
+	// 设置选择器中间选中框的样式
+	indicatorStyle: {
+		type: String,
+		default: 'height: 50px;'
+	},
+	// 设置选择器中间选中框的类名,注意页面或组件的style中写了scoped时,需要在类名前写/deep/
+	indicatorClass: {
+		type: String,
+		default: ''
+	},
+	// cancel文字
+	cancelText: {
+		type: String,
+		default: '取消'
+	},
+	// confirm文字
+	confirmText: {
+		type: String,
+		default: '确定'
+	},
+	// cancel样式style
+	// cancelStyle: {
+	// 	type: Object,
+	// 	default: {}
+	// },
+	// confirm样式style
+	// confirmStyle: {
+	// 	type: Object,
+	// 	default: {}
+	// },
+	// 内容高度 rpx
+	height: {
+		type: Number,
+		default: 500
+	},
+	// 圆角 rpx
+	borderRadius: {
+		type: Number,
+		default: 16
+	},
+	// 背景颜色
+	bgColor: {
+		type: String,
+		default: '#FFFFFF'
+	},
+	// mark 背景颜色
+	markBgColor: {
+		type: String,
+		default: '#00000080'
+	},
+	// 方向 top/bottom/center
+	mode: {
+		type: String,
+		default: 'bottom'
+	}
+}
+
+export default props

+ 26 - 15
src/pages/account/giveAsPresent.vue

@@ -1,14 +1,16 @@
 <template>
   <view class="container">
-    <view class="list flex_r flex_ac flex_jb mar_t16">
+    <view class="list flex_r flex_ac flex_jb mar_t16" @click="OnpickerShow">
       <view class="list_name">赠送类型:</view>
-      <view class="list_text flex_r flex_ac">
-        <uni-data-select
+      <view class="list_text">
+        <!-- <uni-data-select
           v-model="value"
           :localdata="range"
           :clear="false"
           class="type_select"
-        />
+        /> -->
+        <span>{{range[0][value].label}}</span>
+        <span class="iconfont">&#xe62e;</span>
       </view>
     </view>
     <view class="list flex_r flex_ac flex_jb mar_t16" v-if="value == 0">
@@ -51,6 +53,8 @@
     </view>
     <view class="tips">{{ list[value].tips }}</view>
     <view class="btn flex_r flex_ac flex_jc" @tap="give">立即赠送</view>
+
+    <m-picker mode="bottom" :show.sync="pickerShow" :range="range" @confirm="confirm" />
   </view>
 </template>
 <script>
@@ -58,6 +62,7 @@ let page = 1;
 let app = getApp();
 var appEv = app.$vm.$options;
 import { get, post } from "@/request/api.js";
+import mPicker from '@/components/jarvis-picker/m-picker.vue';
 export default {
   data() {
     return {
@@ -65,14 +70,18 @@ export default {
       give_num: "",
       userinfo: undefined, // 获取用户信息
 
+      pickerShow: false,
       value: 0,
       range: [
-        { value: 0, text: "余额" },
-        { value: 1, text: "茶宝" },
+        [
+          { value: 0, label: "余额" },
+          { value: 1, label: "茶宝" },
+        ]
       ],
       list: [],
     };
   },
+  components: { mPicker },
   onLoad() {
     this.userinfo = uni.getStorageSync("userinfo");
     this.getGiveList();
@@ -178,6 +187,13 @@ export default {
         }
       });
     },
+
+    OnpickerShow(){
+      this.pickerShow = !this.pickerShow;
+    },
+    confirm(da){
+      this.value = da[0]
+    }
   },
 };
 </script>
@@ -201,6 +217,10 @@ page {
   flex: 1;
   font-family: "SourceHanSansCN-Bold";
   text-align: right;
+  .iconfont{
+    font-size: 28rpx;
+    margin-left: 12rpx;
+  }
 }
 
 .list_name {
@@ -244,13 +264,4 @@ page {
   margin: 20rpx auto 0;
   border-radius: 10rpx;
 }
-.type_select {
-  text-align: right;
-}
-::v-deep .uni-select {
-  border: 0;
-}
-::v-deep .uni-select__input-text {
-  padding-right: 16rpx;
-}
 </style>