1. 下载 HBuilderX

官网链接:https://www.dcloud.io/hbuilderx.html

2. 安装 HBuilderX

1.将在官网下载好的压缩包解压到文件夹中
2.解压完成后双击.exe文件就能打开HBuilderX

3. 首页

3.1 效果图:

在这里插入图片描述

3.2 实现代码:

数据请求:使用异步函数,在请求指定 URL 的数据后,将结果赋值给this.getSwiperList()、this.getNavList()、this.getFloordata() 变量。

export default {
		data() {
			return {
				swiperList: [],
				navList: [],
				floordata: []
			}
		},
		onLoad() {
			this.getSwiperList()
			this.getNavList()
			this.getFloordata()
		},
		methods: {
			async getSwiperList() {
				const res = await this.$Https({
					url: '/home/swiperdata'
				})
				// console.log(res);
				this.swiperList = res.message;
			},

			async getNavList() {
				const res = await this.$Https({
					url: '/home/catitems'
				})
				// console.log(res);
				this.navList = res.message;
			},

			async getFloordata() {
				const res = await this.$Https({
					url: '/home/floordata'
				})
				// console.log(res);
				this.floordata = res.message;
			}
		}
	}

3.3 页面ui结构:

<template>
	<view>
		<view class="content">
			<!-- 搜索框组件 -->
			<zujian-header></zujian-header>
		</view>
		<!-- 轮播图区域 -->
		<swiper :indicator-dots="true" :autoplay="true" :interval="3500" :duration="1000" :circular="true">
			<swiper-item v-for="(item, i) in swiperList" :key="i">
				<view class="swiper-item">
					<image :src="item.image_src"></image>
				</view>
			</swiper-item>
		</swiper>
		<!-- 导航区域 -->
		<view class="nav-list">
			<view class="nav-item" v-for="(item,i) in navList" :key='i'>
				<image :src="item.image_src" class="nav-img"></image>
			</view>
		</view>
		<!-- 楼层区域 -->
		<view class="floor-list">
			<view class="floor-item" v-for="(item, i) in floordata" :key="i">
				<image :src="item.floor_title.image_src" class="floor-title"></image>
				<view class="floor-img-box">
					<view class="left-img-box">
						<image :src="item.product_list[0].image_src"
							:style="{width: item.product_list[0].image_width + 'rpx'}" mode="widthFix"></image>
					</view>
					<view class="right-img-box">
						<view class="right-img-item" v-for="(item2, i2) in item.product_list" :key="i2" v-if="i2 !== 0">
							<image :src="item2.image_src" mode="widthFix" :style="{width: item2.image_width + 'rpx'}">
							</image>
						</view>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

4. 分类页面

4.1 效果图

在这里插入图片描述

4.2 动态渲染分类列表

4.2.1 页面左侧列表ui结构

scroll-view”:垂直滚动的视图。使用v-bind指令来绑定属性值,以实现动态更新属性。在这里,scroll-y属性被设置为true,以启用垂直滚动。"scroll-top"属性来设置视图的初始滚动位置。这个属性可以用来控制视图的滚动位置,以便用户可以直接跳转到他们感兴趣的内容。

			<view class="left-list">
				<scroll-view scroll-y="true" class="left-scroll-view" :style="{height:winh+'px'}">
					<view class="left-view" :class="index == active ? 'active' : '' " v-for="(item,index) in leftview"
						:key="index" @tap="ChangedIndex(index)">
						<text>{{item}}</text>	
					</view>
				</scroll-view>
			</view>

4.2.3 页面右侧列表ui结构

		   <scroll-view scroll-y="true" class="right-list" :style="{height:winh+'px'}" :scroll-top="scrollTop">
				<view class="right-view" v-for="(item,index) in rightview" :key="index">
					<view>
						<view><span>/</span>{{item.cat_name}}<span>/</span></view>
					</view>

					<view class="lv3-list">
						<navigator v-for="(item2,index2) in item.children" :key="index2"
							:url="'../../subpkg1/goods-list/goods-list?cid='+item2.cat_id">
							<image :src="item2.cat_icon"></image>
							<text>{{item2.cat_name}}</text>
						</navigator>
					</view>
				</view>
			</scroll-view>

4.3实现代码

1.使用生命周期函数“onLoad()”,它在页面加载时会自动执行。
2.使用“uni.getStorageSync()”方法从本地缓存中获取名为“cates”的数据,如果本地缓存中没有该数据,则执行“this.getCategories()”方法从服务器端获取数据。

onLoad() {
			const Cates = uni.getStorageSync('cates');
			if (!Cates) {
				this.getCategories();
			} else {
				if ((Date.now() - Cates.time) > 1000 * 10) {
					this.getCategories();
				} else {
					console.log('使用旧数据');
					this.categories = Cates.data;
					this.leftview = this.categories.map(e => e.cat_name)
					this.rightview = this.categories[0].children
				}
			}
		},

