4 | 小程序实战之分类页面(点击菜单切换商品种类并且右侧菜单置顶 + 使用缓存技术)
1. 效果2. 分析接口数据3. 获取分类页面的数据接口https://api-hmugo-web.itheima.net/api/public/v1/categories4. 调用接口(1)为了方便演示,添加一个编译模式(2)现在分类页面的index.js文件中创建三个空数组index.jsdata: {// 左侧的菜单数据leftMenuList: [],// 右侧的商品数据rightCont
1. 效果
2. 分析接口数据
3. 获取分类页面的数据接口
https://api-hmugo-web.itheima.net/api/public/v1/categories
4. 调用接口
(1)为了方便演示,添加一个编译模式
(2)现在分类页面的index.js文件中创建三个空数组
index.js
data: {
// 左侧的菜单数据
leftMenuList: [],
// 右侧的商品数据
rightContent: []
},
// 为了方便使用数据,在data同层级下创建Cates空数组接收接口返回的数据
Cates: [],
(3)发送异步请求给三个空数组赋值
index.js
// 引入用来发送请求的方法 一定要把路径补全
import {request} from "../../request/index.js"
Page({
/**
* 页面的初始数据
*/
data: {
// 左侧的菜单数据
leftMenuList: [],
// 右侧的商品数据
rightContent: []
},
// 为了方便使用数据,在data同层级下创建Cates空数组接收接口返回的数据
Cates: [],
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getCates();
},
// 获取轮播图数据
getCates(){
request({url: 'https://api-hmugo-web.itheima.net/api/public/v1/categories'})
.then(res=>{
this.Cates = res.data.message;
// 构造左侧的大菜单数据
let leftMenuList = this.Cates.map(v=>v.cat_name);
// 构造右侧的大菜单数据
let rightContent = this.Cates[0].children;
this.setData({
leftMenuList,
rightContent
})
})
},
})
5. 页面布局
index.wxml
<view class="cates">
<!-- 搜索框开始 -->
<SearchInput></SearchInput>
<!-- 搜索框结束 -->
<view class="cates_container">
<!-- 左侧的菜单数据开始 -->
<scroll-view scroll-y class="left_menu">
<!-- *this指的是for循环中item本身 -->
<!-- 注意:要在index.js 先写死 currentIndex:0 -->
<view
class="menu_item {{index===currentIndex?'active':''}}"
wx:for="{{leftMenuList}}"
wx:key="*this"
>
<view>
{{item}}
</view>
</view>
</scroll-view>
<!-- 左侧的菜单数据结束 -->
<!-- 右侧的菜单数据开始 -->
<scroll-view scroll-y class="right_content">
<!-- 由于 goods_group中没有什么是唯一的属性所以-->
<view
class="goods_group"
wx:for="{{rightContent}}"
wx:key="*this"
wx:for-index="index1"
wx:for-item="item1"
>
<view class="goods_title">
<text class="delimeter">/</text>
<text class="title">{{item1.cat_name}}</text>
<text class="delimeter">/</text>
</view>
<view class="goods_list">
<navigator
wx:for="{{item1.children}}"
wx:for-item="item2"
wx:for-index="index2"
wx:key="cat_id"
>
<image mode="widthFix" src="{{item2.cat_icon}}" />
<view class="goods_name">{{item2.cat_name}}</view>
</navigator>
</view>
</view>
</scroll-view>
<!-- 右侧的菜单数据结束 -->
</view>
</view>
index.less
page{
// 先设置父页面高度
height: 100%;
}
.cates{
// 继承父页面高度
height: 100%;
.cates_container{
// less中使用calc的时候要使用 ~ 包裹
height: ~'calc( 100vh - 90rpx )';
display: flex;
.left_menu{
// 因为现在是伸缩盒子的子项 有默认高度 100%
flex: 2;
.menu_item{
display: flex;
height: 80rpx;
justify-content: center;
align-items: center;
font-size: 30rpx;
}
.active{
color: var(--themeColor);
border-left: 5rpx solid currentColor;
}
}
.right_content{
// 因为现在是伸缩盒子的子项 有默认高度 100%
flex: 5;
.goods_group{
.goods_title{
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
.delimeter{
color: #ccc;
padding: 0 10rpx;
}
.title{}
}
.goods_list{
display: flex;
// 允许换行
flex-wrap: wrap;
navigator{
width: 33.33%;
// 文字图片居中对齐
text-align: center;
image{
width: 50%;
}
}
.goods_name{
}
}
}
}
}
}
app.wxss
image{
/* 定义所有图片的宽度格式 */
width: 100%;
}
6. 点击菜单可切换商品种类
修改左侧菜单的页面布局
<!-- 左侧的菜单数据开始 -->
<scroll-view scroll-y class="left_menu">
<!-- *this指的是for循环中item本身 -->
<view
class="menu_item {{index===currentIndex?'active':''}}"
wx:for="{{leftMenuList}}"
wx:key="*this"
bindtap="handleItemTap"
data-index="{{index}}"
>
<view>
{{item}}
</view>
</view>
</scroll-view>
<!-- 左侧的菜单数据结束 -->
添加点击事件的行为
index.js
// 引入用来发送请求的方法 一定要把路径补全
import {request} from "../../request/index.js"
Page({
/**
* 页面的初始数据
*/
data: {
// 左侧的菜单数据
leftMenuList: [],
// 右侧的商品数据
rightContent: [],
currentIndex: 0
},
// 为了方便使用数据,在data同层级下创建Cates空数组接收接口返回的数据
Cates: [],
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.request({
url: 'url',
})
this.getCates();
},
// 获取轮播图数据
getCates(){
request({url: 'https://api-hmugo-web.itheima.net/api/public/v1/categories'})
.then(res=>{
this.Cates = res.data.message;
// 构造左侧的大菜单数据
let leftMenuList = this.Cates.map(v=>v.cat_name);
// 构造右侧的大菜单数据
let rightContent = this.Cates[0].children;
this.setData({
leftMenuList,
rightContent
})
})
},
//左侧菜单点击事件
handleItemTap(e){
/*
1 获取被点击的标题身上的索引
2 给data中的currentIndex赋值就可以了
3 根据不同的索引来渲染右侧的商品内容
*/
const {index} = e.currentTarget.dataset;
let rightContent = this.Cates[index].children;
this.setData({
currentIndex:index,
rightContent
})
}
})
7. 使用缓存技术
思路:在打开页面的时候,先做一个判断,判断本地储存中有没有旧的数据,如果没有的话,就发送请求获取这个数据,假如说有旧的数据,并且这个数据没有过期,那么此时就可以使用本地储存中旧的数据了。所以说,我们需要解决的是怎么去存数据 和 怎么去拿数据 !
index.js
// 引入用来发送请求的方法 一定要把路径补全
import {request} from "../../request/index.js"
Page({
/**
* 页面的初始数据
*/
data: {
// 左侧的菜单数据
leftMenuList: [],
// 右侧的商品数据
rightContent: [],
currentIndex: 0
},
// 为了方便使用数据,在data同层级下创建Cates空数组接收接口返回的数据
Cates: [],
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
/*
1 先判断一下本地存储中有没有旧的数据
{time:Date.now(),data:[...]}
2 没有旧数据 直接发送新请求
3 有旧的数据 同时 旧的数据也没有过期 就使用 本地存储中的旧数据即可
*/
// 1 获取本地存储中的数据 (小程序中也是存在本地存储 技术)
const Cates = wx.getStorageSync('cates');
// 2 判断
if(!Cates){
// 不存在 发送请求获取数据
this.getCates();
}else{
// 有旧的数据 定义过期时间5分钟 1000ms = 1s
if(Date.now()-Cates.time>1000*300){
// 重新发送请求
this.getCates();
}else{
this.Cates = Cates.data;
// 构造左侧的大菜单数据
let leftMenuList = this.Cates.map(v=>v.cat_name);
// 构造右侧的大菜单数据
let rightContent = this.Cates[0].children;
this.setData({
leftMenuList,
rightContent
})
}
}
},
// 获取轮播图数据
getCates(){
request({url: 'https://api-hmugo-web.itheima.net/api/public/v1/categories'})
.then(res=>{
this.Cates = res.data.message;
// 把接口的数据存入到本地存储中
wx.setStorageSync("cates", { time: Date.now(), data: this.Cates });
// 构造左侧的大菜单数据
let leftMenuList = this.Cates.map(v=>v.cat_name);
// 构造右侧的大菜单数据
let rightContent = this.Cates[0].children;
this.setData({
leftMenuList,
rightContent
})
})
},
//左侧菜单点击事件
handleItemTap(e){
/*
1 获取被点击的标题身上的索引
2 给data中的currentIndex赋值就可以了
3 根据不同的索引来渲染右侧的商品内容
*/
const {index} = e.currentTarget.dataset;
let rightContent = this.Cates[index].children;
this.setData({
currentIndex:index,
rightContent
})
}
})
疑惑:web和小程序本地存储的区别
1 写代码的方式不一样了
web: localStorage.setItem(“key”,“value”) localStorage.getItem(“key”)
小程序中: wx.setStorageSync(“key”, “value”); wx.getStorageSync(“key”);
2 存的时候 有没有做类型转换
web: 不管存入的是什么类型的数据,最终都会先调用一下 toString(),把数据变成了字符串 再存入进去
小程序: 不存在 类型转换的这个操作 存什么类似的数据进去,获取的时候就是什么类型
8. 点击菜单-右侧列表置顶
如果你跟着我敲的话,你会发现当你点击一个菜单后,右侧列表往下拉,再点击另一个菜单,你会发现右侧列表没有置顶,那么怎么做呢?👇👇👇
思路:在右侧的菜单数据的 scroll-view 标签中增加 scroll-top 属性设置竖向滚动条位置,但这标签不能写死,如 scroll-top=“0”,因为这对于触发点击事件无效,你得设置一个变量,当点击左边菜单时,对这个变量赋值
index.wxml
<!-- 右侧的菜单数据开始 -->
<scroll-view
scroll-y
class="right_content"
scroll-top="{{scrollTop}}"
>
。。。
<scroll-view/>
index.js
data: {
// 左侧的菜单数据
leftMenuList: [],
// 右侧的商品数据
rightContent: [],
currentIndex: 0,
scrollTop:0
},
。。。
// 左侧菜单的点击事件
handleItemTap(e) {
/*
1 获取被点击的标题身上的索引
2 给data中的currentIndex赋值就可以了
3 根据不同的索引来渲染右侧的商品内容
*/
const { index } = e.currentTarget.dataset;
let rightContent = this.Cates[index].children;
this.setData({
currentIndex: index,
rightContent,
// 重新设置 右侧内容的scroll-view标签的距离顶部的距离
scrollTop: 0
})
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)