网络知识 娱乐 uni-app黑马优购项目学习记录(上)

uni-app黑马优购项目学习记录(上)

写在前边

这篇博文是在黑马程序员uniapp-黑马优购项目文档的基础上进行书写的,原文在这里:uniapp-黑马优购,视频教程。

文章资料和接口文档:链接:https://pan.baidu.com/s/1dkJu8aaJEjnLEfERL7j1Nw
提取码:b3ub

如你所见,本人现在正在学习黑马的uniapp,为了让自己能够方便的复习所学知识,我将自己的理解以及一些在学习过程中遇到的问题和解决方法与黑马原有的文档进行结合,书写了这篇博文,如有侵权,联系必删!

因内容较多,本次博客分为上下两篇,下篇请见:uni-app黑马优购项目学习记录(下)

uni-app黑马优购项目学习记录(上)

  • 写在前边
  • 1. 起步
    • 1.1 uni-app 简介
    • 1.2 开发工具
      • 1.2.1 下载 HBuilderX
      • 1.2.2 安装 HBuilderX
      • 1.2.3 安装 scss/sass 编译
    • 1.2.4 快捷键方案切换
      • 1.2.5 修改编辑器的基本设置
    • 1.3 新建 uni-app 项目
    • 1.4 目录结构
    • 1.5 把项目运行到微信开发者工具
    • 1.6 使用 Git 管理项目
      • 1.6.1 本地管理
      • 1.6.2 把项目托管到码云
  • 2. tabBar
    • 2.1 创建 tabBar 分支
    • 2.2 创建 tabBar 页面
    • 2.3 配置 tabBar 效果
    • 2.4 删除默认的 index 首页
    • 2.5 修改导航条的样式效果
    • 2.6 分支的提交与合并
  • 3. 首页
    • 3.1 创建 home 分支
    • 3.2 配置网络请求
    • 3.3 轮播图区域
      • 3.3.1 请求轮播图的数据
      • 3.3.2 渲染轮播图的 UI 结构
      • 3.3.3 配置小程序分包
      • 3.3.4 点击轮播图跳转到商品详情页面
      • 3.3.5 封装 uni.$showMsg() 方法
    • 3.4 分类导航区域
      • 3.4.1 获取分类导航的数据
      • 3.4.2 渲染分类导航的 UI 结构
      • 3.4.3 点击第一项,切换到分类页面
    • 3.5 楼层区域
      • 3.5.1 获取楼层数据
      • 3.5.2 渲染楼层的内容
      • 3.5.3 点击楼层图片跳转到商品列表页
    • 3.6 分支的合并与提交
  • 4. 分类
    • 4.0 创建 cate 分支
    • 4.1 渲染分类页面的基本结构
    • 4.2 获取分类数据
    • 4.3 动态渲染左侧的一级分类列表
    • 4.4 动态渲染右侧的二级分类列表
    • 4.5 动态渲染右侧的三级分类列表
    • 4.6 切换一级分类后重置滚动条的位置
    • 4.7 点击三级分类跳转到商品列表页面
    • 4.8 分支的合并与提交
  • 5. 搜索
    • 5.0 创建 search 分支
    • 5.1 自定义搜索组件
      • 5.1.1 自定义 my-search 组件
      • 5.1.2 通过自定义属性增强组件的通用性
      • 5.1.3 为自定义组件封装 click 事件
      • 5.1.4 实现首页搜索组件的吸顶效果
    • 5.2 搜索建议
      • 5.2.1 渲染搜索页面的基本结构
      • 5.2.2 实现搜索框自动获取焦点
      • 5.2.3 实现搜索框的防抖处理
      • 5.2.4 根据关键词查询搜索建议列表
      • 5.2.5 渲染搜索建议列表
    • 5.3 搜索历史
      • 5.3.1 渲染搜索历史记录的基本结构
      • 5.3.2 实现搜索建议和搜索历史的按需展示
      • 5.3.3 将搜索关键词存入 historyList
      • 5.3.4 解决关键字前后顺序的问题
      • 5.3.5 解决关键词重复的问题
      • 5.3.6 一行代码解决上述保存关键字顺序和重复的问题
      • 5.3.6 将搜索历史记录持久化存储到本地
      • 5.3.7 清空搜索历史记录
      • 5.3.8 点击搜索历史跳转到商品列表页面
    • 5.4 分支的合并与提交
  • 6. 商品列表
    • 6.0 创建 goodslist 分支
    • 6.1 定义请求参数对象
    • 6.2 获取商品列表数据
    • 6.3 渲染商品列表结构
    • 6.4 把商品 item 项封装为自定义组件
    • 6.5 使用过滤器处理价格
    • 6.6 上拉加载更多
      • 6.6.1 初步实现上拉加载更多
      • 6.6.2 通过节流阀防止发起额外的请求
      • 6.6.3 判断数据是否加载完毕
    • 6.7 下拉刷新
    • 6.8 点击商品 item 项跳转到详情页面
    • 6.9 分支的合并与提交
  • 7. 商品详情
    • 7.0 创建 goodsdetail 分支
    • 7.1 添加商品详情页的编译模式
    • 7.2 获取商品详情数据
    • 7.3 渲染商品详情页的 UI 结构
      • 7.3.1 渲染轮播图区域
      • 7.3.2 实现轮播图预览效果
      • 7.3.3 渲染商品信息区域
      • 7.3.4 渲染商品详情信息
      • 7.3.5 解决商品价格闪烁的问题
    • 7.4 渲染详情页底部的商品导航区域
      • 7.4.1 渲染商品导航区域的 UI 结构
      • 7.4.2 点击跳转到购物车页面
    • 7.5 分支的合并与提交

