HarmonyOS开发案例:【购物APP】

打印 上一主题 下一主题

主题 1683|帖子 1683|积分 5049

介绍

本篇Codelab使用常用组件、页面路由router实现购物应用,包罗以下功能:

  • 使用toolbar、toolbar-item组件实现“首页”,“新品”,“购物车”,“我的”页面切换。
  • 使用list组件,展示购物车里的商品。
  • 使用swiper组件,实现图片自动轮播。
  • 使用panel组件,展示商品规格。
  • 使用自定义组件,进步代码的可读性。

相干概念



  • [swiper]:滑动容器,提供切换子组件显示的本领。
  • [input]:交互式组件,包括单选框,多选框,按钮和单行文本输入框。
  • [search]:搜刮框组件,用于提供用户搜刮内容的输入地区。
  • [toolbar]:工具栏。放在界面底部,用于展示针对当前界面的操作选项。
  • [toolbar-item]:工具栏[toolbar]子组件。 用于展示工具栏上的一个操作选项。
  • [自定义组件]:自定义组件是用户根据业务需求,将已有的组件组合,封装成的新组件,可以在工程中多次调用,从而进步代码的可读性。
环境搭建

软件要求



  • [DevEco Studio]版本:DevEco Studio 3.1 Release及以上版本。
  • OpenHarmony SDK版本:API version 9及以上版本。
硬件要求



  • 开发板类型:[润和RK3568开发板]。
  • OpenHarmony系统:3.2 Release及以上版本。
环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤举行:

  • [获取OpenHarmony系统版本]:标准系统解决方案(二进制)。以3.2 Release版本为例:

  • 搭建烧录环境。

    • [完成DevEco Device Tool的安装]
    • [完成RK3568开发板的烧录]

  • 搭建开发环境。

    • 开始前请参考[工具准备],完成DevEco Studio的安装和开发环境设置。
    • 开发环境设置完成后,请参考[使用工程向导]创建工程(模板选择“Empty Ability”)。
    • 工程创建完成后,选择使用[真机举行调测]。
    • 鸿蒙开发引导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。


代码结构解读

本篇Codelab只对核心代码举行讲解,对于完备代码,我们会在【gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md】中提供。由于本篇Codelab页面较多,因此component和pages目录下只展示“购物主页面”的hml、js、css。
  1. `HarmonyOS与OpenHarmony鸿蒙文档籽料:mau123789是v直接拿`
  2. ├──entry/src/main/js                     // 代码区
  3. │  └──MainAbility
  4. │     ├──common
  5. │     │  ├──constant
  6. │     │  │  └──commonConstants.js    // 公共常量类
  7. │     │  └──images                   // 图片区
  8. │     ├──component
  9. │     │  ├──backComponent            // 后退子组件
  10. │     │  ├──commonButton             // 支付按钮子组件
  11. │     │  ├──commonToolbar            // 导航栏子组件
  12. │     │  ├──home                     // 购物主页子组件
  13. │     │  ├──likedCards               // 猜你喜欢卡片子组件
  14. │     │  ├──myInfo                   // 我的子组件
  15. │     │  ├──newProduct               // 新品子组件
  16. │     │  ├──orderReusableCom         // 用户商品信息子组件
  17. │     │  ├──productBuyInfo           // 购买商品卡片子组件
  18. │     │  ├──shoppingCart             // 购物车子组件
  19. │     │  └──subtitle                 // 副标题子组件
  20. │     ├──i18n
  21. │     │  ├──en-US.json               // 英文国际化                       
  22. │     │  └──zh-CN.json               // 中文国际化       
  23. │     ├──pages
  24. │     │  ├──allOrders                // 全部订单页
  25. │     │  ├──homePage                 // 购物主页
  26. │     │  │  ├──homePage.css          // 购物主页面样式
  27. │     │  │  ├──homePage.hml          // 购物主页面
  28. │     │  │  └──homePage.js           // 购物主页面逻辑
  29. │     │  ├──launchPage               // 启动页
  30. │     │  ├──pendingPayment           // 待支付页
  31. │     │  ├──productDetails           // 产品详情页
  32. │     │  └──sureOrder                // 确定订单页
  33. │     └──app.js                      // 程序入口
  34. └──entry/src/main/resources          // 应用资源目录
