【前端小程序】03 - 分类页面

当返回的分类数据比较多的时候该如何处理?

1. 获取分类接口数据

  1. 获取分类接口数据,并将其拆分。
 /**
     * 页面的初始数据
     */
    data: {
        // 左侧分类数据 
        leftCatesData: [],
        // 右侧内容数据
        rightContent: []
    },

    cates: [],
 request({ url: "https://api-hmugo-web.itheima.net/api/public/v1/categories" }).then(
            result => {
                this.cates = result.data.message;
                // 构造左侧的大菜单数据 
                let leftCatesData = this.cates.map(v => v.cat_name);
                // 构造右侧的商品数据 
                let rightContent = this.cates[0].children;
                this.setData({
                    leftCatesData,
                    rightContent
                });
            }
        )

2. 编写页面结构

<!--  主体内容 开始  -->
    <view class="cates_container">
            <!--  左侧菜单 -->
            <scroll-view scroll-y="{{true}}" class="left_menu">
                <navigator class="menu_item {{index === currentIndex ? 'active':''}}"
                    wx:for="{{leftCatesData}}"
                    wx:key="*this"
                    bindtap="handleItemClick"
                    data-index="{{index}}">
                    <!-- data-index="{{index}}" 在e.currentTarget.dataset中传递索引 index -->
                    {{item}}
                </navigator>
            </scroll-view>

            <!-- 右侧内容区域 -->
            <scroll-view scroll-y="{{true}}" class="right_content">
               <view class="goods_group"
                    wx:for="{{rightContent}}"
                    wx:for-index="index1"
                    wx:for-item="item1">
                   <view class="goods_title">
                       <text class="delimiter">/</text>
                       <text class="content">{{item1.cat_name}}</text>
                       <text class="delimiter">/</text>
                   </view>

                   <view class="goods_list">
                        <navigator
                        wx:for="{{item1.children}}"
                        wx:for-index="index2"
                        wx:for-item="item2"
                        wx:key="item2.cat_id"
                        >
                            <image src="{{item2.cat_icon}}" mode="widthFix"/>
                            <view class="goods_name">{{item2.cat_name}}</view>
                        </navigator>
                   </view>
               </view>
            </scroll-view>
    </view>
<!--  主体内容 结束  -->

3. 编写样式代码

  page {
    /*  设置整个page的高度为 100%  */
    height: 100%;
}

.cates {
    height: 100%;
    .cates_container {
        display: flex;
        /*  计算 容器的内容 高度  ~'' 标记将less 原样输出到 wxss 中  100vh 代表视口 100% 的高度*/
        height: ~'calc(100vh - 90rpx)';
        .left_menu {
            flex: 2;
            .menu_item {
                height: 80rpx;
                display: flex;
                justify-content: center;
                align-content: center;
                font-size: 30rpx;
            }

            .active {
                color: var(--themeColor);
                border-left: 5rpx solid currentColor;
            }
        }
    
        .right_content {
            flex:5;
            .goods_group {
                .goods_title {
                    display: flex;
                    justify-content: center;
                    align-content: center;
                    height: 60rpx;
                    font-size: 30rpx;
                    .delimiter {
                        color: #cccccc;
                        padding: 0 20rpx;
                    }
                }

                .goods_list {
                    display: flex;
                    // 允许换行
                    flex-wrap: wrap;
                    navigator {
                        width: 33.333%;
                        text-align: center;
                        padding: 20rpx 0;
                    }

                    image {
                        width: 50%;   
                    }
                }
            }
        }
    }
}

4. 处理左侧点击与右侧联动

/**
     * 处理左侧菜单点击事件
     */
    handleItemClick(e) {
        // 解构:使用解构赋值的方式将 e.currentTarget.dataset 中的index 解构出来
        const { index } = e.currentTarget.dataset;
        // 点击左侧右侧也进行切换
        let rightContent = this.cates[index].children;
        this.setData({
            currentIndex: index,
            rightContent
        })
    },

5. 使用缓存技术优化商品分类

5.1 web 中的本地存储和小程序中的本地存储的区别

  1. web中 :localStorage.setItem("key","item") localStorage.getItem("key")

  2. 小程序中:wx.getStorageSync("key"); wx.setStorageSync("key","value")

5.2 web中本地存储和小程序中本地存储存的时候有没有做类型转换 ?

  1. web 中不管存入的数据是什么类型的数据,最终都会先调用toString() ,把数据变成了字符串在存进去。

  2. 小程序中:不存在类型转换的操作,存入什么类型的数据,获取的时候就是什么类型的数据。

