微信小程序等瀑布流实现

覃擎宇2024-09-190

什么是瀑布流?

瀑布流布局有一个专业的英文名称Masonry Layouts。瀑布流布局已经有好多年的历史了,我最早知道这个名词的时候大约是在2012年,当时Pinterest网站的布局就是使用的这种流式布局,简言之像Pinterest网站这样的布局就称之为瀑布流布局,也有人称之为Pinterest 布局。瀑布流又称瀑布流式布局,是比较流行的一种网站页面布局方式。即多行等宽元素排列,后面的元素依次添加到其后,等宽不等高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置。瀑布流布局的核心是基于一个网格的布局,而且每行包含的项目列表高度是随机的(随着自己内容动态变化高度),同时每个项目列表呈堆栈形式排列,最为关键的是,堆栈之间彼此之间没有多余的间距差存大。还是上张图来看看我们说的瀑布流布局是什么样子。

image.png

实现瀑布流的方法

一、使用column-count和column-gap来实现瀑布流布局(适合简单的瀑布流排版)

body {
  margin: 4px;
  font-family: Arial, Helvetica, sans-serif;
}

.masonry {
  column-count: 4;
  column-gap: 0;
}

.item {
  padding: 2px;
  position: relative;
  counter-increment: count;
}

.item img {
  display: block;
  width: 100%;
  height: auto;
}

.item::after {
  position: absolute;
  display: block;
  top: 2px;
  left: 2px;
  width: 24px;
  height: 24px;
  text-align: center;
  line-height: 24px;
  background-color: #000;
  color: #fff;
  content: counter(count);
}
<body>
    <div class="masonry">
        <div class="item">
            <img src="https://picsum.photos/360/460?radom=1" alt="">
        </div>
        <div class="item">
            <img src="https://picsum.photos/360/520?radom=2" alt="">
        </div>
        <div class="item">
            <img src="https://picsum.photos/360/420?radom=3" alt="">
        </div>
        <div class="item">
            <img src="https://picsum.photos/360/500?radom=4" alt="">
        </div>
        <div class="item">
            <img src="https://picsum.photos/360/420?radom=5" alt="">
        </div>
        <div class="item">
            <img src="https://picsum.photos/360/460?radom=6" alt="">
        </div>
        <div class="item">
            <img src="https://picsum.photos/360/480?radom=7" alt="">
        </div>
        <div class="item">
            <img src="https://picsum.photos/360/460?radom=8" alt="">
        </div>
        <div class="item">
            <img src="https://picsum.photos/360/420?radom=9" alt="">
        </div>
        <div class="item">
            <img src="https://picsum.photos/360/500?radom=10" alt="">
        </div>
        <div class="item">
            <img src="https://picsum.photos/360/460?radom=11" alt="">
        </div>
        <div class="item">
            <img src="https://picsum.photos/360/360?radom=12" alt="">
        </div>
    </div>
</body>

效果图片

:::danger
图片顺序是从上到下排列。如果你的网页是要按照时间倒序来展示照片,那么,我们就需要照片先从左至右排列,在换行,所以目前这种方式虽然简单,但是很多场景中不适合使用。
:::

二、flexBox方式实现瀑布流布局(不推荐)

body {
  margin: 4px;
  font-family: Arial, Helvetica, sans-serif;
}

.masonry {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  height: 1000px;


}

.item {
  position: relative;
  width: 25%;
  padding: 2px;
  counter-increment: count;
}

.item img {
  display: block;
  width: 100%;
  height: auto;
}

.item::after {
  position: absolute;
  display: block;
  top: 2px;
  left: 2px;
  width: 24px;
  height: 24px;
  text-align: center;
  line-height: 24px;
  background-color: #000;
  color: #fff;
  content: counter(count);
}

效果图

:::warning
由于flex的容量的高度是固定的,这时候缩小容器的宽度,而容器内的图片高度又因为宽度而改变(图片宽度设置成width: 100%),这时候flex只需要分成两列,便可以容纳所有图片,而我们只是用了数学方式来取巧规定了顺序,而交叉轴宽度变小,打乱了原先布局,能那么这时候图片顺序又会被打乱。便会如上图效果。
:::

三、使用js进行判断,根据当前所有列的最低列进行插入

受此uniapp插件启发

子组件

<template>
	<view v-if="spuId" class="goods-item" @click="itemClickHandler">
		<view class="goods-img">
			<image mode="scaleToFill" class="goods-item-image" :src="image" @load="emitHeight" @error="emitHeight"></image>
		</view>
		<view class="goods-desc">
			<view class="goods-subtitle">
				<text v-if="fast" class="fast-tag">极速达</text>
				{{ title }}
			</view>
			<view class="goods-title text-over">
				{{ subTitle }}
			</view>
			<view class="goods-price">
				<text class="price-icon">&yen;</text>
				<text class="price-number">{{ money }}</text>
			</view>
		</view>
		<!-- 购买按钮 -->
		<view class="buy-icon-view" @click.stop="buyBtnHandler">
			<uni-icons type="cart-filled" style="line-height: 23px;display: flex;align-items: center;justify-content: center;" color="#fff" size="20"></uni-icons>
		</view>
	</view>
</template>

<script>
	import BigNumber from 'bignumber.js'
	export default {
		name:"goodsItem",
		props:{
			image:{
				type:String,
				default:''
			},
			title:{
				type:String,
				default:''
			},
			price:{
				type:Number,
				default:0,
			},
			spuId:{
				type:Number,
				default:0
			},
			storeId:{
				type:Number,
				default:0
			},
			subTitle:{
				type:String,
				default:''
			},
			fast:{
				type:Boolean,
			},
			// 左右布局标识
			tag:{
				default:"",
				type:String
			}
		},
		data() {
			return {
				
			};
		},
		computed:{
			money(){
				let num = new BigNumber(this.price)
				return num.multipliedBy(0.01).toFixed(1)
			}
		},
		methods:{
			buyBtnHandler(){
				this.$emit('buyBtnHandler')
			},
			// 点击卡片事件
			itemClickHandler(){
				this.$emit('itemClickHandler')
			},
			emitHeight(e){
				const query = uni.createSelectorQuery().in(this);
								query.select('.goods-item').boundingClientRect(data => {
									let height = Math.floor(data.height);
									this.$emit("height",height,this.$props.tag);
								}).exec();
			},
		}
	}
</script>