3.getCategories方法:这是异步方法,它使用了async和await关键字,以便在等待服务器返回数据时不会阻塞页面的渲染。向服务器发送请求,获取数据,还将数据保存到本地缓存中,以便在用户下次访问时可以直接使用缓存中的数据。如果数据保存失败,则会弹出一个提示框。

4.ChangedIndex方法:处理分类切换的方法。它接收参数index,表示用户选择的分类的索引。该方法将data中的“active”属性设置为index,以标记当前选中的分类。然后,更新data中的“rightview”属性,以显示该分类下的子分类。

methods: {
			async getCategories() {
				const res = await this.$Https({
					url: '/categories'
				})
				this.categories = res.message
				try {
					uni.setStorageSync('cates', {
						time: Data.now(),
						data: this.categories
					});
				} catch (e) {
					uni.showToast({
						tital: "数据缓存失败",
						duration: 2000
					})
				}
				this.leftview = this.categories.map(v => v.cat_name)
				this.rightview = this.categories[0].children
				// console.log(this.rightview);
			},
			ChangedIndex(index) {
				this.active = index;
				this.rightview = this.categories[index].children
				this.scrollTop = this.scrollTop === 0 ? 1 : 0
			}
		}

5. 购物车页面

5.1 效果图

在这里插入图片描述

5.2 页面ui结构

<template>
	<view>
		<view v-if="cart.length!==0">
			<zujian-address :address='address'></zujian-address>
			<view class="cart-title">
				<text class="cart-title-text">&#xe600;购物车</text>
			</view>
			<zujian-goods v-for="(item,index) in cart" :key="index" :goods='item' :showCheck='true' :showNum='true'
				:allowLongTop='true' @changeNum='changeNum' @changeChecked='changeChecked'></zujian-goods>
			<zujian-setter :cartData="cart" :showAllCheck="true" :buttonText="'结算'" @changeAllChecked="changeAllChecked">
			</zujian-setter>
		</view>
		<view v-else class="cartNull">
			<img src="../../static/none.png" alt="">
		</view>
	</view>
</template>

5.3 实现代码

  1. data属性:在组件中定义data属性,包含了默认图片链接和两个用于控制商品数量的属vshowNum和vshowNumOnly。
  2. props属性:在组件中定义props属性,用于接收父组件传递过来的数据。其中,goods属性表示商品的详细信息,showCheck属性表示是否显示选择框,showNum属性表示是否显示商品数量,allowLongTop属性表示是否允许长按删除,showNumOnly属性表示是否只显示商品数量而不显示加减按钮。
  3. methods方法:在组件中定义了一些方法,用于处理用户的操作。showNumEdit方法用于显示商品数量编辑框,gotoDetail方法用于跳转到商品详情页面,changeChecked方法用于切换商品的选中状态,numSub方法用于减少商品数量,numAdd方法用于增加商品数量,deletegoods方法用于长按删除商品。
  4. emit方法:组件中使用了emit方法来触发父组件的事件,以便将商品的选中状态和数量更新到父组件中。
	export default {
		name: "yjs-goods",
		data() {
			return {
				defaultImg: '../../static/no.gif',
				vshowNum: this.showNum,
				vshowNumOnly: this.showNumOnly
			};
		},
		props: {
			goods: {
				type: Object,
				default: null
			},
			showCheck: {
				type: Boolean,
				default: false
			},
			showNum: {
				type: Boolean,
				default: false
			},
			allowLongTop: {
				type: Boolean,
				default: false
			},
			showNumOnly: {
				type: Boolean,
				default: false
			}
		},
		methods: {
			showNumEdit() {
				this.vshowNum = true;
				this.vshowNumOnly = false;
			},
			gotoDetail() {
				uni.navigateTo({
					url: '../../subpkg1/goods-detail/goods-detail?goods_id=' + this.goods.goods_id
				})
			},
			changeChecked() {
				this.$emit('changeChecked', {
					goods_id: this.goods.goods_id,
					checked: !this.goods.checked
				})
			},
			numSub() {
				if (this.goods.cartNum > 1) {
					this.$emit('changeNum', {
						goods_id: this.goods.goods_id,
						cartNum: this.goods.cartNum - 1
					});
				}
			},
			numAdd() {
				this.$emit('changeNum', {
					goods_id: this.goods.goods_id,
					cartNum: this.goods.cartNum + 1,
				})
			},
			//长按删除
			deletegoods() {
				if (this.allowLongTop) {
					uni.showModal({
						title: '删除',
						content: '是否删除此商品',
						success: (res) => {
							if (res.confirm) {
								this.$emit('changeNum', {
									goods_id: this.goods.goods_id,
									cartNum: 0
								});
							}
						}
					})
				}
			}
		}
	}