复制代码
构建购物应用首页

本篇Codelab选取购物应用的主页面、购物车页面、以及导航栏举行详细的讲解,对于完备代码,可在gitee源码中举行查看。
购物应用的主页面主要由界面底部导航栏和导航栏上的内容组成。效果如图所示:

  1. <!-- homePage.hml -->
  2. <element name="home" src="../../component/home/home.hml"></element>
  3. <element name="new-product" src="../../component/newProduct/newProduct.hml"></element>
  4. <element name="shopping-cart" src="../../component/shoppingCart/shoppingCart.hml"></element>
  5. <element name="my-info" src="../../component/myInfo/myInfo.hml"></element>
  6. <element name="common-toolbar" src="../../component/commonToolbar/commonToolbar.hml"></element>
  7. <div class="container">
  8.     <!-- 主页面 -->
  9.     <home if="{{ tag === homePageIndex }}"></home>
  10.     <!-- 新品页面 -->
  11.     <new-product if="{{ tag === newProductIndex }}"></new-product>
  12.     <!-- 购物车页面 -->
  13.     <shopping-cart if="{{ tag === shoppingCartIndex }}"></shopping-cart>
  14.     <!-- 我的页面 -->
  15.     <my-info if="{{ tag === myInfoIndex }}"></my-info>
  16.     <!-- 导航栏 -->
  17.     <common-toolbar tag="{{ tag }}" @switch-toolbar="switchToolbar"></common-toolbar>
  18. </div>
复制代码
底部导航栏:由“主页”、“新品”、“购物车”以及“我的”页面组成,点击导航栏内容,展示所点击模块的内容。
  1. // homePage.js
  2. import CommonConstants from '../../common/constant/commonConstants';
  3. export default {
  4.   data: {
  5.     // 页面默认展示主页,tag是主页面的索引
  6.     tag: 1,
  7.     // 主页面索引
  8.     homePageIndex: CommonConstants.HOME_PAGE_INDEX,
  9.     // 新品页面索引
  10.     newProductIndex: CommonConstants.NEW_PRODUCT_INDEX,
  11.     // 购物车页面索引
  12.     shoppingCartIndex: CommonConstants.SHOPPING_CART_INDEX,
  13.     // 我的页面索引
  14.     myInfoIndex: CommonConstants.MY_INFO_INDEX
  15.   },
  16.   /**
  17.    * 切换导航栏内容
  18.    *
  19.    * @param value 子组件传过来的索引
  20.    */
  21.   switchToolbar(value) {
  22.     this.tag = value.detail.index;
  23.   }
  24. }
复制代码
子组件:导航栏的使用

导航栏由“主页”、“新品”、“购物车”以及“我的”组成,点击导航栏对应的子组件,页面会展示对应模块的内容。效果如图所示:

在父组件homePage.hml中使用@switch-toolbar="switchToolbar"绑定子组件的事件,用于接收子组件传过来的索引,通过if判定,从而展示索引对应的页面。
  1. <!-- homePage.hml -->
  2. ...
  3. <div class="container">
  4.     <!-- 主页面 -->
  5.     <home if="{{ tag === homePageIndex }}"></home>
  6.     <!-- 新品页面 -->
  7.     <new-product if="{{ tag === newProductIndex }}"></new-product>
  8.     <!-- 购物车页面 -->
  9.     <shopping-cart if="{{ tag === shoppingCartIndex }}"></shopping-cart>
  10.     <!-- 我的页面 -->
  11.     <my-info if="{{ tag === myInfoIndex }}"></my-info>
  12.     <!-- 导航栏 -->
  13.     <common-toolbar tag="{{ tag }}" @switch-toolbar="switchToolbar"></common-toolbar>
  14. </div>
  15. <!-- commonToolbar.hml -->
  16. <div class="container">
  17.     <toolbar class="toolbar">
  18.         <toolbar-item value="{{ $t(toolbarName.home) }}" @click="switchToolbar(homePageIndex)"
  19.                       icon="{{ tag === homePageIndex ? commonIcon.home : commonIcon.homeDisable }}">
  20.         </toolbar-item>
  21.         <toolbar-item value="{{ $t(toolbarName.newProduct) }}" @click="switchToolbar(newProductIndex)"
  22.                       icon="{{ tag === newProductIndex ? commonIcon.newProduct : commonIcon.newProductDisable }}">
  23.         </toolbar-item>
  24.         <toolbar-item value="{{ $t(toolbarName.shoppingCart) }}" @click="switchToolbar(shoppingCartIndex)"
  25.                       icon="{{ tag === shoppingCartIndex ? commonIcon.shoppingCart : commonIcon.shoppingCartDisable }}">
  26.         </toolbar-item>
  27.         <toolbar-item value="{{ $t(toolbarName.me) }}" @click="switchToolbar(myInfoIndex)"
  28.                       icon="{{ tag === myInfoIndex ? commonIcon.me : commonIcon.meDisable }}">
  29.         </toolbar-item>
  30.     </toolbar>
  31. </div>