5.3 实现步骤

  1. 获取本地存储中的数据,判断本地存储中是否存在旧数据?

  2. 如果不存在,发送请求重新获取。如果存在,判断数据是否过期,如果数据过期同样需要重新获取。如果以上两种情况都不满足,使用本地存储中的数据。

/**
     * 生命周期函数--监听页面加载
     */
    onLoad: function(options) {
        /**
         * -1 存的时候有没有做类型转换
         *  -1.1 web中不管存入的数据是什么类型的数据,最终都会先调用toString() ,把数据变成了字符串在存进去。
         *  -1.2 小程序中:不存在类型转换的操作,存入什么类型的数据,获取的时候就是什么类型的数据
         * 0. web中的本地存储和小程序中的本地存储的区别  
         *  0.1 web 中 : localStorage.setItem("key","item") localStorage.getItem("key")
         *  0.2 小程序中:wx.getStroageSync("key"); wx.setStroageSync("key","value")
         * 1. 先判断一下本地存储中有没有旧的数据
         * 2. 没有旧数据直接发送请求
         * 3. 有旧数据同时旧的数据没有过期,就使用本地存储中的旧数据即可
         */
        // 1. 先获取本地存储中的数据(小程序中也是存在本地存储技术的)
        const cates = wx.getStorageSync("cates");
        if (!cates) {
            // 如果不存在 则发送请求 
            this.getCates();
        } else { // 否则存在且事件未过期
            if (Date.now() - cates.time > 1000 * 10) {
                // 如果旧数据已经过期了需要重新获取 
                this.getCates();
            } else {
                this.cates = cates.data;
                // 构造左侧的大菜单数据 
                let leftCatesData = this.cates.map(v => v.cat_name);
                // 构造右侧的商品数据 
                let rightContent = this.cates[0].children;
                this.setData({
                    leftCatesData,
                    rightContent
                });
            }
        }
    },
  • 修改获取商品分类数据中的代码,添加将分类数据存储到本地存储的代码。
/**
     * 获取商品分类数据
     */
    getCates() {
        request({ url: "https://api-hmugo-web.itheima.net/api/public/v1/categories" }).then(
            result => {
                this.cates = result.data.message;
                // 发送完请求将数据存入到本地存储中  Date.now() 获取当前的事件戳
                wx.setStorageSync("cates", { time: Date.now(), data: this.cates });
                // 构造左侧的大菜单数据 
                let leftCatesData = this.cates.map(v => v.cat_name);
                // 构造右侧的商品数据 
                let rightContent = this.cates[0].children;
                this.setData({
                    leftCatesData,
                    rightContent
                });
            }
        )
    },

6. 右侧商品列表置顶

  1. 首先滑动右侧至底,点击左侧进行切换时,右侧出现未置顶显示的情况。

6.1 优化解决方案

  1. 设置 scroll-view标签的scrollTop属性为0;

7. 优化接口代码 - 提取公共接口路径

  1. 发现接口请求路径中存在公共的部分,需要将其进行抽取。
/**
 *  export 导出
 * @param {*} params 
 */
export const request = (params) => {
    // 定义公共的 url 
    const baseUrl = "https://api-hmugo-web.itheima.net/api/public/v1";
    return new Promise((resolve, reject) => {
        var reqTask = wx.request({
            // 解构出参数
            ...params,
            url: baseUrl + params.url,
            success: (result) => {
                resolve(result);
            },
            fail: (err) => {
                reject(err);
            }
        });

    })
}

8. 小程序支持es7async 语法

es7async号称是解决回调的最终⽅案。

  1. 在⼩程序的开发⼯具中,勾选es6es5语法。
勾选`es6`转`es5`语法
  1. 下载facebookregenerator库中的regenerator/packages/regenerator-runtime/runtime.js

  2. 在⼩程序⽬录下新建⽂件夹lib/runtime/runtime.js ,将代码拷⻉进去。

  3. 在每⼀个需要使⽤async语法的⻚⾯js⽂件中,都引⼊(不能全局引⼊)。

import regeneratorRuntime from "../../libs/runtime/runtime.js";
  1. 编写ES7代码:
   /**
     * 获取商品分类数据 ES7 新语法
     */
    async getCates() {
        const result = await request({ url: "/categories" });
        this.cates = result.data.message;
        // 发送完请求将数据存入到本地存储中  Date.now() 获取当前的事件戳
        wx.setStorageSync("cates", { time: Date.now(), data: this.cates });
        // 构造左侧的大菜单数据 
        let leftCatesData = this.cates.map(v => v.cat_name);
        // 构造右侧的商品数据 
        let rightContent = this.cates[0].children;
        this.setData({
            leftCatesData,
            rightContent
        });
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358

推荐阅读更多精彩内容