【愚公系列】2022年11月 微信小程序-优购电商项目-商品分类

举报
愚公搬代码 发表于 2022/11/29 20:32:54 2022/11/29
【摘要】 前言商品分类是指根据一定的管理目的,为满足商品生产、流通、消费活动的全部或部分需要,将管理范围内的商品集合总体,以所选择的适当的商品基本特征作为分类标志,逐次归纳为若干个范围更小、特质更趋一致的子集合体(类目),例如大类、中类、小类、细类,直至品种、细目等,从而使该范围内所有商品得以明确区分与体系化的过程。商品种类繁多,据不完全统计,在市场上流通的商品有25万种以上。为了方便消费者购买,有...

前言

商品分类是指根据一定的管理目的,为满足商品生产、流通、消费活动的全部或部分需要,将管理范围内的商品集合总体,以所选择的适当的商品基本特征作为分类标志,逐次归纳为若干个范围更小、特质更趋一致的子集合体(类目),例如大类、中类、小类、细类,直至品种、细目等,从而使该范围内所有商品得以明确区分与体系化的过程。

商品种类繁多,据不完全统计,在市场上流通的商品有25万种以上。为了方便消费者购买,有利于商业部门组织商品流通,提高企业经营管理水平,须对众多的商品进行科学分类。商品分类是指为了一定目的,选择适当的分类标志,将商品集合总体科学地、系统地逐级划分为门类、大类、中类、小类、品类以至品种、花色、规格的过程称为商品分类。

对于电商的商品分类主要有两种方法:

一是按照消费者的需求及特征划分,如按消费者的衣、食、住、用、行划分,有食品类、服装类、鞋帽类、日用品类、家具类、家用电器类、纺织品类、‘五金电料类、厨具类等;按照消费者的需要层次划分,有基本生活品类、享受品类和发展品类等;按照消费者购买行为划分,有日用品类、选购品类和特殊品类;按照消费者的年龄和性别分有老年人用品类、中年用品类、青年用品类、儿童及婴儿用品类;女士用品类、男士用品类等。

二是按照商场经营管理商品的角度划分,如按经营重要程度划分,可分为主营商品、一般商品类和辅助商品类。主营商品类在销售额中占主要比重,反映商场的经营特色,是商场的利润的主要来源;一般商品类是为了配合主营商品的销售,满足顾客的连带需要、例外需要的商品,在销售额中的比重较低;辅助商品类是商场为了吸引顾客,提高商场规格,促进主营商品类和一般商品类的销售,在销售额中占有的比重最低;按商品销售的顺畅程度划分,有畅销商品类、平销商品类、滞销商品类和冷背商品类;按商品质量及价格划分,有高档商品类、中档商品类和低档商品类。这种划分有利于商场的经营管理。

以上内容来源于百度百科。

一、商品分类

1.业务逻辑

  1. 加载分类⻚⾯数据
  2. 点击左侧菜单,右侧数据动态渲染

2.涉及的接口数据

  1. 分类⻚⾯数据
"message": [
    {
        "cat_id": 1, 
        "cat_name": "大家电", 
        "cat_pid": 0, 
        "cat_level": 0, 
        "cat_deleted": false, 
        "cat_icon": "/full/none.jpg", 
        "children": []
    }, 
]

在这里插入图片描述

3. 关键技术

  • scroll–view 组件
  • es7的 async 和 await

es7的 async 号称是解决回调的最终⽅案

  1. 在⼩程序的开发⼯具中,勾选 es6转es5语法
  2. 下载 facebook的regenerator库中的 regenerator/packages/regenerator-runtime/runtime.js
  3. 在⼩程序⽬录下新建⽂件夹 lib/runtime/runtime.js ,将代码拷⻉进去
  4. 在每⼀个需要使⽤async语法的⻚⾯js⽂件中,都引⼊(不能全局引⼊)
import regeneratorRuntime from '../../lib/runtime/runtime'

