优购项目准备
首页
配置顶部文字和样式
封装搜索组件
这不是一个真正可以输入的搜索框, 仅仅是样式而已
<template>
<view class="searchBox">
<view class="input">搜索</view>
</view>
</template>
<script>
export default {};
</script>
<style lang="scss" scoped>
.searchBox {
height: 100rpx;
background-color: #eb4450;
display: flex;
justify-content: center;
align-items: center;
.input {
width: 700rpx;
height: 80rpx;
line-height: 80rpx;
background-color: #fff;
border-radius: 5rpx;
color: #767676;
font-size: 32rpx;
text-align: center;
}
}
</style>
轮播图
分类导航
异步请求封装说明
其实使用的是 uview 组件库为我们封装的函数 $u.get
然后进行全局设定
分类页
静态左右布局
左右独立滚动
<template>
<view class="page">
<!-- 搜索 -->
<YgSearch />
<!-- 主要内容 -->
<view class="catBox">
<view class="left">
<view class="leftItem">6666</view>
<view class="leftItem">6666</view>
<view class="leftItem">6666</view>
<view class="leftItem">6666</view>
</view>
<view class="right">
<view class="rightItem">999</view>
<view class="rightItem">999</view>
<view class="rightItem">999</view>
<view class="rightItem">999</view>
<view class="rightItem">999</view>
<view class="rightItem">999</view>
<view class="rightItem">999</view>
<view class="rightItem">999</view>
</view>
</view>
</view>
</template>
<script>
export default {};
</script>
<style lang="scss" scoped>
.page {
display: flex;
flex-direction: column;
height: 100vh;
.catBox {
width: 100%;
flex: 1;
display: flex;
overflow: hidden;
.left {
width: 182rpx;
overflow: auto;
}
.right {
flex: 1;
overflow: auto;
}
}
}
</style>
获取数据
左侧第一层菜单
右侧二级菜单独立组件
<template>
<view>
<view class="mainTitle"> / {{data.cat_name}} / </view>
<view class="list">
<!-- 这里再次遍历就是第三层的具体分类了 -->
<view class="item" v-for="item in data.children" :key="item.cat_id">
<image
class="img"
:src="item.cat_icon"
mode="scaleToFill"
/>
<view class="title">
{{item.cat_name}}
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
data: {
type: Object,
required: true
}
}
}
</script>
<style lang="scss" scoped>
.mainTitle {
font-size: 26rpx;
color: #575757;
text-align: center;
margin-top: 50rpx;
}
.list {
display: flex;
flex-wrap: wrap;
.item {
width: 33.33%;
text-align: center;
.img {
width: 120rpx;
height: 120rpx;
}
}
}
</style>
点击切换分类
切换时没有退回顶部的bug
渲染优化
原理
- 小程序底层的 setData 应该只包含必要的数据, 不然可能影响渲染性能
- uniapp 当中 绑定在 data 当中的数据 其实都出发了 setData
- 所以不是非要渲染的内容, 应该尽可能不要放入 data 当中
商品列表页
创建页面跳转并传参
tabs uViewUi 版
商品列表页
数据获取
以下代码只包含必要部分
export default {
components: {Tabs},
data() {
return {
prodList: []
}
},
onLoad(options) {
// 定好发送请求的参数
this.pageConfig = {
// 本来应该是跳转时传入id
// 但是测试的时候由于没有跳转, 可以设定一个默认值
cid: options.cat_id || 5,
pagenum: 1,
pagesize: 10
}
// 真正发送请求
this.loadPage()
},
methods: {
async loadPage() {
const {message} = await this.$u.get('/goods/search', this.pageConfig)
this.prodList = message.goods
}
}
}
布局渲染
滚动到底加载下一页
下拉刷新
商品详情页
创建页面带上id跳转
获取数据
显示轮播图
点击显示轮播图预览
价格和标题之类的主要信息
商品详情
底部工具条布局
办法一直接参考模板
办法二手写
封装储存购物车数据和添加的功能
商品详情底部购物车数量
数据持久化
js 普通数据赋值, 其实刷新就会重置
数据持久化其实逻辑就是两个
- 数据发生变化, 存起来做备份 (存在刷新都不会丢失的本地储存当中)
- 每当页面刷新, 优先使用本地数据
产品选中状态切换
更改产品数量
如果数量等于一,再次点击二次询问
删除商品
购物车续
底部布局和样式
.submitBar {
position: fixed;
bottom: 0;
left: 0;
background-color: #fff;
border-top: 1rpx solid #ddd;
width: 100%;
height: 83rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 23rpx;
.priceBox {
flex: 1;
font-size: 26rpx;
color: #292929;
.price {
color: #eb4450;
font-size: 28rpx;
margin-left: 6rpx;
}
}
.btn {
padding: 0 26rpx;
line-height: 52rpx;
background-color: #eb4450;
color: #fff;
border-radius: 26rpx;
}
}
底部数据渲染
辅助函数简化
全选功能
被动显示
主动变更
主动变更简化写法
空状态优化
没有商品时, 全选状态应为 false
默认显示空状态图标
数据持久化统一封装
结算页
创建页面配置路由和跳转
地址基本布局
获取地址信息
注意有可能包隐私权限错误, 可以通过修改 manifest.json
产品渲染
.list {
background: #fff;
padding-bottom: 100rpx;
.mainTitle{
font-size: 26rpx;
color: #434343;
padding: 26rpx;
}
.item {
display: flex;
.img {
width: 191rpx;
height: 191rpx;
}
.info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 16rpx;
.bottom {
display: flex;
justify-content: space-between;
.price {
color: #eb4450;
}
}
}
}
}
底部工具栏
<view class="submitBar">
<view class="price">合计 <text class="number">¥{{totalPrice}}</text></view>
<view class="btn" :class="{disable: !address}">去支付({{totalType}})</view>
</view>
.submitBar {
border-top: 1rpx solid #ccc;
position: fixed;
background-color: #fff;
bottom: 0;
left: 0;
width: 100%;
height: 83rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 28rpx;
.price {
.number {
color: #eb4450;
margin-left: 20rpx;
}
}
.btn {
color: #fff;
background-color: #eb4450;
line-height: 52rpx;
padding: 0 26rpx;
border-radius: 26rpx;
font-size: 24rpx;
}
.disable {
background-color: #888;
}
}