4 | 小程序实战之分类页面(点击菜单切换商品种类并且右侧菜单置顶 + 使用缓存技术)

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
    })
  }
  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是添加右键菜单及四个按钮的VBA代码: ``` Option Explicit '声明常量 Const MENU_NAME As String = "MyMenu" Const BUTTON1_NAME As String = "Button1" Const BUTTON2_NAME As String = "Button2" Const BUTTON3_NAME As String = "Button3" Const BUTTON4_NAME As String = "Button4" '添加右键菜单 Sub AddContextMenu() Dim cBar As CommandBar Dim cMenu As CommandBarPopup '删除已有的菜单和按钮 Call RemoveContextMenu '获取“编辑”菜单栏并添加一个弹出菜单 Set cBar = Application.CommandBars("Cell") Set cMenu = cBar.Controls.Add(Type:=msoControlPopup) cMenu.Caption = MENU_NAME '添加按钮到弹出菜单 Call AddButton(cMenu, BUTTON1_NAME, "按钮1", "ShowForm1") Call AddButton(cMenu, BUTTON2_NAME, "按钮2", "ShowForm2") Call AddButton(cMenu, BUTTON3_NAME, "按钮3", "ShowForm3") Call AddButton(cMenu, BUTTON4_NAME, "按钮4", "ShowForm4") '设置菜单置顶显示 cMenu.Protection = msoBarTop End Sub '删除右键菜单和按钮 Sub RemoveContextMenu() Dim cBar As CommandBar Dim cMenu As CommandBarPopup '获取菜单栏和菜单 On Error Resume Next Set cBar = Application.CommandBars("Cell") Set cMenu = cBar.FindControl(Type:=msoControlPopup, ID:=10) On Error GoTo 0 '删除菜单和按钮 If Not cMenu Is Nothing Then Call RemoveButton(cMenu, BUTTON1_NAME) Call RemoveButton(cMenu, BUTTON2_NAME) Call RemoveButton(cMenu, BUTTON3_NAME) Call RemoveButton(cMenu, BUTTON4_NAME) cMenu.Delete End If End Sub '添加按钮到菜单 Sub AddButton(cMenu As CommandBarPopup, sButtonName As String, sCaption As String, sMacroName As String) Dim cButton As CommandBarButton '添加按钮到菜单 Set cButton = cMenu.Controls.Add(Type:=msoControlButton) cButton.Caption = sCaption cButton.Tag = sMacroName cButton.OnAction = sMacroName cButton.BeginGroup = False cButton.FaceId = 59 cButton.Style = msoButtonIconAndCaption '设置按钮名称 cButton.Name = sButtonName End Sub '删除菜单中的按钮 Sub RemoveButton(cMenu As CommandBarPopup, sButtonName As String) Dim cButton As CommandBarButton '查找并删除按钮 On Error Resume Next Set cButton = cMenu.FindControl(Type:=msoControlButton, ID:=sButtonName) On Error GoTo 0 If Not cButton Is Nothing Then cButton.Delete End If End Sub '显示窗体1 Sub ShowForm1() UserForm1.Show End Sub '显示窗体2 Sub ShowForm2() UserForm2.Show End Sub '显示窗体3 Sub ShowForm3() UserForm3.Show End Sub '显示窗体4 Sub ShowForm4() UserForm4.Show End Sub ``` 在VBA中添加以上代码后,你需要在Excel中创建四个用户窗体(UserForm),分别命名为UserForm1、UserForm2、UserForm3和UserForm4,然后在每个用户窗体中添加需要的控件和功能。 最后,在VBA编辑器中运行AddContextMenu()子程序,即可添加右键菜单和按钮。右键单击任意单元格时,菜单将显示在顶部,并且单击每个按钮时,将显示相应的用户窗体。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值