1. 起步

1.1 uni-app 简介

uni-app 是一个使用 Vue.js 开发所有前端应用的框架。开发者编写一套代码,可发布到 iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。
在这里插入图片描述

详细的 uni-app 官方文档,请翻阅 https://uniapp.dcloud.net.cn/

1.2 开发工具

uni-app 官方推荐使用 HBuilderX 来开发 uni-app 类型的项目。主要好处:

  • 模板丰富

  • 完善的智能提示

  • 一键运行

1.2.1 下载 HBuilderX

  1. 访问 HBuilderX 的官网首页 https://www.dcloud.io/hbuilderx.html

  2. 点击首页的 DOWNLOAD 按钮

  3. 选择下载 正式版 -> App 开发版

1.2.2 安装 HBuilderX

  1. 将下载的 zip包 进行解压缩

  2. 将解压之后的文件夹,存放到纯英文的目录中(且不能包含括号等特殊字符)

  3. 双击 HBuilderX.exe 即可启动 HBuilderX

1.2.3 安装 scss/sass 编译

为了方便编写样式(例如:),建议安装 scss/sass 编译 插件。插件下载地址:

https://ext.dcloud.net.cn/plugin?name=compile-node-sass

进入插件下载页面之后,点击右上角的 使用 HBuilderX 导入插件 按钮进行自动安装,截图如下:

在这里插入图片描述

如果没有右侧这两个按钮,可以看一下是不是自己的浏览器安装了屏蔽广告的插件,将插件关闭后就会显示按钮了

1.2.4 快捷键方案切换

操作步骤:工具 -> 预设快捷键方案切换 -> VS Code
在这里插入图片描述

1.2.5 修改编辑器的基本设置

操作步骤:工具 -> 设置 -> 打开 Settings.json 按需进行配置

源码视图下可用的参考配置:

{
  "editor.colorScheme": "Default",
  "editor.fontSize": 12,
  "editor.fontFamily": "Consolas",
  "editor.fontFmyCHS": "微软雅黑 Light",
  "editor.insertSpaces": true,
  "editor.lineHeight": "1.5",
  "editor.minimap.enabled": false,
  "editor.mouseWheelZoom": true,
  "editor.onlyHighlightWord": false,
  "editor.tabSize": 2,
  "editor.wordWrap": true,
  "explorer.iconTheme": "vs-seti",
  "editor.codeassist.px2rem.enabel": false,
  "editor.codeassist.px2upx.enabel": false
}

Tips:可以使用 Ctrl + 鼠标滚轮 缩放编辑器

1.3 新建 uni-app 项目

  1. 文件 -> 新建 -> 项目
    在这里插入图片描述

  2. 填写项目基本信息
    在这里插入图片描述

    项目模板按需进行选择

  3. 项目创建成功
    在这里插入图片描述

1.4 目录结构

一个 uni-app 项目,默认包含如下目录及文件:

