赞
踩
// pages/category/index.js import { request } from "../../request/index.js" Page({ /** * 页面的初始数据 */ data: { //左侧菜单数据 leftMenuList: [], //右侧的商品数据 rightContent: [], // 被点击的左侧菜单 currentIndex: 0, //右侧距离顶部距离 scrollTop:0, }, //接口返回数据 Cates: [], /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { /** * 1,先判断本地储存中有没有旧的缓存数据 * 本地存储数据格式: * {time.Data.now(),data:[.....]} * 2,没有数据就发送请求, * 3,有旧数据且旧数据没有过期,直接使用本地储存中的旧数据 */ const Cates = wx.getStorageSync("cates"); if (!Cates) { //不存在,获取数据 this.getCates(); } else { //本地有缓存 if (Date.now() - Cates.time > 1000 * 10) { //超过10s就重新发送请求 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: "/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, //设置右侧距离顶部距离 scrollTop:0, }); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { } })
{
"usingComponents": {
"SearchInput":"../../components/SearchInput/SearchInput"
},
"navigationBarTitleText": "商品分类"
}
vscode的easyless插件会自动生成index.wxss
/* pages/category/index.wxss */ page { height: 100%; } .cates { height: 100%; .cates_container { // less中使用calc注意 height: ~'calc(100vh - 90rpx)'; display: flex; .left_menu { flex: 2; .menu_item { height: 80rpx; display: flex; justify-content: center; align-items: center; font-size: 30rpx; } .active { color: var(--themeColor); border-left: 5rpx solid currentColor; } } .right_content { flex: 5; .good_group { .good_title { height: 80rpx; display: flex; justify-content: center; align-items: center; .delimiter { color: #cccccc; padding: 0 10rpx; } .title {} } .good_list { display: flex; flex-wrap: wrap; navigator { width: 33.33%; text-align: center; image { width: 50%; } .goods_name {} } } } } } }
<view class="cates"> <SearchInput></SearchInput> <view class="cates_container"> <!-- 左侧菜单 --> <scroll-view scroll-y="{{true}}" class="left_menu"> <view class="menu_item {{index===currentIndex?'active':''}}" wx:for="{{leftMenuList}}" wx:key="*this" bindtap="handleItemTap" data-index="{{index}}" > {{item}} </view> </scroll-view> <!-- 右侧菜单 --> <scroll-view scroll-top="{{scrollTop}}" scroll-y="{{true}}" class="right_content"> <view class="good_group" wx:for="{{rightContent}}" wx:for-index="index1" wx:for-item="item1" > <view class="good_title"> <text class="delimiter">/</text> <text class="title">{{item1.cat_name}}</text> <text class="delimiter">/</text> </view> <view class="good_list"> <navigator class="" target="" url="/pages/goods_list/index?cid={{item2.cat_id}}" hover-class="navigator-hover" open-type="navigate" wx:for="{{item1.children}}" wx:for-index="index2" wx:for-item="item2" wx:key="cat_id" > <image class="" src="{{item2.cat_icon}}" mode="widthFix" lazy-load="false" binderror="" bindload="" /> <view class="goods_name">{{item2.cat_name}}</view> </navigator> </view> </view> </scroll-view> </view> </view>
主要是布局文件index.less的编写,注意less语法。
商品列表页功能:支持上拉加载更多,下拉刷新等
// pages/goods_list/index.js import { request } from "../../request/index.js" Page({ /** * 页面的初始数据 */ data: { tabs: [{ id: 0, value: "综合", isActive: true, }, { id: 1, value: "销量", isActive: false, }, { id: 0, value: "价格", isActive: false, }, ], //商品列表数据 goodsList: [], }, //接口要的参数 QueryParams: { query: "", cid: "", pagenum: 1, pagesize: 10 }, //总页数 totalPages: 1, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.QueryParams.cid = options.cid; this.getGoodsList(); }, //获取商品列表页数据 getGoodsList() { request({ url: "/goods/search", data: this.QueryParams, }).then(res => { //console.log(res); //数据总条数 const total = res.data.message.total; //计算总页数 this.totalPages = Math.ceil(total/this.QueryParams.pagesize); //console.log(this.totalPages); this.setData({ goodsList:[...this.data.goodsList,... res.data.message.goods], }); //手动关闭下拉刷新界面,首次进入也不会报错,无需处理 wx.stopPullDownRefresh(); }) }, //标题点击事件 从子组件Tabs传递过来的 handleTabsItemChange(e) { //获取被点击的标题索引 const { index } = e.detail; //修改源数组 let { tabs } = this.data; tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false); //赋值到data中 this.setData({ tabs }); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { //console.log('下拉了'); //重置数组 this.setData({ goodsList:[], }); //重置页码 this.QueryParams.pagenum=1; //重新发送请求 this.getGoodsList(); }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { //console.log('页面触底了~~'); //判断还有没有下一页数据 if(this.QueryParams.pagenum>=this.totalPages){ //没有下一页数据了 wx.showToast({ title: '没有更多数据了', }); }else{ this.QueryParams.pagenum++; this.getGoodsList(); } }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { } })
{
"usingComponents": {
"SearchInput":"../../components/SearchInput/SearchInput",
"Tabs":"../../components/Tabs/Tabs"
},
"navigationBarTitleText": "商品列表页",
"enablePullDownRefresh": true,
"backgroundTextStyle": "dark"
}
/* pages/goods_list/index.wxss */ .first_tab { .goods_item { display: flex; border-bottom: 1px solid #cccccc; .goods_img_wrap { flex: 2; display: flex; justify-content: center; align-items: center; image { width: 70%; } } .goods_info_wrap { flex: 3; display: flex; flex-direction: column; justify-content: space-around; .goods_name { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; } .goods_price { color: var(--themeColor); font-size: 32rpx; } } } }
<SearchInput></SearchInput> <!-- 监听自定义事件 --> <Tabs tabs="{{tabs}}" bindtabsItemChange="handleTabsItemChange"> <block wx:if="{{tabs[0].isActive}}"> <view class="first_tab"> <navigator class="goods_item" wx:for="{{goodsList}}" wx:key="goods_id" > <!-- 左侧的图片容器 --> <view class="goods_img_wrap"> <image class="" src="{{item.goods_small_logo}}" mode="widthFix" lazy-load="false" binderror="" bindload="" /> </view> <!-- 右边的商品信息 --> <view class="goods_info_wrap"> <view class="goods_name">{{item.goods_name}}</view> <view class="goods_price">¥{{item.goods_price}}</view> </view> </navigator> </view> </block> <block wx:elif="{{tabs[1].isActive}}">1</block> <block wx:elif="{{tabs[2].isActive}}">2</block> </Tabs>
// components/Tabs/Tabs.js Component({ /** * 组件的属性列表 */ properties: { //接收父组件的传值 tabs:{ type:Array, value:[], } }, /** * 组件的初始数据 */ data: { }, /** * 组件的方法列表 */ methods: { handleItemTap(e){ //获取点击索引 const {index} = e.currentTarget.dataset; //触发父组件的事件 this.triggerEvent("tabsItemChange",{index}) }, } })
.tabs{ .tabs_title{ display: flex; .title_item{ display: flex; padding: 15rpx 0; justify-content: center; align-items: center; flex: 1; } } .tabs_content{} } .active{ color: var(--themeColor); border-bottom: 5rpx solid currentColor; }
<view class="tabs">
<view class="tabs_title">
<view class="title_item {{item.isActive?'active':''}}" wx:for="{{tabs}}" wx:key="id" bindtap="handleItemTap" data-index="{{index}}">
{{item.value}}
</view>
</view>
<view class="tabs_content">
<slot></slot>
</view>
</view>
1,父组件(商品列表页)和子组件(Tabs组件)相互传递数据问题
2,上拉加载更多、下拉刷新实现的逻辑
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。