6.我的页面

6.1 效果图

在这里插入图片描述

6.2 页面ui结构

<template>
	<view>
		<view class="my-userinfo-container" :style="{height:winh+'px'}">
			<view class="top-box">
				<img :src="userInfo.avatarUrl" alt="" style="width: 90px;height: 90px; border-radius: 50%;">
				<view class="nickname">{{userInfo.nickName}}</view>
			</view>
			<view class="panel-list">
				<view class="panel">
					<view class="panel-body">
						<view class="panel-item" v-for="(item,index) in Feet" :key="item.id">
							<text>{{item.num}}</text>
							<text>{{item.text}}</text>
						</view>
					</view>
				</view>
				<view class="panel">
					<view class="panel-title">我的订单</view>
					<view class="panel-body">
						<view class="panel-item" v-for="(item,index) in FeetTow" :key="item.id"
							@click="gotoOrder(index)">
							<i :style="{ fontFamily: 'iconfont' }" v-html="item.icon"
								style="font-size: 25px; color:var(--blue); font-weight: 600;"></i>
							<text>{{item.text}}</text>
						</view>
					</view>
				</view>
				<view class="panel">
					<view class="panel-list-item but">
						<text>收货地址管理</text>
						<uni-icons type="arrowright" size="15"></uni-icons>
					</view>
					<view class="panel-list-item">
						<text>联系客服</text>
						<text>400-123-654</text>
					</view>
					<view class="panel-list-item">
						<text>意见反馈</text>
						<uni-icons type="arrowright" size="15"></uni-icons>
					</view>
					<view class="panel-list-item">
						<text @click="gotoOrder">关于我们</text>
						<uni-icons type="arrowright" size="15"></uni-icons>
					</view>
				</view>
				<button class="btn-login" @click="logout">退出登录</button>
			</view>
		</view>
	</view>
</template>

6.3 实现代码

  1. 使用“uni.getStorageSync()”方法从本地缓存中获取“userInfo”的数据,将其保存在data的“userInfo”属性中。这个数据包含了用户的基本信息,如用户名、头像等。
  2. 使用“uni.getStorageSync()”方法从本地缓存中获取名为“token”的数据,将其保存在data的“token”属性中。用于验证用户的身份,以便在用户进行一些敏感操作时进行权限验证。
  3. 如果本地缓存中没有“token”数据,则将当前页面的标识保存在本地缓存中,使用“uni.reLaunch()”方法跳转到登录页面。
  4. methods方法中定义了两个方法,其中logout方法用于实现用户退出登录的功能。它使用“uni.showModal()”方法弹出一个模态框,询问用户是否确认退出登录。如果用户确认退出,则使用“uni.removeStorageSync()”方法从本地缓存中移除“token”、“address”和“userinfo”数据,并使用“uni.redirectTo()”方法跳转到登录页面。
  5. gotoOrder方法用于跳转到订单页面,如果订单数量为0,则跳转到订单页面,并将订单数量作为参数传递给订单页面。
data() {
			return {
				winh: 0,
				token: '',
				userInfo: {},
				
				Feet: 
				[
				{id: 0,num: 0,text: '收藏的店铺'}, 
				{id: 1,num: 0,text: '收藏的商品'}, 
				{id: 2,num: 0,text: '关注的商品'}, 
				{id: 3,num: 0,text: '我的足迹'},
				],
				
				FeetTow: 
				[
				{id: 0,icon: '&#xe897;',text: '全部订单'}, 
				{id: 1,icon: '&#xe61e;',text: '待付款'}, 
				{id: 2,icon: '&#xe69e;',text: '待收货'},
				{id: 3,icon: '&#xe62c;',text: '退款/退货'},
				]
			}
		 }
	  },
		onShow() {
			this.userInfo = uni.getStorageSync('userInfo');
			// console.log(this.userInfo);
			this.token = uni.getStorageSync('token');
			if (!this.token) {
				uni.setStorageSync('page', 'user')
				uni.reLaunch({
					url: '../../subpkg2/login/login'
				})
			}
		},
		methods: {
			async logout() {
				const result = await uni.showModal({
					title: '提示',
					content: '确认退出登录吗'
				});
				const {
					err = null, confirm: succ = false
				} = result || {};
				if (succ) {
					uni.removeStorageSync('token');
					uni.removeStorageSync('address');
					uni.removeStorageSync('userinfo');

					uni.redirectTo({
						url: '../../subpkg2/login/login'
					});
				}
			},
			gotoOrder(num) {
				if (num == 0) {
					uni.navigateTo({
						url: '../../subpkg2/order/order?num=' + num
					})
				}
			}
		}
	}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