┌─components            uni-app组件目录
│  └─comp-a.vue         可复用的a组件
├─pages                 业务页面文件存放的目录
│  ├─index
│  │  └─index.vue       index页面
│  └─list
│     └─list.vue        list页面
├─static                存放应用引用静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─main.js               Vue初始化入口文件
├─App.vue               应用配置,用来配置小程序的全局样式、生命周期函数等
├─manifest.json         配置应用名称、appid、logo、版本等打包信息
└─pages.json            配置页面路径、页面窗口样式、tabBar、navigationBar 等页面类信息

1.5 把项目运行到微信开发者工具

  1. 填写自己的微信小程序的 AppID:
    在这里插入图片描述

  2. 在 HBuilderX 中,配置“微信开发者工具”的安装路径
    在这里插入图片描述

  3. 在微信开发者工具中,通过 设置 -> 安全设置 面板,开启“微信开发者工具”的服务端口
    在这里插入图片描述
    在这里插入图片描述

  4. 在 HBuilderX 中,点击菜单栏中的 运行 -> 运行到小程序模拟器 -> 微信开发者工具,将当前 uni-app 项目编译之后,自动运行到微信开发者工具中,从而方便查看项目效果与调试:
    在这里插入图片描述

  5. 初次运行成功之后的项目效果:
    在这里插入图片描述

    如果运行不成功可以尝试多运行几次

    如果想要修改小程序project.config.json里的配置项(如setting内容),不能直接在小程序开发者工具里修改,需要到HBuilderX的项目根目录下manifest.json里选择源码视图进行修改:
    在这里插入图片描述

1.6 使用 Git 管理项目

1.6.1 本地管理

  1. 在项目根目录中新建 .gitignore 忽略文件,并配置如下:

    # 忽略 node_modules 目录
    /node_modules
    /unpackage/dist
    

    注意:由于我们忽略了 unpackage 目录中仅有的 dist 目录,因此默认情况下, unpackage 目录不会被 Git 追踪

    此时,为了让 Git 能够正常追踪 unpackage 目录,按照惯例,我们可以在 unpackage 目录下创建一个叫做 .gitkeep 的文件进行占位

  2. 打开终端,切换到项目根目录中,运行如下的命令,初始化本地 Git 仓库:

    git init
    
  3. 将所有文件都加入到暂存区:

    git add .
    
  4. 本地提交更新:

    git commit -m "init project"
    

