wx小程序前端微信小程序

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

2020-11-16  本文已影响0人  itlu

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

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
        });
    }
上一篇 下一篇

猜你喜欢

热点阅读