二、商品分类代码

1.相关代码

import { request } from "../../request/index.js";
import regeneratorRuntime from '../../lib/runtime/runtime';
Page({
  data: {
    // 左侧的菜单数据
    leftMenuList: [],
    // 右侧的商品数据
    rightContent: [],
    // 被点击的左侧的菜单
    currentIndex: 0,
    // 右侧内容的滚动条距离顶部的距离
    scrollTop: 0
  },
  // 接口的返回数据
  Cates: [],

  onLoad: function (options) {
    /* 
    0 web中的本地存储和 小程序中的本地存储的区别
      1 写代码的方式不一样了 
        web: localStorage.setItem("key","value") localStorage.getItem("key")
    小程序中: wx.setStorageSync("key", "value"); wx.getStorageSync("key");
      2:存的时候 有没有做类型转换
        web: 不管存入的是什么类型的数据,最终都会先调用以下 toString(),把数据变成了字符串 再存入进去
      小程序: 不存在 类型转换的这个操作 存什么类似的数据进去,获取的时候就是什么类型
    1 先判断一下本地存储中有没有旧的数据
      {time:Date.now(),data:[...]}
    2 没有旧数据 直接发送新请求 
    3 有旧的数据 同时 旧的数据也没有过期 就使用 本地存储中的旧数据即可
     */

    //  1 获取本地存储中的数据  (小程序中也是存在本地存储 技术)
    const Cates = wx.getStorageSync("cates");
    // 2 判断
    if (!Cates) {
      // 不存在  发送请求获取数据
      this.getCates();
    } else {
      // 有旧的数据 定义过期时间  10s 改成 5分钟
      if (Date.now() - Cates.time > 1000 * 10) {
        // 重新发送请求
        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
        })
      }
    }

  },
  // 获取分类数据
  async 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
    //     })
    //   })

    // 1 使用es7的async await来发送请求
    const res = await request({ url: "/categories" });
    // this.Cates = res.data.message;
    this.Cates = res;
    // 把接口的数据存入到本地存储中
    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,
      // 重新设置 右侧内容的scroll-view标签的距离顶部的距离
      scrollTop: 0
    })

  }
})
<view class="cates">
  <SearchInput></SearchInput>
  <view class="cates_container">
    <!-- 左侧菜单 -->
    <scroll-view scroll-y 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 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="title">{{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="cat_id"
          url="/pages/goods_list/index?cid={{item2.cat_id}}"
          >
          <image mode="widthFix" src="{{item2.cat_icon}}"></image>
          <view class="goods_name">{{item2.cat_name}}</view>
          </navigator>
        </view>
      </view>
    </scroll-view>
  </view>
</view>
page {
  height: 100%;
}
.cates {
  height: 100%;
}
.cates .cates_container {
  /* less中使用calc的时候要注意 */
  height: calc( 100vh - 90rpx );
  display: flex;
}
.cates .cates_container .left_menu {
  /* 子项 高度 100% flex */
  flex: 2;
}
.cates .cates_container .left_menu .menu_item {
  height: 80rpx;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 30rpx;
}
.cates .cates_container .left_menu .active {
  color: var(--themeColor);
  border-left: 5rpx solid currentColor;
}
.cates .cates_container .right_content {
  /* 子项 高度 100% flex */
  flex: 5;
}
.cates .cates_container .right_content .goods_group .goods_title {
  height: 80rpx;
  display: flex;
  justify-content: center;
  align-items: center;
}
.cates .cates_container .right_content .goods_group .goods_title .delimiter {
  color: #ccc;
  padding: 0 10rpx;
}
.cates .cates_container .right_content .goods_group .goods_list {
  display: flex;
  flex-wrap: wrap;
}
.cates .cates_container .right_content .goods_group .goods_list navigator {
  width: 33.33%;
  text-align: center;
}
.cates .cates_container .right_content .goods_group .goods_list navigator image {
  width: 50%;
}

2.效果

在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。