复制代码
在子组件commonToolbar.js中通过this.$emit(‘switchToolbar’, {info: value})触发事件并向上传递参数,homePage.js中的switchToolbar方法接收子组件传过来的索引。在子组件commonToolbar.js文件中定义props,props用于组件之间的数据通信,当父组件中的tag发生变革的时候,子组件也会随之相应,然后改变toolbar-item中icon的颜色。
  1. // homePage.js
  2. import CommonConstants from '../../common/constant/commonConstants';
  3. export default {
  4.   data: {
  5.     // 页面默认展示主页,tag是主页面的索引
  6.     tag: 1,
  7.     ...
  8.   },
  9.   /**
  10.    * 切换导航栏内容
  11.    *
  12.    * @param value 子组件传过来的索引
  13.    */
  14.   switchToolbar(value) {
  15.     this.tag = value.detail.index;
  16.   }
  17. }
  18. // commonToolbar.js
  19. import CommonConstants from '../../common/constant/commonConstants';
  20. export default {
  21.   props: ['tag'],
  22.   data: {
  23.     commonIcon: CommonConstants.COMMON_TOOLBAR_ICON,
  24.     toolbarName: CommonConstants.COMMON_TOOLBAR_NAME,
  25.     // 主页面索引
  26.     homePageIndex: CommonConstants.HOME_PAGE_INDEX,
  27.     // 新品页面索引
  28.     newProductIndex: CommonConstants.NEW_PRODUCT_INDEX,
  29.     // 购物车页面索引
  30.     shoppingCartIndex: CommonConstants.SHOPPING_CART_INDEX,
  31.     // 我的页面索引
  32.     myInfoIndex: CommonConstants.MY_INFO_INDEX
  33.   },
  34.   /**
  35.    * 向父组件传值
  36.    *
  37.    * @param index 选中子模块的索引
  38.    */
  39.   switchToolbar(index) {
  40.     this.$emit('switchToolbar', {
  41.       index: index
  42.     });
  43.   }
  44. }
复制代码
构建购物车页面