1.6.2 把项目托管到码云

  1. 注册并激活码云账号( 注册页面地址:https://gitee.com/signup )

  2. 生成并配置 SSH 公钥

  3. 创建空白的码云仓库

  4. 把本地项目上传到码云对应的空白仓库中

2. tabBar

2.1 创建 tabBar 分支

运行如下的命令,基于 master 分支在本地创建 tabBar 子分支,用来开发和 tabBar 相关的功能:

git checkout -b tabbar

2.2 创建 tabBar 页面

pages 目录中,创建首页(home)、分类(cate)、购物车(cart)、我的(my) 这 4 个 tabBar 页面。在 HBuilderX 中,可以通过如下的两个步骤,快速新建页面:

  1. pages 目录上鼠标右键,选择新建页面

  2. 在弹出的窗口中,填写页面的名称、勾选 scss 模板之后,点击创建按钮。截图如下:
    在这里插入图片描述

2.3 配置 tabBar 效果

  1. 资料 目录下的 static 文件夹 拷贝一份,替换掉项目根目录中的 static 文件夹

  2. 修改项目根目录中的 pages.json 配置文件,新增 tabBar 的配置节点(与pages配置节点同级)如下:

    {
      "tabBar": {
        "selectedColor": "#C00000",
        "list": [
          {
          // 路径
          "pagePath": "pages/home/home",
          // 导航文本
          "text": "首页",
          // 默认图标
          "iconPath": "static/tab_icons/home.png",
          // 选中的图标
          "selectedIconPath": "static/tab_icons/home-active.png"
          },
          {
            "pagePath": "pages/cate/cate",
            "text": "分类",
            "iconPath": "static/tab_icons/cate.png",
            "selectedIconPath": "static/tab_icons/cate-active.png"
          },
          {
            "pagePath": "pages/cart/cart",
            "text": "购物车",
            "iconPath": "static/tab_icons/cart.png",
            "selectedIconPath": "static/tab_icons/cart-active.png"
          },
          {
            "pagePath": "pages/my/my",
            "text": "我的",
            "iconPath": "static/tab_icons/my.png",
            "selectedIconPath": "static/tab_icons/my-active.png"
          }
        ]
      }
    }
    

2.4 删除默认的 index 首页

  1. 在 HBuilderX 中,把 pages 目录下的 index首页文件夹 删除掉

  2. 同时,把 page.json 中记录的 index 首页 路径删除掉

  3. 为了防止小程序运行失败,在微信开发者工具中,手动删除 pages 目录下的 index 首页文件夹

  4. 同时,把 components 目录下的组件文件夹删除掉

2.5 修改导航条的样式效果

  1. 打开 pages.json 这个全局的配置文件

  2. 修改 globalStyle 节点如下:

      "globalStyle": {
        // 小程序导航栏标题颜色,仅支持 black / white
        "navigationBarTextStyle": "white",
        //小程序导航栏标题文字内容
        "navigationBarTitleText": "小陈优购",
        //小程序导航栏背景颜色
        "navigationBarBackgroundColor": "#C00000",
        // 窗口的背景色
        "backgroundColor": "#ffffff",
        "app-plus": {
          "background": "#efeff4"
        }
      }
    

2.6 分支的提交与合并

  1. 将本地的 tabbar 分支进行本地的 commit 提交:

    git add .
    git commit -m "完成了 tabBar 的开发"
    
  2. 将本地的 tabbar 分支推送到远程仓库进行保存:

    git push -u origin tabbar
    

    在这里插入图片描述

    此时码云仓库已经有了tabbar分支

  3. 将本地的 tabbar 分支合并到本地的 master 分支:

    git checkout master
    git merge tabbar
    
  4. 更新码云仓库代码

    因为新的代码我们推到了tabbar分支里面,master分支里的代码我们还没有更新,可运行以下代码进行更新:

    git push
    
  5. 删除本地的 tabbar 分支:

    git branch -d tabbar
    

3. 首页

展示:
请添加图片描述


接口描述:

  • 轮播图

请求URL:

  • https://api-ugo-web.itheima.net/api/public/v1/home/swiperdata

请求方式:

  • GET

参数:

返回示例

{
    "message": [
        {
            "image_src": "https://api-ugo-web.itheima.net/pyg/banner1.png",
            "open_type": "navigate",
            "goods_id": 129,
            "navigator_url": "/pages/goods_detail/index?goods_id=129"
        }
    ],
    "meta": {
        "msg": "获取成功",
        "status": 200
    }
}

返回参数说明

参数名类型说明
image_srcstring图片路径
open_typestring打开方式
goods_idnumber商品id
navigator_urlstring导航链接

接口描述:

  • 导航菜单

请求URL:

  • https://api-ugo-web.itheima.net/api/public/v1/home/catitems

请求方式:

  • GET

参数:

返回示例

{
    "message": [
        {
            "name": "分类",
            "image_src": "https://api-ugo-web.itheima.net/pyg/icon_index_nav_4@2x.png",
            "open_type": "switchTab",
            "navigator_url": "/pages/category/index"
        },
        {
            "name": "秒杀拍",
            "image_src": "https://api-ugo-web.itheima.net/pyg/icon_index_nav_3@2x.png"
        },
        {
            "name": "超市购",
            "image_src": "https://api-ugo-web.itheima.net/pyg/icon_index_nav_2@2x.png"
        },
        {
            "name": "母婴品",
            "image_src": "https://api-ugo-web.itheima.net/pyg/icon_index_nav_1@2x.png"
        }
    ],
    "meta": {
        "msg": "获取成功",
        "status": 200
    }
}

返回参数说明

参数名类型说明
namestring标题名称
image_srcstring图片路径

简要描述:

  • 楼层

请求URL:

  • https://api-ugo-web.itheima.net/api/public/v1/home/floordata

请求方式:

  • GET

参数:

返回示例

{
    "message": [
        {
            "floor_title": {
                "name": "时尚女装",
                "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor01_title.png"
            },
            "product_list": [
                {
                    "name": "优质服饰",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor01_1@2x.png",
                    "image_width": "232",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list/index?query=服饰"
                },
                {
                    "name": "春季热门",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor01_2@2x.png",
                    "image_width": "233",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list/index?query=热"
                },
                {
                    "name": "爆款清仓",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor01_3@2x.png",
                    "image_width": "233",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list/index?query=爆款"
                },
                {
                    "name": "倒春寒",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor01_4@2x.png",
                    "image_width": "233",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list/index?query=春季"
                },
                {
                    "name": "怦然心动",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor01_5@2x.png",
                    "image_width": "233",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list/index?query=心动"
                }
            ]
        },
        {
            "floor_title": {
                "name": "户外活动",
                "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor02_title.png"
            },
            "product_list": [
                {
                    "name": "勇往直前",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor02_1@2x.png",
                    "image_width": "232",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list/index?query=户外"
                },
                {
                    "name": "户外登山包",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor02_2@2x.png",
                    "image_width": "273",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list/index?query=登山包"
                },
                {
                    "name": "超强手套",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor02_3@2x.png",
                    "image_width": "193",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list/index?query=手套"
                },
                {
                    "name": "户外运动鞋",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor02_4@2x.png",
                    "image_width": "193",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list/index?query=运动鞋"
                },
                {
                    "name": "冲锋衣系列",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor02_5@2x.png",
                    "image_width": "273",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list/index?query=冲锋衣"
                }
            ]
        },
        {
            "floor_title": {
                "name": "箱包配饰",
                "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor03_title.png"
            },
            "product_list": [
                {
                    "name": "清新气质",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor03_1@2x.png",
                    "image_width": "232",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list?query=饰品"
                },
                {
                    "name": "复古胸针",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor03_2@2x.png",
                    "image_width": "263",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list?query=胸针"
                },
                {
                    "name": "韩版手链",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor03_3@2x.png",
                    "image_width": "203",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list?query=手链"
                },
                {
                    "name": "水晶项链",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor03_4@2x.png",
                    "image_width": "193",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list?query=水晶项链"
                },
                {
                    "name": "情侣表",
                    "image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor03_5@2x.png",
                    "image_width": "273",
                    "open_type": "navigate",
                    "navigator_url": "/pages/goods_list?query=情侣表"
                }
            ]
        }
    ],
    "meta": {
        "msg": "获取成功",
        "status": 200
    }
}

返回参数说明

参数名类型说明
floor_titlestring一级分类标题
product_listarray一级分类内容
namestring名称
image_srcstring图片路径
image_widthstring图片宽度
open_typestring打开方式
navigator_urlstring跳转连接

3.1 创建 home 分支

运行如下的命令,基于 master 分支在本地创建 home 子分支,用来开发和 home 首页相关的功能:

git checkout -b home

3.2 配置网络请求

由于平台的限制,小程序项目中不支持 axios,而且原生的 wx.request() API 功能较为简单,不支持拦截器等全局定制的功能。因此,建议在 uni-app 项目中使用 @escook/request-miniprogram 第三方包发起网络数据请求。

请参考 @escook/request-miniprogram 的官方文档进行安装、配置、使用

官方文档:https://www.npmjs.com/package/@escook/request-miniprogram

最终,在项目的 main.js 入口文件中,通过如下的方式进行配置:

import { $http } from '@escook/request-miniprogram'

uni.$http = $http
// 配置请求根路径
$http.baseUrl = 'https://api-ugo-web.itheima.net'

// 请求开始之前做一些事情
$http.beforeRequest = function (options) {
  uni.showLoading({
    title: '数据加载中...',
  })
}

// 请求完成之后做一些事情
$http.afterRequest = function () {
  uni.hideLoading()
}

3.3 轮播图区域

3.3.1 请求轮播图的数据

实现步骤:

  1. data 中定义轮播图的数组

  2. onLoad 生命周期函数中调用获取轮播图数据的方法

  3. methods 中定义获取轮播图数据的方法

示例代码:

//home.vue
export default {
    data() {
      return {
        //存放轮播图数据
        swiperList:[]
      };
    },
    onLoad(){
      //在小程序页面刚加载的时候,调用获取轮播图数据的方法
      this.getSwiperList()
    },
    methods:{
      //获取轮播图数据
      async getSwiperList(){
        //发起请求,从返回的数据中结构出data并起个res的别名
        const {data:res} = await uni.$http.get('/api/public/v1/home/swiperdata')
        //请求失败
        if(res