<style lang="scss">
.goods-item {
	position: relative;
	font-size: 26rpx;
	width: 100%;
	background-color: #fff;
	border-radius: var(--default-radio);
	height: max-content;
	overflow: hidden;
	margin-bottom: 10px;
	.goods-img {
		width: 100%;
		height: max-content;
		overflow: hidden;
		.goods-item-image {
			width: 100%;
			max-height: 200px;
			// height: 200px;
			object-fit: cover;
		}
	}
	.goods-desc {
		width: 100%;
		box-sizing: border-box;
		padding: 8px;
	}
	.goods-subtitle {
		width: 100%;
		-webkit-line-clamp: 2;
		display: -webkit-box;
		overflow: hidden;
		word-break: break-all;
		-webkit-box-orient: vertical;
	}
	.goods-title {
		width: calc(100% - 30px);
		margin: 10rpx 0px;
		color: var(--pleace-text-color);
	}
	.goods-price {
		font-weight: bold;
		color: var(--primary-red-color);
		.price-icon {
			
		}
		.price-number {
			font-size: 32rpx;
		}
	}
	.buy-icon-view {
		position: absolute;
		right: 8px;
		bottom: 8px;
		display: flex;
		align-items: center;
		justify-content: center;
		width: 30px;
		height: 30px;
		border-radius: 100%;
		background-color: var(--primary-color);
	}
	.fast-tag {
		color: #fff;
		border-radius: 8px 0px 8px 0px;
		font-size: 13px;
		font-weight: bold;
		padding: 1px 3px;
		margin-right: 5px;
		background: linear-gradient(38deg, #d93211, #e85b36, #f37a1e);
	}
}
</style>

父组件

......
<view class="home-goods-list" :style="{width:bannerWidth+'px',marginTop: homeListMarginTop+'px'}">
					<view class="left-goods-container" id="left-goods-list" v-if="leftList.length > 0" :style="{width:goodsListWidth+'px'}">
						<goodsItem
						 v-for="(leftGoodsItem,index) in leftList"
						  :key="index"
						  :image="leftGoodsItem.image"
						  :title="leftGoodsItem.title"
						  :subTitle="leftGoodsItem.subTitle"
						  :spuId="leftGoodsItem.spuId"
						  :fast="leftGoodsItem.fast"
						  :price="leftGoodsItem.price"
						  @height="waterHeight"
						  tag="left"
						  @buyBtnHandler="buyBtnHandler(leftGoodsItem)"
						  @itemClickHandler="itemClickHandler(leftGoodsItem)"
						></goodsItem>
					</view>
					
					<view v-if="leftList.length <= 0" :style="{width:goodsListWidth+'px',background:'#fff'}" class="left-goods-container preview-left-list">
						<Skeleton class="goods-item-skeleton" :key="i" :loading="true" v-for="i in 4"
							:animate="true" avatar-shape="square" :showAvatar="true" :avatarSize=" (goodsListWidth / 2) + 'px' " :showTitle="true" :row="3" titleWidth="100%">
						</Skeleton>
					</view>
					
					<view class="right-goods-container" id="right-goods-list" v-if="rightList.length > 0" :style="{width:goodsListWidth+'px'}">
						<goodsItem
						 v-for="(rightGoodsItem,index) in rightList"
						  :key="index"
						  :image="rightGoodsItem.image"
						  :price="rightGoodsItem.price"
						  :title="rightGoodsItem.title"
						  :subTitle="rightGoodsItem.subTitle"
						  :spuId="rightGoodsItem.spuId"
						  :fast="rightGoodsItem.fast"
						  @height="waterHeight"
						  tag="right"
						  @buyBtnHandler="buyBtnHandler(rightGoodsItem)"
						  @itemClickHandler="itemClickHandler(rightGoodsItem)"
						></goodsItem>
					</view>
					
					<view v-if="rightList.length <= 0" :style="{width:goodsListWidth+'px',background:'#fff'}" class="right-goods-container preview-left-list">
						<Skeleton class="goods-item-skeleton" :key="i" :loading="true" v-for="i in 4"
							:animate="true" avatar-shape="square" :showAvatar="true" :avatarSize=" (goodsListWidth / 2) + 'px' " :showTitle="true" :row="3" titleWidth="100%">
						</Skeleton>
					</view>

					<!-- 添加当前的瀑布流信息 -->
<!-- 					<HelangWaterFall :status="state" :list="goodsList">
						
					</HelangWaterFall> -->
					
					
				</view>
......

<script>
export default {
   methods:{
      waterHeight(height,tag){
				let marginBottom = uni.upx2px(10);
				if (tag == 'left') {
									this.leftListHeight += (height + marginBottom);
								} else {
									this.rightListHeight += (height + marginBottom);
								}
								// console.log('height',height,'tag',tag,'this.leftListHeight',this.leftListHeight,'this.rightListHeight',this.rightListHeight)
								this.renderList()
			},
      renderList(){
				// console.log('sss',this.awaitList)
				if(this.awaitList.length < 1){
					return 
				}
				let item = this.awaitList.splice(0,1)[0]
				if(this.leftListHeight > this.rightListHeight){
					this.rightList.push(item);
				}else{
					this.leftList.push(item);
				}
				// console.log('left',this.leftList,this.rightList)
			},
// 查询首页商品数据
			QueryHomeGoods(){
				this.loadConfig.loadStatus = 'loading'
				this.state = 'loading'
				this.loadConfig.showIcon = true
				this.$service({
					method:"POST",
					url:"/QueryHomeGoods",
					data:{
						location:this.userAddress.location,
						page:this.page
					}
				}).then(response => {
					// console.log('首页商品数据',response);
					this.loadConfig.showIcon = false
					/* 查询当前首页里面是否已经有返回的列表里面的数据 则过滤一遍 */
					let _responseList = []
					this.state = 'success'
					response.list.forEach(i => {
						let _find = this.goodsList.findIndex(v => v.spuId == i.spuId)
						if(_find < 0){
							// 说明当前列表里面没有当前的
							_responseList.push(i)
						}
					})
					// console.log('_response',_responseList)
					this.goodsList = [...this.goodsList,..._responseList]
					this.awaitList = _responseList
					this.renderList()
					// _responseList.forEach((item,index) => {
					// 	// 偶数放右边
					// 	if((index % 2) === 0) {
					// 		this.rightList.push(item)
					// 	}else {
					// 		this.leftList.push(item)
					// 	}
					// })
				}).catch(err => {
					this.loadConfig.showIcon = false
					this.$t.errorToast(err.msg)
				})
			},
   }
}
</script>




完整index.vue代码

<template>
	<view class="container">
		<!-- 如果迁移的话 顶部迁移到此处 -->
		<!-- 全局搜索 -->
		<!-- 如果已经登录则显示当前页面如果没有显示则不显示 -->
		<scroll-view
		 :style="{height:'100vh'}"
		 scroll-y="true" :enhanced="true"
		 :scroll-top="scrollTop"
         :bounces="false"
		 :throttle="false"
		  @scroll="scrollHandler"
		  @scrolltoupper="toupperHandler"
		  @scrolltolower="tolowerHandler"
		  v-if="checkUserLoginStatus()"
		  >
			<view class="home-content"
			:style="{backgroundImage:`url(${previewPageBackground})`}"
			>
				<view class="" >

				<!-- 微信环境的条件编译 -->
				<!-- :bg-color="scrollOpcity == 0 ? '#fff' : '' " -->
				<pageTopBar style="width: 100%;position: fixed;z-index: 99;" :isFullRight="false" :bg-color="scrollOpcity == 0 ? '#fff' : 'transparent' "  text-color="#fff">
					<template #left-icon>
						<view class="location-view" @click="chooseLocationView">
							<view class="location-view-icon">
								<uni-icons :color="scrollOpcity == 0 ? '#000' : '#000' " type="location" class="location-icon-color" size="30"></uni-icons>
							</view>
							<view v-if="scrollOpcity!==0" class="location-view-text text-over">
								<text class="top-right-delivery" style="color: #000;" v-if="userAddress.receiver">{{ userAddress.receiver }}</text>
								<text  style="color: #000;" v-else>送至·选择配送地址</text>
								<uni-icons class="top-right-icon" type="right" color="#000"></uni-icons>
							</view>
							<view :style="{width:navBarWidth+'px'}" v-if="scrollOpcity==0" class="nav-bar-">
								<navBarSearch @searchClick='searchClickHandler'></navBarSearch>
							</view>
						</view>
					</template>
				</pageTopBar>
				<!-- 微信环境条件编译 -->

				<!-- banner && 搜索 -->
				<view class="home-top-content" :style="{paddingTop: appNavHeight + 'px'}">
					<view class="search-view" @click="searchClickHandler" :style="{paddingRight:padding+'px',paddingLeft:padding+'px',}">
						<view class="search-inner" :style="{backgroundColor:searchConfig.editing.color ? searchConfig.editing.color : '#fff'}">
							<view class="search-left-scan" @click.stop="scanCodeHandler">
								<uni-icons type="scan" size="22" color="#aaaaaa"></uni-icons>
							</view>
							<view class="search-inner-right-input">
								<view class="search-border">
									<view class="search-inner-center" :style="{color:searchConfig.editing.text ?  searchConfig.editing.text : '#a8a8a8'}">
										{{ searchConfig.editing.title ?  searchConfig.editing.title : '请输入搜索商品'}}
									</view>
									<view class="search-inner-button" :style="{backgroundColor:searchConfig.button.color ? searchConfig.button.color : 'burlywood',color:searchConfig.button.text ? searchConfig.button.text : '#fff'}">
										{{ searchConfig.button.title ? searchConfig.button.title : '搜索'}}
									</view>
								</view>
							</view>
						</view>
					</view>
					<!-- banner -->
					<view class="uni-margin-wrap" :style="{width:bannerWidth+'px',margin:`0px ${padding}px`}">
						<swiper
						 @change="swiperChangeHandler"
						 class="swiper swiper-content-main"
						 indicator-active-color="#0071ce"
						 indicator-color="#d8d8d7"
						 circular :indicator-dots="indicatorDots" :autoplay="autoplay" :interval="interval"
						 :duration="duration">
							<swiper-item v-for="(bannerItem,index) in banner">
								<view class="swiper-item uni-bg-red">
									<image @click="bannerPreviewHandler(bannerItem)" :src="bannerItem.image"  mode="" class="banner-img"></image>
								</view>
							</swiper-item>
						</swiper>
					</view>
				</view>

					<!-- 分类 -->
					<view class="secend-cate-view whrite-bg radius-12" v-if="cates.length > 0">
						<view class="c-cate-view" :style="{width:cateRowWidth}" id="cate">
							<view class="c-item"
							 v-for="(item,index) in cates"
							 :key="index"
							 @click="cateItemHandler(item)"
							 >
								<view class="c-top-img">
									<image class="c-top-image" :src="item.image" mode=""></image>
								</view>
								<view class="c-bottom">
									{{ item.title }}
								</view>
							</view>
						</view>
					</view>
					<view v-if="cates.length <= 0" style="display: flex; align-items: center;flex-wrap: wrap;" class="secend-cate-view whrite-bg radius-12">
						<Skeleton  :key="i" class="goods-skeleton-glo" :loading="true" v-for="i in 10"
							:animate="true" avatar-shape="round" :showAvatar="true" avatarSize="45px" :showTitle="true" :row="0" titleWidth="100%">
						</Skeleton>
					</view>
					
					<view class="swiper-3 flex-1-row login-flex-1">
						<view class="row-left-view">
							<banner-swiper
							 @bannerSwiperItemClick="bannerSwiperItemClickHandler"
							 :array-list="previewPageDeveicy"
							 swiper-height="70px"></banner-swiper>
						</view>
						<view class="row-right-view">
							<banner-swiper @bannerSwiperItemClick="bannerSwiperItemClickHandler" :array-list="previewPageShequn" swiper-height="70px"></banner-swiper>
						</view>
					</view>

					<!-- 横幅 -->
					<!-- <view class="streamer-box" v-if="wxbanner" :style="{width:bannerWidth+'px'}">
						<swiper
						 class="_swiper"
						 indicator-active-color="#0071ce"
						 indicator-color="#d8d8d7"
						 :indicator-dots="false"
						 circular  :autoplay="autoplay" :interval="interval"
						 :duration="duration">
							<swiper-item @click="toWebView(bannerItem.link)" v-for="(bannerItem,index) in wxbanner">
								<view class="swiper-item uni-bg-red">
									<image :src="bannerItem.image"  mode="" class="banner-img"></image>
								</view>
							</swiper-item>
						</swiper>
					</view> -->

					<!-- 弹窗 -->
					<view v-if="showMask && !showAddressPopup" @touchmove.stop.prevent="moveStop" class="sm-mask">
						<view class="sm-content">
							<view class="content">
								<image @click="maskPreview" class="sm-image" :show-menu-by-longpress="true" :src="wxMask.image" mode="aspectFill"></image>
								<view class="sm-close" @click="closeMask">
									<i class="iconfont icon-guanbi close-icon-btn"></i>
								</view>
							</view>
						</view>
					</view>

					<!-- 需要显示的查询之前收货地址的信息 -->
					<view class="choose-address-model" v-if="showAddressPopup">
						<view class="choose-address-model-inner">
							<view class="choose-address-model-top">
								<view class="choose-title uni-h5 ft-weight-bold">
									请选择收货地址
								</view>
								<view class="add">
									<i class="iconfont icon-guanbi close-icon" @click="closeAddressPopup"></i>
								</view>
							</view>
							<view class="address-list" v-if="addressList.length <= 0">
								<img style="width: 100%;object-fit: cover;" class="wait-add-image" :src="waitImg" alt="" srcset="" />
							</view>
							<view class="address-list" v-if="addressList.length > 0">
								<view class="address-item"
								 v-for="(addressItem,addressIndex) in addressList"
								 @click="updateAddress(addressItem)"
								 :key="addressIndex"
								 >
									<view class="item-center">
										<text class="item-tag" v-if="addressItem.tag!==''">{{ addressItem.tag }}</text>
										<text class="item-receiver" style="word-break: break-all;">{{ addressItem.receiver }}</text>
										<text class="item-detail">{{ addressItem.detail }}</text>
									</view>
									<view class="item-bottom">
										<text class="item-name">{{ addressItem.name }}</text>
									</view>
								</view>
							</view>
							<view class="address-cancel" @click="addOtherLocation">
								<view class="address-cancel-btn">
									添加其它地址
								</view>
							</view>
						</view>
					</view>
				</view>
				<view class="home-goods-list" :style="{width:bannerWidth+'px',marginTop: homeListMarginTop+'px'}">
					<view class="left-goods-container" id="left-goods-list" v-if="leftList.length > 0" :style="{width:goodsListWidth+'px'}">
						<goodsItem
						 v-for="(leftGoodsItem,index) in leftList"
						  :key="index"
						  :image="leftGoodsItem.image"
						  :title="leftGoodsItem.title"
						  :subTitle="leftGoodsItem.subTitle"
						  :spuId="leftGoodsItem.spuId"
						  :fast="leftGoodsItem.fast"
						  :price="leftGoodsItem.price"
						  @height="waterHeight"
						  tag="left"
						  @buyBtnHandler="buyBtnHandler(leftGoodsItem)"
						  @itemClickHandler="itemClickHandler(leftGoodsItem)"
						></goodsItem>
					</view>
					
					<view v-if="leftList.length <= 0" :style="{width:goodsListWidth+'px',background:'#fff'}" class="left-goods-container preview-left-list">
						<Skeleton class="goods-item-skeleton" :key="i" :loading="true" v-for="i in 4"
							:animate="true" avatar-shape="square" :showAvatar="true" :avatarSize=" (goodsListWidth / 2) + 'px' " :showTitle="true" :row="3" titleWidth="100%">
						</Skeleton>
					</view>
					
					<view class="right-goods-container" id="right-goods-list" v-if="rightList.length > 0" :style="{width:goodsListWidth+'px'}">
						<goodsItem
						 v-for="(rightGoodsItem,index) in rightList"
						  :key="index"
						  :image="rightGoodsItem.image"
						  :price="rightGoodsItem.price"
						  :title="rightGoodsItem.title"
						  :subTitle="rightGoodsItem.subTitle"
						  :spuId="rightGoodsItem.spuId"
						  :fast="rightGoodsItem.fast"
						  @height="waterHeight"
						  tag="right"
						  @buyBtnHandler="buyBtnHandler(rightGoodsItem)"
						  @itemClickHandler="itemClickHandler(rightGoodsItem)"
						></goodsItem>
					</view>
					
					<view v-if="rightList.length <= 0" :style="{width:goodsListWidth+'px',background:'#fff'}" class="right-goods-container preview-left-list">
						<Skeleton class="goods-item-skeleton" :key="i" :loading="true" v-for="i in 4"
							:animate="true" avatar-shape="square" :showAvatar="true" :avatarSize=" (goodsListWidth / 2) + 'px' " :showTitle="true" :row="3" titleWidth="100%">
						</Skeleton>
					</view>

					<!-- 添加当前的瀑布流信息 -->
<!-- 					<HelangWaterFall :status="state" :list="goodsList">
						
					</HelangWaterFall> -->
					
					
				</view>
				<!-- 加载图标 -->
				<uni-load-more iconType="circle"
				 icon-size="14"
				 :show-icon="loadConfig.showIcon"
				 :status="loadConfig.loadStatus" />
			</view>
			<view class="global-mask" v-if="showAddressPopup">
				
			</view>
		</scroll-view>
		<!-- 条件 用户未登录 而且未授权协议 -->
		<view v-if="!checkUserLoginStatus() && userLicenseAgreement" class="no-login-box" :style="{padding:`0px ${padding}px 0px ${padding}px`,backgroundImage:`url(${previewPageBackground.image})`}">
			<view class="no-login-tabbar">
				<!-- transparent -->
				<page-top-bar
				bg-color="#fff"
				>
					<template #title>
						<view>好吃鬼</view>
					</template>
				</page-top-bar>
			</view>
			<!-- 显示内容 -->
			<view class="login-form">
				<!-- 写入 未登录时候的内容 -->
				<view class="no-auth-review" :style="{paddingTop: appNavHeight+'px'}">
					<view class="swiper-1" v-if="previewPageAnnounce && previewPageAnnounce.length > 0">
						<banner-swiper :array-list="previewPageAnnounce" swiper-height="100px" @bannerSwiperItemClick="noLoginBannerItemHandler1"></banner-swiper>
					</view>
					<view class="swiper-2">
						<banner-swiper :array-list="previewPageCarouse" @bannerSwiperItemClick="noLoginBannerItemHandler1"></banner-swiper>
					</view>
					<view class="swiper-3 flex-1-row">
						<view class="row-left-view">
							<banner-swiper @bannerSwiperItemClick="noLoginBannerItemHandler1" :array-list="previewPageDeveicy" swiper-height="70px"></banner-swiper>
						</view>
						<view class="row-right-view">
							<banner-swiper @bannerSwiperItemClick="noLoginBannerItemHandler1" :array-list="previewPageShequn" swiper-height="70px"></banner-swiper>
						</view>
					</view>
					
					
					<bottomPositionBtn>
						<!-- #ifndef MP-TOUTIAO -->
						<button class="use-login-btn lx-text-center"
							open-type="getPhoneNumber"  @getphonenumber="getphonenumber">
								登录后才可购买商品噢~
						</button>
						<!-- #endif -->
						<!-- #ifdef MP-TOUTIAO -->
						<view class="use-login-btn lx-text-center" style="padding: 15px 10px;" @click="ttGetUserInfoHandler">
							登录后才可购买商品噢~
						</view>
						<!-- #endif -->
					</bottomPositionBtn>
				</view>
				
				<!-- 预览列表 -->
				<view class="preview-goods-list">
					<view v-if="noAuthorizationLeftPreviewList.length > 0" class="preview-left-list">
						<goodsItem
						 v-for="(leftGoodsItem,index) in noAuthorizationLeftPreviewList"
						  :key="index"
						  :image="leftGoodsItem.image"
						  :title="leftGoodsItem.title"
						  :subTitle="leftGoodsItem.subTitle"
						  :spuId="leftGoodsItem.spuId"
						  :storeId="leftGoodsItem.spuId"
						  :fast="leftGoodsItem.fast"
						  :price="leftGoodsItem.price"
						  @buyBtnHandler="buyBtnHandler(leftGoodsItem)"
						  @itemClickHandler="itemClickHandler(leftGoodsItem)"
						></goodsItem>
					</view>
					
					<view v-if="noAuthorizationLeftPreviewList.length <= 0" class="skeleton-preview-left-list preview-left-list">
						<Skeleton class="goods-item-skeleton" :key="i" :loading="true" v-for="i in 4"
							:animate="true" avatar-shape="square" :showAvatar="true" :avatarSize=" (goodsListWidth / 2) + 'px' " :showTitle="true" :row="3" titleWidth="100%">
						</Skeleton>
					</view>
					
					<view v-if="noAuthorizationRightPreviewList.length <= 0" class="skeleton-preview-left-list preview-right-list">
						<Skeleton class="goods-item-skeleton" :key="i" :loading="true" v-for="i in 4"
							:animate="true" avatar-shape="square" :showAvatar="true" :avatarSize=" (goodsListWidth / 2) + 'px' " :showTitle="true" :row="3" titleWidth="100%">
						</Skeleton>
					</view>
					
					<view v-if="noAuthorizationRightPreviewList.length > 0" class="preview-right-list">
						<goodsItem
						 v-for="(rightGoodsItem,index) in noAuthorizationRightPreviewList"
						  :key="index"
						  :image="rightGoodsItem.image"
						  :title="rightGoodsItem.title"
						  :storeId="rightGoodsItem.spuId"
						  :subTitle="rightGoodsItem.subTitle"
						  :spuId="rightGoodsItem.spuId"
						  :fast="rightGoodsItem.fast"
						  :price="rightGoodsItem.price"
						  @buyBtnHandler="buyBtnHandler(rightGoodsItem)"
						  @itemClickHandler="itemClickHandler(rightGoodsItem)"
						></goodsItem>
					</view>
					<!-- 遮罩 -->
					<view class="preview-goods-list-bottom-mask">
						
					</view>
				</view>
				
				
				
				<view class="login-inner">
					<!-- 一键登录 -->
					<view class="one-click-login">
						<!-- <view class="one-click-login-title">
							登录后了解优质商品
						</view>
						<view class="one-click-logo">
							<image class="logo" src="https://img-qn.51miz.com/preview/video/00/00/15/15/V-151592-29F80320O.jpg" mode=""></image>
						</view> -->
						<view class="login-form-btns">
							<!-- #ifndef MP-TOUTIAO -->
							<!-- <button class="login-form-btn access-phone-login"
							open-type="getPhoneNumber"  @getphonenumber="getphonenumber">
								授权手机号一键登录
							</button> -->
							<!-- #endif -->
							<!-- #ifdef MP-TOUTIAO -->
							<!-- <view class="login-form-btn access-phone-login" @click="ttGetUserInfoHandler">
								授权手机号登录
							</view> -->
							<!-- #endif -->
							<!-- <view class="login-form-btn code-login" @click="goCodeLogin">
								短信验证码登录
							</view> -->
						</view>
					</view>
				</view>
			</view>
		</view>
		<!-- 引入隐私政策 用户注册协议 -->
		<privacyPolicy :show-popup="showPrivacyPolicy" :privacyContent="htmlContent.html"></privacyPolicy>
	</view>
</template>

<script>
	/**
	 * 顶部 280px
	 * 搜索高度 - 50px
	 * banner 高度 150px
	 * 剩余高度 280 - 200 = 80 也就是当前banner占用了高度
	 * 需要距离高度为 当前高度 - 占用高度

	 */
	import pageTopBar from '@/components/pageTopBar/pageTopBar.vue'
	import navBarSearch from '@/components/navBarSearch/navBarSearch.vue'
	import goodsItem from '@/components/goodsItem/goodsItem.vue'
	import privacyPolicy from '@/components/privacyPolicy/privacyPolicy.vue'
	import bannerSwiper from '@/components/bannerSwiper/bannerSwiper.vue'
	import bottomPosition from '@/components/bottomPopup/bottomPopup.vue'
	import Skeleton from '@/components/J-skeleton/J-skeleton.vue'
	import HelangWaterFall from '@/components/helang-waterfall/components/waterfall/waterfall-list.vue'
	import {mapState,mapMutations,mapGetters,mapActions} from 'vuex'
	import { checkURL, twoFixed } from '../../utils/utils'
	import { httpQueryGoodsGrouping,httpGetAroundAddress,httpGetUserInfo } from '../../API'
	import { imgHttpPre } from '@/utils/gloablHttpUrl.js'
	export default {
		created() {
			console.log(twoFixed(0))
			let that = this
			console.log(this.smToken);
			if(this.smToken) {
				// 如果是登陆状态时候进入页面执行的函数
				this.isLoginCreate()
			}else {
				this.noLoginCreate()
			}
			uni.$on('update',function(res){
				that.updateLocationInitRequest()
			})
			// 用户同意用户协议 -- 保存同意认证
			uni.$on('confirm-privacy',function(){
				that.showPrivacyPolicy = false
				that.SET_IS_USER_AGGREMMENT('true')
				that.userAuthorizationLocation()
				// that.getNoAuthorizationData() // 去请求无需授权的data
			})
			/* 添加其他地址之后关闭当前的选择收货地址页面 */
			uni.$on('close-address-popup',() => {
				that.showAddressPopup = false
			})
			// 进入页面时候如果有大概地理位置信息则查询附近地址
			// this.setDefaultAroundAddress()
		},
		data() {
			return {
				waitImg:imgHttpPre  + '/images/wait-add.png',
				state:'',
				initScrollTop:0, // 滚动时候判断当前页面是向上还是向下滑动
				// isScrollPosition:false, // 是否滑动到指定位置 显示搜索 隐藏当前选择的地址
				scrollOpcity:1, // 滑动之后显示的搜索框透明度 0 为不显示 1为显示
				searchViewInner:0,
				indicatorDots: true,
				autoplay: true,
				interval: 2000,
				duration: 500,
				cates:[], // 分类列表
				progressLeft:0,
				goodsList:[],//首页商品列表
				leftList:[], // 左侧
				rightList:[], // 右侧商品池
				loadConfig:{
					showIcon:true,
					loadStatus:'more'
				},
				searchViewLeftPadding: 0, // 向上滑动时候需要缩小的内边距倍率
				cateRowWidth:'',// 分类的宽度
				rowNumber:6, // 当前每一行多少个分类
				switchUrl:'city',
				page:1, // 当前加载商品页码
				userAgremment:false,
				scrollTop:0,
				old:{
					scrollTop:0,
				},
				wxMask:{}, // 微信弹窗
				showMask:false, // 是否显示微信弹窗
				initShowMask:false,
				showAddressPopup:false,//显示address弹窗
				addressList:[],// 收货地址列表
				isFirstShowAddressPopup:false,//是第一次 显示过了 当前定位
				showPrivacyPolicy:true, // 用户隐私协议
				noAuthorizationLeftPreviewList:[], // 未登录预览
				noAuthorizationRightPreviewList:[],
				leftListHeight:1, // 左右两边列表的大致高度
				rightListHeight:2,
				awaitList:[],
			}
		},
		// 分享页
		onShareAppMessage() {
			let team = this.userInforMation.team
			if(team){
				return {
					path:`pages/index/index?team=${team}`
				}
			}
			return {
				path:`pages/index/index`
			}
		},
		// 朋友圈分享
		onShareTimeline() {
			let team = this.userInforMation.team
			if(team){
				return {
					title:"好吃鬼严选,点击加入我的团队",
					path:`pages/index/index?team=${team}`
				}
			}
			return {
				title:"好吃鬼严选,点击加入我的团队",
				path:`pages/index/index`
			}
		},
		onShow() {
			let _this = this
			// 页面显示时候根据传递的信息判断是否需要重新刷新当前页面
			this.updateBadge()
			// 如果用户未登录但是同意了协议
			// 如果本地没有地理位置信息则直接进行授权获取
			if(this.userAddress.location == undefined || this.userAddress.location == '' || this.userAddress.location == 'undefined'){
				uni.getFuzzyLocation({
					success(res) {
						console.log('获取模糊位置信息 ',res);
						let location = `${res.longitude},${res.latitude}`
						_this.UPDATE_ADDRESS({key:'location',value:location})
						// _this.getNoAuthorizationData() // 去请求无需授权的data
						_this.UPDATE_APP_CONFIG()
					},
					fail(err) {
						uni.redirectTo({
							url:"/sub_pages/noPosition/noPosition"
						})
					}
				})	
			}
			else {
				this.UPDATE_APP_CONFIG().then(res => {
					// 不管登录没有都要获取配置之后请求当前商品数据列表 == 分类列表格式化
					if(this.formatAppConfig && this.formatAppConfig.length) {
						console.log('22222',getApp().globalData)
						if(this.smToken){
							this.cates = this.cates.length > 0 ? this.cates : []
							if(this.cates && this.cates.length > 0){
								this.QueryHomeGoods()
							}else {
								this.queryGroupList()
								this.QueryHomeGoods()
							}
						}
						this.wxMask = this.findPageTypeDetail(this.formatAppConfig,'首页','弹窗广告')  ? this.findPageTypeDetail(this.formatAppConfig,'首页','弹窗广告') : []
						if(!(this.wxMask instanceof Array)) {
							// 只弹出一次 本次会话有效
							console.log('wxmask',this.findPageTypeDetail(this.formatAppConfig,'首页','弹窗广告'));
							this.showMask = this.initShowMask ? false : true
							if(this.smToken){
								this.initShowMask == true ? '' : this.queryUserAddress()
								// 进入页面时候如果有大概地理位置信息则查询附近地址
								this.setDefaultAroundAddress()
							}
							this.initShowMask = true	
						}
					}
				})
			}
			if(this.isUserAgremment === 'true' && (!this.smToken)) {
				this.getNoAuthorizationData()
				// this.UPDATE_APP_CONFIG().then(res => {
				// 	console.log('sppconfig',this.formatAppConfig[0]);
				// })
			}
			console.log('formatAppConfig',this.appConfig)
		},
		mounted() {
			this.qrCodeSkip()
		},
		components:{pageTopBar,navBarSearch,goodsItem,privacyPolicy,bannerSwiper,Skeleton,HelangWaterFall},
		computed:{
			...mapState('user',['smToken','isUserAgremment','userInforMation']),
			...mapState('address',['userAddress']),
			...mapGetters('shoppingCart',['goodsCount']),
			...mapState('appConfig',['formatAppConfig','appConfig']),
			// 未登录预览背景
			previewPageBackground(){
				if(this.formatAppConfig && this.formatAppConfig.length) {
					let s = this.findPageTypeDetail(this.formatAppConfig,'首页','页面背景')
					return s	
				}
				return ''
			},
			// 未登录顶部公告
			previewPageAnnounce(){
				if(this.formatAppConfig && this.formatAppConfig.length) {
					let s = this.findPageTypeDetail(this.formatAppConfig,'首页','横幅公告')
									console.log('横幅公告',s)
					return s	
				}
				return []
			},
			// 未登录 --广告轮播
			previewPageCarouse(){
				if(this.formatAppConfig && this.formatAppConfig.length) {
					let s = this.findPageTypeDetail(this.formatAppConfig,'首页','轮播广告')
					return s	
				}
				return []
			},
			// 未登录配送类型
			previewPageDeveicy(){
				if(this.formatAppConfig && this.formatAppConfig.length) {
					let s = this.findPageTypeDetail(this.formatAppConfig,'首页','配送类型')
					let a = []
					a.push(s)
					return a
				}
				return []
			},
			previewPageShequn(){
				if(this.formatAppConfig && this.formatAppConfig.length) {
					let s = this.findPageTypeDetail(this.formatAppConfig,'首页','官方社群')
					let a = []
					a.push(s)
					return 	a
				}
				return []
			},
			htmlContent(){
				if(this.formatAppConfig && this.formatAppConfig.length) {
					let s = this.findPageTypeDetail(this.formatAppConfig,'首页','用户协议')
					console.log('s',s)
					return 	s
				}
				return ""
			},
			wxbanner(){
				if(this.formatAppConfig && this.formatAppConfig.length) {
					let s = this.findPageTypeDetail(this.formatAppConfig,'首页','横幅广告')
					return 	s
				}
				return []
			},
			banner(){
				if(this.formatAppConfig && this.formatAppConfig.length) {
					let s = this.findPageTypeDetail(this.formatAppConfig,'首页','轮播广告')
					return 	s
				}
				return []
			},
			// 搜索配置
			searchConfig(){
				if(this.formatAppConfig && this.formatAppConfig.length) {
					let s = this.findPageTypeDetail(this.formatAppConfig,'首页','商品搜索')
					return 	s
				}
				return {}
			},
			padding(){
				return getApp().globalData.gapLeft
			},
			// banner区域的宽度也可以视为当前页面主题内容标准宽度
			bannerWidth(){
				return (getApp().globalData.screenWidth - 2*this.padding)
			},
			// 顶部搜索宽度
			navBarWidth(){
				// #ifndef MP-TOUTIAO
				return (getApp().globalData.screenWidth - 35 - 2*this.padding - getApp().globalData.boundingObject.width)
				// #endif

				// #ifdef MP-TOUTIAO
				return (getApp().globalData.screenWidth - 2*this.padding - 30)
				// #endif
			},
			goodsListWidth(){
				return ((this.bannerWidth / 2) - this.padding / 2)
			},
			cateRow(){
				let num = this.cates.length
				if(num < this.rowNumber) {
					this.cateRowWidth = `calc(var(--width) * ${num})`
				}else {
					this.cateRowWidth = `calc(var(--width) * ${this.rowNumber})`
				}
				return Math.ceil((num / this.rowNumber))
			},
			homeListMarginTop(){
				// 当前行数 this.cateRow
				// 每行高度 76
				// return (this.cateRow * 90) - 80 + 10
				return 10
			},
			appNavHeight(){
				// #ifndef MP-TOUTIAO
				return getApp().globalData.appNavHeight + 10
				// #endif

				// #ifdef MP-TOUTIAO
				return 52
				// #endif
			},
			/* 用户授权协议 */
			userLicenseAgreement(){
				return this.isUserAgremment === 'true' ? true : false
			},
		},
		methods: {
			...mapMutations('shoppingCart',['ADD_GOODS_TO_SHOPPING_CART']),
			...mapMutations('user',['SET_SM_TOKEN','SET_IS_USER_AGGREMMENT','SET_USER_INFO','UPDATE_USER_INFORMATION']),
			...mapMutations('appConfig',['SET_APP_CONFIG']),
			...mapActions('appConfig',['UPDATE_APP_CONFIG']),
			...mapMutations('address',['UPDATE_ADDRESS']),
			...mapActions('shoppingCart',['ADD_GOODS_TO_SERVER_HANDLER']),
			waterHeight(height,tag){
				let marginBottom = uni.upx2px(10);
				if (tag == 'left') {
									this.leftListHeight += (height + marginBottom);
								} else {
									this.rightListHeight += (height + marginBottom);
								}
								// console.log('height',height,'tag',tag,'this.leftListHeight',this.leftListHeight,'this.rightListHeight',this.rightListHeight)
								this.renderList()
			},
			// 扫码跳转
			qrCodeSkip(){
				let _this = this
				if(this.smToken && this.userInforMation.spuId){
					setTimeout(() => {
						uni.navigateTo({
							url:`/sub_pages/goodsDetail/goodsDetail?spuId=${this.userInforMation.spuId}`
						})
						_this['UPDATE_USER_INFORMATION']({key:'spuId',value:''})
					},100)
				}
			},
			renderList(){
				// console.log('sss',this.awaitList)
				if(this.awaitList.length < 1){
					return 
				}
				let item = this.awaitList.splice(0,1)[0]
				if(this.leftListHeight > this.rightListHeight){
					this.rightList.push(item);
				}else{
					this.leftList.push(item);
				}
				// console.log('left',this.leftList,this.rightList)
			},
			// 更新了用户的location信息之后
			updateLocationInitRequest(){
				uni.showTabBar()
				this.goBackTop()
				this.leftList = []
				this.rightList = []
				this.page = 1
				this.goodsList = []
				this.switchUrl = 'location'
				this.isLoginCreate()
			},
			/**
			 * @name findPageTypeDetail
			 * @param {Array}  appConfig - 页面配置集合
			 * @param {String} page - 页面名称
			 * @param {String} type - 页面名称下类型
			 * @returns {any || []} detailes
 			*/
			findPageTypeDetail(appConfig,page,type){
				let result = null
				appConfig.forEach(i => {
					if(i.page == page) {
						let r = i.attr.find(v => v.type == type)
						if(r) {
							result = r.details
						}
					}
				})
				return result || []
			},
			// 判断用户是否已经授权 如果已经同意过则 判断是否登录过如果登录过显示正常页面 如果没有登录过显示测试页面
			checkUserAuth(){
				// 用户隐私授权过
				if(this.isUserAgremment === 'true') {
					this.showPrivacyPolicy = false // 则不提示授权窗口
					return true
				}else {
					return false
				}
			},
			/* 查询分类列表 */
			queryGroupList(){
				httpQueryGoodsGrouping().then((res) => {
					console.log('列表分类',res)
					if(res.code == 200) {
						this.cates = res.list
						getApp().globalData.isSessionEnter = true
						this.catesFormate()
					}
				}).catch(err => {
					
				})
			},
			// 已经登录状态进入页面执行的create
			isLoginCreate(){
				// 登录时候如果没有 location状态
				if((!this.userAddress.location || !this.userAddress.city || !this.userAddress.province) && this.smToken) {
					// 执行获取地理位置信息
					this.userAuthorizationLocation()
				}
				
				this.checkLocation() // 判断用户应该进入哪个页面
				// 如果本地已经选择了location 但是没有选择addressid  且为第一次进入弹窗则显示弹窗
				// console.log(this.userAddress.addressid,this.userAddress.location);
				// 登录状态时候如果没有这两个属性则直接跳转到选择配送城市页面
				// if(!this.userAddress.location && !this.userAddress.city) {
				// 	uni.navigateTo({
				// 		url:"/sub_pages/chooseCity/chooseCity"
				// 	})
				// }
				// if((!this.userAddress.addressid) && this.userAddress.location && !this.isFirstShowAddressPopup){
				// 	this.queryUserAddress()
				// }
			},
			// 未登录状态进入页面执行的
			noLoginCreate(){

			},
			// 进入页面检查当前是否含有地址信息 没有的话提示选择信息 点击上面定位图标则跳转到选择城市页面
			// 判断个当前用户的登录状态
			checkUserLoginStatus(){
				this.checkUserAuth()
				if(this.smToken && this.smToken!=='' && this.smToken !== undefined && this.smToken.length > 1) {
					return true
				}else {
					uni.hideTabBar()
					return false
				}
			},
			/* 设置默认周边信息 */
			setDefaultAroundAddress(){
				console.log(this.userAddress.location && !this.userAddress.province && !this.userAddress.city && !this.userAddress.receiver)
				if(this.userAddress.location && !this.userAddress.province && !this.userAddress.city && !this.userAddress.receiver){
					httpGetAroundAddress(this.userAddress.location).then(res => {
						// console.log('获取周边地理位置之后设置默认地址',res)
						if(res.code == 200){
							let result = res.list[0]
							Object.keys(this.userAddress).forEach(key => {
								this.UPDATE_ADDRESS({key:key,value:result[key] ? result[key] : '' })
							})
						}
					}).catch(err => {
						this.$t.toast(err.msg || '获取周边默认位置信息失败')
					})
				}
			},
			updateBadge(){
				if(this.goodsCount > 0) {
					uni.setTabBarBadge({ //显示红点
						index: 2 ,//tabbar下标
						text:this.goodsCount+'',
					})
				}
				if(this.goodsCount == 0) {
					uni.hideTabBarRedDot({
						index:2
					})
				}
			},
			/* 让用户授权位置信息 */
			userAuthorizationLocation(){
				let _this = this
				// #ifndef MP-TOUTIAO
						uni.getFuzzyLocation({
							success(res) {
								console.log('获取模糊位置信息 ',res);
								let location = `${res.longitude},${res.latitude}`
								_this.UPDATE_ADDRESS({key:'location',value:location})
								_this.getNoAuthorizationData() // 去请求无需授权的data
								// 授权成功之后进行获取周边地理位置信息
								// _this.$service({
								// 	method:"POST",
								// 	url:"/QueryAround",
								// 	data:{
								// 		location:location,
								// 		size:10
								// 	},
								// }).then(response => {
								// 	console.log('response',response);
								// 	if(response.list) {
								// 		let _address = response.list[0]
								// 		Object.keys(_address).forEach(key => {
								// 			_this.UPDATE_ADDRESS({key,value:_address[key]})
								// 		})
								// 	}
								// }).catch(error => {
								// 	_this.$t.toast('获取周边数据失败')
								// 	console.log('获取周边数据失败',error);
								// 	uni.redirectTo({
								// 		url:"/sub_pages/noPosition/noPosition"
								// 	})
								// })
							},
							fail(err) {
								console.log('获取位置信息失败',err);
								// 获取地理位置信息失败 则跳转定位失败页面
								uni.redirectTo({
									url:"/sub_pages/noPosition/noPosition"
								})
								// _this.$t.toast('获取地理位置失败')
							}
						})	
				// #endif
				
				// #ifdef MP-TOUTIAO
				uni.getLocation({
					success(res) {
						console.log('字节获取地理信息 ',res);
						let location = `${res.latitude},${res.longitude}`
					},
					fail(err) {
						console.log('获取位置信息失败',err);
						uni.showToast({
							title:"获取定位信息失败",
							icon:"error"
						})
					}
				})	
				// #endif
			},
			checkLocation(){
				let result = this.userAddress.location
				//
				if(result) {
					this.switchUrl = "location"
				}else {
					this.switchUrl = 'city'
				}
			},
			/* 扫码点击 */
			scanCodeHandler(){
				let _this = this
				return _this.$t.toast('扫码功能暂不可用')
				if(!_this.searchConfig.QRcode) {
					_this.$t.toast('扫码功能暂不可用')
					return
				}
				uni.scanCode({
					onlyFromCamera:false,
					// scanType:["barCode"],
					autoDecodeCharSet:true,
					success(res) {
						// console.log('扫码成功结果',res);
						// 如果扫出来了数据
						if(res.result) {
							//
							_this.$service({
								method:"POST",
								url:"/QuerySpuid",
								data:{
									location:_this.userAddress.location,
									qrcode:res.result
								}
							}).then(response => {
								uni.navigateTo({
									url:"/sub_pages/goodsDetail/goodsDetail?spuId=" + response.spuid
								})
							}).catch(error => {
								_this.$t.errorToast('获取失败')
							})
						}
					},
					fail(error) {
						console.log('扫码失败',error);
					}
				})
			},
			// 获取app配置
			getHomeConfig(){
				this.$service({
					method:"POST",
					url:"/QueryPageConfig",
					data:{
						location:this.userAddress.location
					}
				}).then(response => {
					console.log('获取到的配置项',response);
					let config = response.list
					config.forEach(configItem => {
						if(configItem.page == '首页' && configItem.type == '商品分类'){
							// this.cates = configItem.details ? configItem.details : []
							// this.catesFormate()
						}else if(configItem.page == '首页' && configItem.type == '弹窗广告'){
							this.wxMask = configItem.details ? configItem.details : {}
							if(this.showAddressPopup) {
								this.showMask = false
								this.initShowMask = true
							}else {
								this.showMask = true
							}
						}
					})
					this.QueryHomeGoods()
				}).catch(error => {
					if(error.code == 100) {
						this.$t.errorToast('获取失败')
					}
				})
			},
			// 计算分类的行数
			catesFormate(){
				let length = this.cates.length
				if(length > 12) {
					this.rowNumber = Math.ceil(length / 2)
				}else {
					this.rowNumber = length
				}
			},
			// 查询首页商品数据
			QueryHomeGoods(){
				this.loadConfig.loadStatus = 'loading'
				this.state = 'loading'
				this.loadConfig.showIcon = true
				this.$service({
					method:"POST",
					url:"/QueryHomeGoods",
					data:{
						location:this.userAddress.location,
						page:this.page
					}
				}).then(response => {
					// console.log('首页商品数据',response);
					this.loadConfig.showIcon = false
					/* 查询当前首页里面是否已经有返回的列表里面的数据 则过滤一遍 */
					let _responseList = []
					this.state = 'success'
					response.list.forEach(i => {
						let _find = this.goodsList.findIndex(v => v.spuId == i.spuId)
						if(_find < 0){
							// 说明当前列表里面没有当前的
							_responseList.push(i)
						}
					})
					// console.log('_response',_responseList)
					this.goodsList = [...this.goodsList,..._responseList]
					this.awaitList = _responseList
					this.renderList()
					// _responseList.forEach((item,index) => {
					// 	// 偶数放右边
					// 	if((index % 2) === 0) {
					// 		this.rightList.push(item)
					// 	}else {
					// 		this.leftList.push(item)
					// 	}
					// })
				}).catch(err => {
					this.loadConfig.showIcon = false
					this.$t.errorToast(err.msg)
				})
			},
			// 点击顶部搜索跳转
			searchClickHandler(){
				uni.navigateTo({
					url:'/sub_pages/search/search'
				})
			},
			catesScrollHandler(e){
				let {target} = e
				let {deltaX,scrollLeft,scrollWidth} = target
				let str = Math.round((scrollLeft / scrollWidth)*100) / 100
				this.progressLeft = str*100
			},
			// 轮播图滚动处理函数
			swiperChangeHandler(event){
				let that = this
			},
			// 跳转选择地址页面
			chooseLocationView(){
				if(this.switchUrl == 'city') {
					uni.navigateTo({
						url:'/sub_pages/chooseCity/chooseCity'
					})
				}else {
					uni.navigateTo({
						url:'/sub_pages/chooseLocation/chooseLocation'
					})
				}
			},
			scrollHandler(e){
				let that = this
				// 同步滚动数据
				let {scrollTop} = e.detail
				that.old.scrollTop = scrollTop
				let rados = scrollTop * 0.02 // 当前显示倍数
				this.searchViewLeftPadding = rados * 28 // 搜索框左右拉伸
				if(that.initScrollTop > scrollTop){
					this.scrollOpcity = Math.abs(rados - 1)
					this.searchViewInner = this.scrollOpcity
					if(this.scrollOpcity > 0.9 || scrollTop < 5) {
						this.scrollOpcity = 1
						this.searchViewLeftPadding = 0
					}
				}else{
					/* 向下滑动隐藏然后 opcity应该趋近于0 */
					this.scrollOpcity = 1 - rados
					this.searchViewInner = this.scrollOpcity
					if(this.scrollOpcity < 0.3) {
						this.searchViewLeftPadding = 28
						return this.scrollOpcity = 0
					}
				}
				that.initScrollTop = scrollTop;
			},
			goBackTop(){
				this.scrollTop = this.old.scrollTop
				this.scrollOpcity = 1
				this.$nextTick(function() {
					this.scrollTop = 0
				});
			},
			// 触底
			tolowerHandler(){
				if(this.loadConfig.showIcon) return
				this.page++
				this.QueryHomeGoods()
			},
			// 滑动触顶
			toupperHandler(){
				// console.log('触顶',Math.random());
				this.$nextTick(() => {
					this.scrollOpcity = 1
				})
			},
			/* 商品分类点击处理 */
			cateItemHandler(cateItem){
				uni.reLaunch({
					url:"/pages/cate/cate?fatherId=" + cateItem.fatherId
				})
			},
			// 服务端添加数据
			addGoodsToServerHandler(spuId,quantity){
				let that = this
				return new Promise((resolve,reject) => {
					that.$service({
						method:"POST",
						url:"/Cart",
						data:{
							type:"add",
							spuid:spuId,
							quantity
						}
					}).then(response => {
						return resolve(response)
					}).catch(error => {
						return reject(error)
					})
				})
			},
			// 加购
			buyBtnHandler(goodsItem){
				if(!this.checkUserLoginStatus()) {
					this.$t.toast('请先登录查看更多')
					return
				}
				if(goodsItem.stock <= 0) return this.$t.toast('暂无库存')
				let {price,spuId,storeId} = goodsItem
				this.ADD_GOODS_TO_SERVER_HANDLER({spuId,quantity:1,storeId}).then(res => {
					this['ADD_GOODS_TO_SHOPPING_CART']({spuId,price,select:true,quantity:1,storeId})
					uni.showToast({
						title:"加购成功",
						icon:"success"
					})
				}).catch(err => {
					this.$t.errorToast('加购失败')
				})
			},
			// 跳转详情页
			itemClickHandler(goodsItem){
				if(!this.checkUserLoginStatus()) {
					this.$t.toast('请先登录查看更多')
					return
				}
				let { price,stock } = goodsItem
				if(price ==0 || stock == 0){
					return this.$t.toast('当前商品已下架,请查看其余商品')
				}
				uni.navigateTo({
					url:`/sub_pages/goodsDetail/goodsDetail?spuId=${goodsItem.spuId}`
				})
			},
			// 获取用户的登录信息
			getUserLoginInfo(){
				if(this.smToken && this.smToken!==''){
					httpGetUserInfo().then(res => {
						console.log(res)
						if(res.code == 200){
							this.SET_USER_INFO(res.UserInfo)
						}else {
							this.$t.toast(res.msg || '获取用户信息失败')
						}
					}).catch(err => {
						this.$t.toast(err.message || '获取用户信息异常')
						console.log('err: 获取用户信息失败',err)
					})
				}
			},
			getphonenumber(res){
				// console.log('一键登录回调',res);
				let {detail:{code}} = res
				let _this = this
				if(code){
					this.$service({
						method:"POST",
						url:"/WeChatQuickLogin",
						data:{
							code,
							team:_this.userInforMation.team ? _this.userInforMation.team : ""
						}
					}).then(response => {
						// console.log('ssss',response);
						if(response.code == 200) {
							this.SET_SM_TOKEN(response.token)
							this.getUserLoginInfo()
							if(this.userInforMation.spuId){
								uni.reLaunch({
									url:`/pages/index/index?spuId=${this.userInforMation.spuId}`
								})
								return
							}
							uni.reLaunch({
								url:"/pages/index/index"
							})
						}
					}).catch(error => {
						// console.log('一键登录失败',error);
						this.$t.errorToast('获取手机号失败')
					})
				}else {
					this.$t.errorToast('获取手机号失败')
				}
			},
			// 字节小程序获取用户信息
			ttGetUserInfoHandler(){
				if(uni.getUserProfile) {
					uni.getUserProfile({
						desc:"用于快速一键登录",
						success(res) {
							console.log('字节一件登录成功',res);
						},
						fail(err) {
							console.log('一键登录失败',err);
						}
					})
				}
			},
			// 短信验证码
			goCodeLogin(){
				if(this.userAgremment) {
					uni.navigateTo({
						url:"/sub_pages/codeLogin/codeLogin"
					})
				}else {
					uni.showToast({
						title:"请先阅读勾选用户协议",
						icon:"none"
					})
				}
			},
			// 弹窗点击
			maskPreview(){
				let that = this
				if(checkURL(that.wxMask.link)) {
					uni.navigateTo({
						url:"/sub_pages/webView/webView?webUrl=" + that.wxMask.link
					})
				}else {
						uni.navigateTo({
							url:`${that.wxMask.link}`
						})
				}
				this.closeMask()
			},
			// 轮播图
			bannerPreviewHandler(bannerItem){
				// console.log(bannerItem.link);
				if(checkURL(bannerItem.link)){
					uni.navigateTo({
						url:`/sub_pages/webView/webView?webUrl=${bannerItem.link}`
					})
				}else {
					uni.navigateTo({
						url:`${bannerItem.link}`
					})
				}
			},
			closeMask(){
				this.showMask = false
				uni.showTabBar()
			},
			/* 跳转webbview */
			toWebView(webUrl){
				if(checkURL(webUrl)) {
					uni.navigateTo({
						url:"/sub_pages/webView/webView?webUrl=" + webUrl
					})
				}else {
					uni.navigateTo({
						url:`${webUrl}`
					})
				}
			},
			/* 获取用户的云端收货地址 */
			queryUserAddress(){
				this.$service({
					method:"POST",
					url:"/Address",
					data:{
						type:"query"
					}
				}).then(res => {
					if(res.code == 200) {
						this.addressList = res.list.slice(0,3)
						console.log('response',this.addressList)
						if(this.addressList && this.addressList.length > 0){
							this.updateAddress(this.addressList[0])
							return
						}
						this.showAddressPopup = true
					}
				}).catch(err => {
					this.$t.errorToast('云端查询失败')
				})
			},
			// 点击收货地址弹窗里面内容
			updateAddress(addressItem){
				Object.keys(this.userAddress).forEach(key => {
					this.UPDATE_ADDRESS({key:key,value:addressItem[key]})
				})
				this.showAddressPopup = false
				this.showMask = this.initShowMask
			},
			closeAddressPopup(){
				this.showAddressPopup = false
				this.showMask = this.initShowMask
			},
			// 禁止滑动事件
			moveStop(){
			
			},
			// 未登录时候点击第一层轮播图的触发
			noLoginBannerItemHandler1(bannerItem){
				// console.log('接收到的信息',bannerItem);
				this.$t.toast('登录查看详情')
			},
			// 获取未登录首页配置
			getNoAuthorizationData(){
				let _this = this
				this.$service({
					method:"POST",
					url:"/QueryHomeGoods",
					data:{
						location:_this.userAddress.location,
						page:1
					}
				}).then(res => {
					console.log('查询首页商品列表>>>',res)
					res.list.forEach((item,index) => {
						item.money = twoFixed(item.price)
						// 偶数放右边
						if((index % 2) === 0) {
							this.noAuthorizationRightPreviewList.push(item)
						}else {
							this.noAuthorizationLeftPreviewList.push(item)
						}
					})
				}).catch(err => {
					
				})
			},
			// 点击自己封装的轮播组件函数
			bannerSwiperItemClickHandler(bannerItem){
				if(bannerItem.link) {
					this.toWebView(bannerItem.link)
				}
			},
			// 添加其他地址
			addOtherLocation(){
				uni.navigateTo({
					url:"/sub_pages/editShippingAddress/editShippingAddress?pageMode=add"
				})
			}
		},
		onPageScroll(e) {
		},
		// 触底
		onReachBottom() {
		},
	}
</script>

<style lang="scss" scoped>
	.container {
		// background-color: #f4f0ed;
	}
	.location-view {
		display: flex;
		align-items: center;
		.location-view-icon {
			color: #000;
		}
		.location-view-text {
			width: 160px;
			display: flex;
			align-items: center;
			.top-right-delivery {
				color: #000;
				flex: 1;
				max-width:max-content;
				overflow: hidden;
				white-space: nowrap;
				text-overflow: ellipsis;
			}
			.top-right-icon {
				width: max-content;
			}
		}
	}
	// 主要内容区域
	.home-content {
		width: 100%;
		background-color: var(--gray-color);
		background-repeat: no-repeat;
		background-size: cover;
		.home-top-content {
			position: relative;
			width: 100%;
			padding-top: 10px;
			// height: 280px;
			// transition: 1s linear;
			// box-shadow: 0 -17px 10px 0px rgba(255,255,255,.8) inset;
			// background-color: antiquewhite;
		}
		.search-view {
			transition: .1s all;
			display: flex;
			align-items: center;
			height: 50px;
			justify-content: space-between;
			.search-inner {
				width: 100%;
				box-sizing: border-box;
				display: flex;
				align-items: center;
				border-radius: 24px;
				padding: 4px 6px;
				background-color: #fff;
				.search-left-scan {
					margin-right: 8px;
					margin-left: 8px;
				}
				.search-inner-right-input {
					width: 100%;
					.search-border {
						position: relative;
						display: flex;
						align-items: center;
						padding-left: 8px;
						justify-content: space-between;
						&::after {
							position: absolute;
							left: 0;
							top: 50%;
							transform: translateY(-50%);
							content: "";
							width: 1px;
							height: 50%;
							background-color: #ececec;
						}
					}
					.search-inner-center {
						flex: 1;
						color: var(--pleace-text-color);
					}
					.search-inner-button {
						width: max-content;
						height: 100%;
						padding: 6px 15px;
						text-align: center;
						color: #fff;
						background-color: burlywood;
						border-radius: 24px;
					}
				}
			}
			// background-color: var(--primary-red-color);
			.search-view-left {
				flex: 1;
				display: flex;
				align-items: center;
				.search-view-inner {
					padding-left: 10px;
					width: 100%;
					height: 35px;
					line-height: 35px;
					background-color: #fff;
					margin-right: 30px;
					border-radius: 28px;
					display: flex;
					align-items: center;
					.search-view-left-icon {
						line-height: 35px;
					}
					.search-view-right-search {
						height: 100%;
					}
					.search-view-center {
						flex: 1;
						font-size: 14px;
						height: 100%;
						color: var(--pleace-text-color);
					}
					.search-view-button {
						color: #fff;
						height: 100%;
						padding: 0px 15px;
						border-radius: 28px;
						background-color: var(--primary-red-color);
					}
				}

			}
			.search-view-right {
				width: max-content;
			}
		}
	}

	.streamer-box {
		margin: 0 auto;
		// margin-top: 10px;
		border-radius: var(--default-radio);
		overflow: hidden;
		// height: 100px;
		.streamer-image {
			width: 100%;
			height: 100%;
			object-fit: cover;
		}
	}


	// 分类显示
	::v-deep .cates-view {
		position: absolute;
		bottom: -20px;
		height: 100px;
		background-color: #fff;
		border-radius: var(--default-radio);
	    .scroll-view_H {
			width: 100%;
			white-space: nowrap;
			display: flex;
			.scroll-view-item_H {
				display: inline-block;
				padding: 10px;
				// display: flex;
				.top-item-img {
					display: flex;
					flex-direction: column;
					align-items: center;
					justify-content: center;
					overflow: hidden;
					.top-item-img-cover {
						border-radius: var(--default-radio);
						width: 50px;
						height: 50px;
						object-fit: cover;
					}
					.top-item-title {
						font-size: 14px;
					}
				}
			}
		}
		.scroll-progress {
			position: absolute;
			left: 50%;
			transform: translateX(-50%);
			border-radius: 30px;
			width: 40px;
			height: 3px;
			overflow: hidden;
			background-color: var(--gray-color);
			.progress-inner {
				position: absolute;
				border-radius: 30px;
				width: 15px;
				height: 100%;
				background-color: var(--primary-color);
			}
		}
	}

	::v-deep .nav-bar- {
		// margin: 0px 2.5px;
	}
	::v-deep .nav-bar-search {
		// background-color: #fff !important;
	}
	.flex-1-row {
		width: 100%;
		display: flex;
		align-items: center;
		justify-content: space-between;
		
		.row-left-view {
			width: calc(50% - 5px);
		}
		.row-right-view {
			width: calc(50% - 5px);
		}
	}
	.login-flex-1 {
		margin: 0px 7px;
		margin-top: 10px;
		width: calc(100% - 14px);
	}
	
	// banner
	.uni-margin-wrap {
			border-radius: var(--default-radio);
			overflow: hidden;
		}
		.swiper {
			border-radius: var(--default-radio);
			overflow: hidden;
			margin: 10px 0px;
			height: 180px;
		}
		.swiper-item {
			border-radius: var(--default-radio);
			overflow: hidden;
			background-color: aliceblue;
			display: block;
			height: 180px;
			// line-height: 130px;
			text-align: center;
			.banner-img {
				border-radius: var(--default-radio);
				width: 100%;
				height: 100%;
				object-fit: cover;
			}
		}
		/deep/ .wx-swiper-dots .wx-swiper-dot {
			transition: .3s all;
			height: 5px;
			width: 5px;
		}
		/deep/ .wx-swiper-dots .wx-swiper-dot-active{
			width: 10px !important;
			border-radius: 24px;
		}

		// 商品数据列表
		.home-goods-list {
			display: flex;
			justify-content: space-between;
			margin: 0 auto;
			min-height: 500px;
			.goods-item-wrap {
				
			}
			.left-goods-container,.right-goods-container {
				border-radius: var(--default-radio);
			}
			.left-goods-container {
				min-height: 100%;
			}
			.right-goods-container {
				min-height: 100%;
			}
		}
		.secend-cate-view {
			margin: 0px 7px;
			width: calc(100% - 14px);
			overflow-x: auto;
			&::-webkit-scrollbar {
				display: none;
			}
			--width: 70px;
			--cover-width: 56px;
			--row-count: 10;
			.c-cate-view {
				display: flex;
				flex-wrap: wrap;
				// width: calc(var(--width) * var(--row-count));
				overflow: hidden;
				.c-item {
					display: flex;
					flex-direction: column;
					align-items: center;
					justify-content: center;
					text-align: center;
					width: var(--width);
					height: 90px;
					font-size: 13px;
					// font-weight: 600;
					// height: var(--width);
				}
				.c-top-img {
					margin: 0 auto;
					text-align: center;
					width: var(--cover-width);
					height: var(--cover-width);
					border-radius: 12px;
					overflow: hidden;
					.c-top-image {
						width: 100%;
						height: 100%;
						object-fit: cover;
					}
				}
				.c-bottom {
					margin-top: 3px;
				}
			}
		}
		::v-deep .page-top-bar-header {
			background-color: #fff;
		}


		/* 未登录状态显示 */
		.no-login-box {
			position: relative;
			width: 100%;
			box-sizing: border-box;
			// height: 100vh;
			background-repeat: no-repeat;
			background-size: 100%;
			height: calc(100vh - env(safe-area-inset-bottom));
			background-color: #f3f4f6;
			overflow: auto;
			.no-login-tabbar {
				/* #ifdef MP-TOUTIAO */
				height: 0px;
				/* #endif */
			}
			::v-deep .page-top-bar-header {
				position: fixed;
				top: 0px;
				left: 0;
				width: 100%;
				
			}
			
			@for $index from 1 through 10 {
				@if $index==1 {
					// .swiper-#{$index} {
					// 	margin-top: 10px;
					// }
				}
				.swiper-#{$index} {
					margin-bottom: 10px;
				}
			}
			.use-login-btn {
				box-sizing: border-box;
				width: 100%;
				color: #fff;
				background-image: linear-gradient(180deg,#0fb5f9 12%,#3194f0 60%);
				border-radius: var(--default-radio);
			}
			.swiper-1 {
				
			}
			.swiper-2 {
				
			}
			
			
			.login-form {
				width: 100%;
				.login-inner {
					text-align: center;
					display: flex;
					flex-direction: column;
					justify-content: center;
					// background-color: #f4f0ed;
					.one-click-login {
						width: 100%;
						.one-click-login-title {
							margin: 80rpx auto;
							font-size: 34rpx;
							white-space: break-spaces;
							font-weight: bolder;
						}
						.one-click-logo {
							.logo {
								width: 75px;
								height: 75px;
								object-fit: cover;
								border-radius: 8px;
								border:1px solid #e2e2e2;
							}
						}
						.login-form-btns {
							width: 100%;
							margin: 0 auto;
							margin-top: 60rpx;
							.login-form-btn {
								line-height: normal;
								width: 80%;
								margin: 0 auto;
								margin-bottom: 40rpx;
								padding: 15px 0px;
								border-radius: 4px;
								font-weight: bold;
								font-size: inherit;
							}
							.access-phone-login {
								background-color: var(--primary-color);
								color: #fff;
							}
							.code-login {
								background-color: #f6f6f6;
							}
						}
					}
				}
			}
			/* 隐私协议 */
			.user-agremment-box {
				position: absolute;
				left: 50%;
				transform: translateX(-50%);
				width: max-content;
				bottom:calc(20rpx + env(safe-area-inset-bottom));
			}
		}
		::v-deep checkbox.user-agremment-box-checked .wx-checkbox-input,
			checkbox.user-agremment-box-checked .uni-checkbox-input {
				width: 18px;
				height: 18px;
				border-radius: 100%;
				border: 1px solid var(--desc-color);
			}

		::v-deep checkbox.user-agremment-box-checked[checked] .wx-checkbox-input,
			checkbox.user-agremment-box.checked .uni-checkbox-input {
				background-color: var(--primary-color) !important;
				border-color: var(--primary-color) !important;
				color: #fff !important;
			}


			.sm-mask {
				width: 100%;
				height: 100vh;
				background-color: rgba(0,0,0,.3);
				position: fixed;
				z-index: 456;
				top: 0px;
				left: 0px;
				.sm-content {
					display: flex;
					flex-direction: column;
					align-items: center;
					justify-content: center;
					width: 100%;
					height: 100%;
					.content {
						position: relative;
					}
					.sm-close {
						position: absolute;
						left: 50%;
						z-index: 457;
						transform: translateX(-50%);
						bottom: -50px;
						margin: 10px 0px;
						padding: 10px 10px;
						background-color: rgba(0,0,0,.5);
						color: #fff;
						display: flex;
						align-items: center;
						justify-content: center;
						font-size: 14px;
						border-radius: 50%;
					}

					.sm-image {
						height: 395px;
						object-fit: cover;
					}
				}
			}
			::v-deep ._swiper {
				margin: 10px 0px;
				margin-bottom: 0px;
				height: 100px !important;
				overflow: hidden;
				border-radius: 12px;
				.swiper-item {
					height: 100px !important;
				}
			}



			/* 显示地址弹窗 */
			.choose-address-model {
				box-sizing: border-box;
				// padding: 20px;
				width: 70%;
				position: fixed;
				top: 50%;
				left: 50%;
				transform: translate(-50%,-50%);
				z-index: 999999;
				background-color: #fff;
				border-radius: var(--default-radio);
				overflow: hidden;
		
				.choose-address-model-inner {
					width: 100%;
					background-color: #fff;
					.choose-address-model-top {
						width: 100%;
						box-sizing: border-box;
						padding: 10px;
						text-align: center;
						display: flex;
						position: relative;
						align-items: center;
						background: linear-gradient(180deg, #ebf4ff, #eff7ff,#fff);
						// border-bottom: 1px solid var(--primary-color);
						.choose-title {
							text-align: center;
							width: 100%;
						}
						.add {
							position: absolute;
							right: 10px;
							top: 10px;
							.close-icon {
								font-size: 22px;
								color: var(--desc-color);
							}
						}
					}
					.address-list {
						padding: 0px 10px;
						width: 100%;
						box-sizing: border-box;
						.address-item {
							box-sizing: border-box;
							padding: 14px 5px;
							border-bottom: 1px solid #f0f0f0;
							.item-top {
								color: var(--desc-color);
								width: 100%;
								overflow: hidden;
								.item-province {
									margin-right: 5px;
								}
							}
							.item-center {
								margin: 3px 0px;
								font-weight: bold;
								.item-tag {
									font-size: 12px;
									padding: 2px 3px;
									color: var(--primary-color);
									background-color: #e6f2fe;
									border-radius: 2px;
									margin-right: 3px;
								}
							}
							.item-bottom {
								color: var(--desc-color);
								font-size: 12px;
								.item-name {
									margin-top: 5px;
									margin-right: 5px;
								}
							}
						}
					}
					.address-cancel {
						width: 100%;
						box-sizing: border-box;
						padding: 10px;
						.address-cancel-btn {
							text-align: center;
							color: var(--primary-color);
							border-radius: 24px;
							font-weight: bold;
							padding: 5px;
							box-sizing: border-box;
						}
					}
				}
			}
			.preview-goods-list {
				position: relative;
				display: flex;
				justify-content: space-between;
				.preview-left-list {
					width: calc(50% - 5px);
				}
				.preview-right-list {
					width: calc(50% - 5px);
				}
				.preview-goods-list-bottom-mask {
					--bottom-height: 76px;
					position: fixed;
					bottom: calc(var(--bottom-height) + constant(safe-area-inset-bottom));
					bottom: calc(var(--bottom-height) + env(safe-area-inset-bottom));
					left: 0;
					width: 100%;
					height: 60px;
					z-index: 2;
					background: linear-gradient(to bottom, rgba(255,255,255,0) 0%, #fff);
				}
			}
			
			.global-mask {
				position: fixed;
				left: 0;
				top: 0;
				z-index: 2;
				content: "";
				width: 100vw;
				height: 100vh;
				background-color: rgba(0,0,0,.5);
				
			}
			
			.skeleton-preview-left-list {
				background-color: var(--whrite-color);
				border-radius: var(--default-radio);
			}
			
</style>


效果

image.png

image.png

分类:前端uniApp

标签:前端vue3uniapp

上一篇CSS背景图预留放置位适配下一篇开发者工具,调试 network 请求排序问题?

版权声明

本文系作者 @覃擎宇 转载请注明出处,文中若有转载的以及参考文章地址也需注明。\(^o^)/~

Preview