Преглед на файлове

上传文件至 'components'

linwenxin преди 4 месеца
родител
ревизия
2bfb70835f
променени са 5 файла, в които са добавени 504 реда и са изтрити 0 реда
  1. 99 0
      components/custom.vue
  2. 172 0
      components/drag-button.vue
  3. 122 0
      components/floatButton.vue
  4. 42 0
      components/loadingText.vue
  5. 69 0
      components/modalDialog.vue

+ 99 - 0
components/custom.vue

@@ -0,0 +1,99 @@
+<template>
+	<view class="navigation" :style="{height:CustomBar+'px'}" >
+		<view class="me-container" :class="bgColor" :style="cuStyle" >
+			<view class="me-left flex_ac">
+				<!-- <view v-if="isBack" @tap="toBack" class="iconfont icon-back"></view> -->
+				<image v-if="isBack" @tap="toBack" src="@/static/icon/back.png"></image>
+				<slot name="left"></slot>
+			</view>
+			<view class="me-content">
+				<slot name="content"></slot>
+			</view>
+			<view class="me-right">
+				<slot name="right"></slot>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:{
+			isBack:{
+				type:Boolean,
+				default:true
+			},
+			bgColor:{
+				type:String,
+				default:'bg-white'
+			}
+		},
+		computed:{
+			cuStyle(){
+				return `height:${this.CustomBar-this.StatusBar}px;padding-top:${this.StatusBar}px;`
+			}
+		},
+		data() {
+			return {
+				StatusBar:this.StatusBar,
+				CustomBar:this.CustomBar
+			};
+		},
+		methods:{
+			toBack(){
+				uni.navigateBack({
+					delta:1
+				})
+			}
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+	cover-view{
+		box-sizing: border-box;
+	}
+.navigation{
+	position: relative;
+	.bg-none {
+		background: none;
+	}
+	.bg-white{
+		background: #FFFFFF;
+	}
+	.bg-tran{
+		background: transparent;
+	}
+	.bg-them{
+		background: #fb5152;
+	}
+	.bg-linear {
+		background: linear-gradient(-90deg,#6da7ff 0%, #7fdaff 100%);;
+	}
+	.me-container{
+		position: fixed;
+		width: 100%;
+		top: 0;
+		z-index: 1024;
+		// box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.1);
+		// padding: 0 30rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		.me-content{
+			position: absolute;
+			left: 50%;
+			transform: translateX(-50%);
+		}
+		.me-left{
+			image {
+				width: 32rpx;
+				height: 32rpx;
+				display: block;
+				margin-left: 30rpx;
+			}
+		}
+		
+	}
+}
+</style>

+ 172 - 0
components/drag-button.vue

@@ -0,0 +1,172 @@
+<template>
+	<view>
+		<view id="_drag_button" class="drag" :style="{top:top+'px',left:left+'px',opacity:firstIn?1:0}"
+			@touchstart="touchstart" @touchmove.stop.prevent="touchmove" @touchend="touchend"
+			@click.stop.prevent="click" :class="{transition: isDock && !isMove }">
+			<button class="btn" style="border: none;padding: 0;margin: 0;">
+				<image class="img" src="@/static/icon/cart.png" mode="widthFix"></image>
+				<text>购物车</text>
+			</button>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'drag-button',
+		props: {
+			isDock: {
+				type: Boolean,
+				default: false
+			},
+			customBar: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				top: 0,
+				left: 0,
+				width: 0,
+				height: 0,
+				offsetWidth: 0,
+				offsetHeight: 0,
+				windowWidth: 0,
+				windowHeight: 0,
+				isMove: true,
+				edge: 10,
+				firstIn: false,
+				customBarHeight: this.CustomBar
+			}
+		},
+		methods: {
+			init() {
+				// 获取手机信息配置接口
+				const sys = uni.getSystemInfoSync();
+				// 屏幕的宽高
+				this.windowWidth = sys.windowWidth;
+				this.windowHeight = sys.windowHeight;
+				if (sys.windowTop) {
+					this.windowHeight += sys.windowTop;
+				}
+				// 获取元素
+				const query = uni.createSelectorQuery().in(this);
+				query.select('#_drag_button').boundingClientRect(data => {
+					this.width = data.width;
+					this.height = data.height;
+					this.offsetWidth = data.width / 2;
+					this.offsetHeight = data.height / 2;
+					// this.left = this.windowWidth - this.width - this.edge;
+					// this.top = this.windowHeight - this.height - this.edge;
+					
+					// 若storage无值,设置初始值
+					if(!uni.getStorageSync('top')) {
+						uni.setStorageSync("top", this.windowHeight - this.height - this.edge - 100 - (this.customBar ? this.customBarHeight : 0));
+					}
+					if(!uni.getStorageSync('left')) {
+						uni.setStorageSync("left", this.windowWidth - this.width - this.edge);
+					}
+					
+					this.left = uni.getStorageSync('left');
+					this.top = uni.getStorageSync('top') - (this.customBar ? this.customBarHeight : 0);
+					this.$nextTick(() => {
+						this.firstIn = true;
+					})
+				}).exec();
+			},
+			click() {
+				uni.switchTab({
+					url:'/pages/cart/index'
+				})
+			},
+			touchstart(e) {
+				
+			},
+			touchmove(e) {
+				// 单指触摸
+				if (e.touches.length !== 1) {
+					return false;
+				}
+				this.isMove = true;
+
+				this.left = e.touches[0].clientX - this.offsetWidth;
+
+				let clientY = e.touches[0].clientY - this.offsetHeight;
+				
+				let edgeBottom = this.windowHeight - this.height - this.edge;
+
+				// 上下触及边界
+				if (clientY < this.edge) {
+					this.top = this.edge;
+				} else if (clientY > edgeBottom) {
+					this.top = edgeBottom;
+				} else {
+					this.top = clientY
+				}
+				uni.setStorageSync("top", this.top + (this.customBar ? this.customBarHeight : 0));
+			},
+			touchend(e) {
+				if (this.isDock) {
+					let edgeRigth = this.windowWidth - this.width - this.edge;
+
+					if (this.left < this.windowWidth / 2 - this.offsetWidth) {
+						this.left = this.edge;
+					} else {
+						this.left = edgeRigth;
+					}
+				}
+				uni.setStorageSync("left", this.left);
+				this.isMove = false;
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.drag {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		width: 100rpx;
+		height: 100rpx;
+		border-radius: 50%;
+		font-size: $uni-font-size-sm;
+		position: fixed;
+		z-index: 999999;
+		background: #FFA162;
+		border: 4rpx solid #FE781F;
+
+		&.transition {
+			transition: left .3s ease, top .3s ease;
+		}
+	}
+
+	.btn {
+		background-color: transparent;
+		width: 100rpx;
+		height: 100rpx;
+		border-radius: 50%;
+		z-index: 9999;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+		.img {
+			width: 36rpx;
+			display: block;
+		}
+		text {
+			font-size: 22rpx;
+			line-height: 24rpx;
+			color: #FFFFFF;
+			margin-top: 8rpx;
+		}
+	}
+
+	button::after {
+		border: none;
+	}
+
+</style>
+

+ 122 - 0
components/floatButton.vue

@@ -0,0 +1,122 @@
+<template>
+  <view class="btn-group">
+    <view class="btn" @tap="toShare()" v-if="isShare">
+      <text class="iconfont icon-fenxiang"></text>
+      <text class="text">分享</text>
+    </view>
+    <view class="btn" @tap="toCart()" v-if="isCart">
+      <text class="iconfont icon-gouwuche"></text>
+      <text class="text">购物车</text>
+    </view>
+    <button class="btn" open-type="contact" v-if="isService">
+      <text class="iconfont icon-kefu"></text>
+      <text class="text">在线客服</text>
+    </button>
+  </view>
+</template>
+
+<script>
+export default {
+  props: {
+    isDock: {
+      type: Boolean,
+      default: false,
+    },
+    customBar: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    curRoute() {
+      let routes = getCurrentPages();
+      return routes[routes.length - 1].route;
+    },
+
+    isCart() {
+      return ![
+        'pages/login/index',
+        'pages/cart/index',
+        'pages/mine/index',
+        'packageGoods/pages/detail',
+        'packageGoods/pages/order',
+        'pages/mine/order/detail',
+        'packageGoods/pages/coupon',
+        'pages/mine/coupon/list',
+      ].includes(this.curRoute);
+    },
+
+    isService() {
+      return ![
+        'pages/login/index',
+        'pages/cart/index',
+        'pages/mine/index',
+        'packageGoods/pages/order',
+        'pages/mine/order/detail',
+        'packageGoods/pages/coupon',
+        'pages/mine/coupon/list',
+      ].includes(this.curRoute);
+    },
+
+    isShare() {
+      return [
+        'pages/mine/groupbuy/list',
+        // 'packageGoods/pages/activity',
+      ].includes(this.curRoute);
+    },
+  },
+  mounted() {},
+  methods: {
+    toCart() {
+      uni.switchTab({
+        url: '/pages/cart/index',
+      });
+    },
+
+    toShare() {
+      uni.$emit('hanbleShare');
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.btn-group {
+  position: fixed;
+  bottom: 20vh;
+  right: 20rpx;
+  z-index: 999998;
+  .btn {
+    width: 92rpx;
+    height: 92rpx;
+    background: #ffffff;
+    box-shadow: 0 2rpx 8rpx 2rpx rgba(0, 0, 0, 0.3);
+    transition: all 0.5s;
+    text-align: center;
+    border-radius: 50%;
+    color: #333333;
+    margin-top: 15rpx;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding: 0;
+    padding-bottom: 8rpx;
+    line-height: 1;
+    box-sizing: border-box;
+    &::after {
+      border: none;
+    }
+    .iconfont {
+      font-size: 44rpx;
+    }
+    .text {
+      font-size: 18rpx;
+      margin-top: 6rpx;
+    }
+  }
+}
+</style>

+ 42 - 0
components/loadingText.vue

@@ -0,0 +1,42 @@
+<template>
+	<view class="container">
+		<text v-if="!loading && !noMore">上滑加载更多</text>
+		<view v-if="loading && !noMore">
+			<text class="iconfont icon-refrsh roate"></text>
+			<text>加载中...</text>
+		</view>
+		<text v-if="noMore">没有更多数据了</text>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:{
+			loading:{
+				type: Boolean,
+				default: false
+			},
+			noMore:{
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+.container{
+	width: 100%;
+	height: 100rpx;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	color: #666666;
+	font-size: 28rpx;
+}
+</style>

+ 69 - 0
components/modalDialog.vue

@@ -0,0 +1,69 @@
+<template>
+	<view>
+		<view class="global-mask" v-show="isShowDialog"></view>
+		<view class="global-dialog" v-show="isShowDialog">
+			<view class="title">{{showTitle}}</view>
+			<view class="content">
+				<view class="text">{{showText}}</view>
+			</view>
+			<view class="btn">
+				<view class="left" @tap="cancel" v-if="isShowCancel">{{cancelText}}</view>
+				<view class="right" @tap="confirm" v-if="isShowConfirm">{{confirmText}}</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'modalDialog',
+		props: {
+			showTitle: {
+				type: String,
+				default: '温馨提示'
+			},
+			showText: {
+				type: String,
+				default: '提示内容'
+			},
+			isShowDialog: {
+				type: Boolean,
+				default: false
+			},
+			isShowCancel: {
+				type: Boolean,
+				default: true
+			},
+			cancelText: {
+				type: String,
+				default: '取消'
+			},
+			isShowConfirm: {
+				type: Boolean,
+				default: true
+			},
+			confirmText: {
+				type: String,
+				default: '确定'
+			}
+		},
+		data() {
+			return {
+				
+			};
+		},
+		methods: {
+			cancel() {
+				this.$emit('cancel');
+			},
+			
+			confirm() {
+				this.$emit('confirm');
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+
+</style>