购物车页面由顶部标题栏、购物车商品列表、猜你喜好的商品列表三部分组成,并以子组件的形式显示在主页面中。其中,购物车商品列表使用list组件和for循环,实现对多条商品数据举行展示。猜你喜好的商品列表是通过引用自定义组件实现的。效果如图所示:

  1. <!-- shoppingCart.hml -->
  2. <element name="liked-cards" src="../../component/likedCards/likedCards.hml"></element>
  3. <div class="container">
  4.     <div class="top">
  5.         <!-- 顶部导航标题栏 -->
  6.         <div class="top-title">
  7.             <text class="shopping-cart">{{ $t('strings.shopping_cart') }}</text>
  8.             <text class="edit">{{ $t('strings.edit') }}</text>
  9.         </div>
  10.         <!-- 购物车商品列表 -->
  11.         <div class="top-list">
  12.             <div class="list-title">
  13.                 <input class="all-checkbox" type="checkbox" checked="{{ isAllSelect }}" @change="checkboxOnChange">
  14.                 </input>
  15.                 <image class="my-icon-size" src="{{ person }}"></image>
  16.                 <text class="mall-self-operated">{{ $t('strings.mall_self_operated') }}</text>
  17.             </div>
  18.             <list class="list">
  19.                 <list-item for="{{ (index, item) in shoppingListData }}" class="list-item">
  20.                     <div class="list-content">
  21.                         <input class="checkbox" type="checkbox" checked="{{ item.isSelect }}"></input>
  22.                         <image class="product-pictures" src="{{ item.image }}"></image>
  23.                         <div class="box-content">
  24.                             <text class="product-title">{{ $t(item.title) }}</text>
  25.                             <text class="product-subtitle">{{ $t(item.subtitle) }}</text>
  26.                             <div class="content-price">
  27.                                 <text class="product-price">{{ item.price }}</text>
  28.                                 <div class="price-num">
  29.                                     <image class="my-icon-size" @click="subtractNum(index)" src="{{ item.num === 0 ?
  30.                                             commonIcon.decreaseDisableIcon : commonIcon.decreaseIcon }}">
  31.                                     </image>
  32.                                     <text class="product-num">{{ item.num }}</text>
  33.                                     <image class="my-icon-size" src="{{ commonIcon.increaseIcon }}"
  34.                                            @click="addNum(index)">
  35.                                     </image>
  36.                                 </div>
  37.                             </div>
  38.                         </div>
  39.                     </div>
  40.                 </list-item>
  41.             </list>
  42.         </div>
  43.     </div>
  44.     <!-- 猜你喜欢商品列表 -->
  45.     <div class="middle-card">
  46.         <liked-cards></liked-cards>
  47.     </div>
  48. </div>
复制代码


  • 点击“商品自营”头像前的多选框,会触发checkboxOnChange()方法,页面会勾选/不勾选购物车的中所有商品。
  • 点击“+”按钮会触发addNum()方法,增加单件商品的数目。
  • 点击“-”按钮会触发subtractNum()方法,减少单件商品的数目。
  1. // shoppingCart.js
  2. import CommonConstants from '../../common/constant/commonConstants';
  3. export default {
  4.   data: {
  5.     isAllSelect: false,
  6.     shoppingListData: CommonConstants.SHOPPING_LIST_DATA,
  7.     commonIcon: CommonConstants.SHOPPING_CART_ICON,
  8.     person: CommonConstants.COMMON_ICON.person
  9.   },
  10.   /**
  11.    * 购物车商品全选/非全选
  12.    */
  13.   checkboxOnChange() {
  14.     this.isAllSelect = !this.isAllSelect;
  15.     this.shoppingListData.filter((item) => {
  16.       item.isSelect = this.isAllSelect;
  17.     });
  18.   },
  19.   /**
  20.    * 勾选单个商品
  21.    *
  22.    * @param subscript 选中商品的索引
  23.    * @param event 单选框事件
  24.    */
  25.   singleAnswer(subscript, event) {
  26.     // 修改商品的选择状态
  27.     this.shoppingListData.forEach((item, index) => {
  28.       if (index === subscript) {
  29.         item.isSelect = event.checked;
  30.       }
  31.     })
  32.     // 检查购物车中的所有商品是否都被选中
  33.     let selectAll = this.shoppingListData.every(item => item.isSelect === true);
  34.     if (selectAll === true) {
  35.       this.isAllSelect = true;
  36.     } else {
  37.       this.isAllSelect = false;
  38.     }
  39.   },
  40.   /**
  41.    * 减少商品数量逻辑
  42.    *
  43.    * @param value 当前商品的数量
  44.    */
  45.   subtractNum(value) {
  46.     if (this.shoppingListData[value].num > 0) {
  47.       this.shoppingListData[value].num--;
  48.     }
  49.   },
  50.   /**
  51.    * 增加商品数量逻辑
  52.    *
  53.    * @param value 当前商品的数量
  54.    */
  55.   addNum(value) {
  56.     this.shoppingListData[value].num++;
  57.   }
  58. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美丽的神话

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表