黑马小程序品优购商城项目分析
黑马电商品优购小程序
几日前完成了该项目,整理了下大概的逻辑思路,希望和大家一起交流学习,文档中不足之处希望各位不吝赐教。
该项目使用小程序原生mina框架
项目页面的搭建
页面名称 | 文件 |
---|---|
首页 | index |
分类 | category |
商品列表 | goods_list |
商品详情 | goods_detail |
购物车 | cart |
收藏 | collect |
订单 | order |
搜索 | search |
个人中心 | user |
意见反馈 | user |
登录 | login |
授权 | auth |
结算 | pay |
- 项目文件目录
首页
分类页面
1.点击左侧菜单切换内容
获取被点击的标题身上的索引
给data中的currentIndex赋值
根据不同的索引来渲染右侧的商品内容
handleItemTap (e) {const { index } = e.currentTarget.dataset;let rightContent = this.Cates[index].children;this.setData({currentIndex: index,rightContent,scrollTop: 0})}
商品列表
Tab栏
1.自定义组件传值
- ⽗组件通过属性的⽅式给⼦组件传递参数、⼦组件通过事件的⽅式向⽗组件传递参数
- ⽗组件 把数据 {{tabs}} 传递到 ⼦组件的 tabItems 属性中
- ⽗组件 监听 onMyTab 事件
- ⼦组件 触发 bindmytap 中的事件
- ⾃定义组件触发事件时,需要使⽤ triggerEvent ⽅法,指定 事件名 、 detail 对象
- ⽗ -> ⼦ 动态传值 this.selectComponent("#tabs");
2.Tab栏切换
获取被点击的标题索引
修改源数组
赋值到data中
const { index } = e.detail; let { tabs } = this.data; tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false); this.setData({tabs })
3.下拉页面功能
⻚⾯的json⽂件中开启设置 enablePullDownRefresh:true
- ⻚⾯的JS中,绑定事件 onPullDownRefresh
// 下拉刷新事件 onPullDownRefresh () {// 1 重置数组this.setData({goodsList: []})// 2 重置页码this.QueryParams.pagenum = 1;// 3 发送请求this.getGoodsList();}
启⽤上拉⻚⾯功能 onReachBottom ⻚⾯触底事件
加载下⼀⻚功能
// 页面上滑 滚动条触底事件onReachBottom () {// 1 判断还有没有下一页数据if (this.QueryParams.pagenum >= this.totalPages) {// 没有下一页数据wx.showToast({ title: '没有下一页数据' });} else {// 还有下一页数据this.QueryParams.pagenum++;this.getGoodsList();}},
商品详情
1.点击图片预览
- 实现效果
2.加入购物车 逻辑
- 先绑定点击事件
- 获取缓存中的购物车数据 数组格式
- 先判断 当前的商品是否已经存在于 购物车
- 已经存在 修改商品数据 执行购物车数量++ 重新把购物车数组 填充回缓存中
- 不存在于购物车的数组中 直接给购物车数组添加一个新元素 新元素 带上 购买数量属性 num 重新把购物车数组 填充回缓存中
- 弹出提示
// 点击 加入购物车handleCartAdd() {// 1 获取缓存中的购物车 数组let cart = wx.getStorageSync("cart") || [];// 2 判断 商品对象是否存在于购物车数组中let index = cart.findIndex(v => v.goods_id === this.GoodsInfo.goods_id);if (index === -1) {//3 不存在 第一次添加this.GoodsInfo.num = 1;this.GoodsInfo.checked = true;cart.push(this.GoodsInfo);} else {// 4 已经存在购物车数据 执行 num++cart[index].num++;}// 5 把购物车重新添加回缓存中wx.setStorageSync("cart", cart);// 6 弹窗提示wx.showToast({title: '加入成功',icon: 'success',// true 防止用户 手抖 疯狂点击按钮 mask: true});},
3.商品收藏
页面onShow的时候 加载缓存中的商品收藏的数据
判断当前商品是不是被收藏
是 改变页面的图标
不是
点击商品收藏按钮
- 判断该商品是否存在于缓存数组中
- 已经存在 把该商品删除
- 没有存在 把商品添加到收藏数组中 存入到缓存中即可
// 点击 商品收藏图标handleCollect () {let isCollect = false;// 1 获取缓存中的商品收藏数组let collect = wx.getStorageSync("collect") || [];// 2 判断该商品是否被收藏过let index = collect.findIndex(v => v.goods_id === this.GoodsInfo.goods_id);// 3 当index!=-1表示 已经收藏过 if (index !== -1) {// 能找到 已经收藏过了 在数组中删除该商品collect.splice(index, 1);isCollect = false;wx.showToast({title: '取消成功',icon: 'success',mask: true});} else {// 没有收藏过collect.push(this.GoodsInfo);isCollect = true;wx.showToast({title: '收藏成功',icon: 'success',mask: true});}// 4 把数组存入到缓存中wx.setStorageSync("collect", collect);// 5 修改data中的属性 isCollectthis.setData({isCollect})}
购物车
1.获取用户的收货地址
绑定点击事件
调用小程序内置 api 获取用户的收货地址 wx.chooseAddress
获取 用户权限 状态 scope
假设 用户 点击获取收货地址的提示框 确定 scope 值 true 直接调用 获取收货地址
假设 用户 从来没有调用过 收货地址的api scope undefined 直接调用 获取收货地址
假设 用户 点击获取收货地址的提示框 取消
- scope 值 false
- 诱导用户 自己 打开 授权设置页面(wx.openSetting) 当用户重新给与 获取地址权限的时候
- 获取收货地址
- 把获取到的收货地址 存入到 本地存储中
// 点击 收货地址async handleChooseAddress() {try {// 1 获取 权限状态const res1 = await getSetting();const scopeAddress = res1.authSetting["scope.address"];// 2 判断 权限状态if (scopeAddress === false) {await openSetting();}// 4 调用获取收货地址的 apilet address = await chooseAddress();address.all = address.provinceName + address.cityName + address.countyName + address.detailInfo;// 5 存入到缓存中wx.setStorageSync("address", address);} catch (error) {console.log(error);}},
2.全选的实现 数据的展示
- onShow 获取缓存中的购物车数组
- 根据购物车中的商品数据 所有的商品都被选中 checked=true 全选就被选中
// 商品全选功能handleItemAllCheck() {// 1 获取data中的数据let { cart, allChecked } = this.data;// 2 修改值allChecked = !allChecked;// 3 循环修改cart数组 中的商品选中状态cart.forEach(v => v.checked = allChecked);// 4 把修改后的值 填充回data或者缓存中this.setCart(cart);},
3.商品数量编辑
- 获取传递过来的参数
- 获取购物车数组
- 找到需要修改的商品的索引
- 判断是否要执行删除
- 进行修改数量
- 设置回缓存和data中
// 商品数量的编辑功能async handleItemNumEdit (e) {// 1 获取传递过来的参数 const { operation, id } = e.currentTarget.dataset;// 2 获取购物车数组let { cart } = this.data;// 3 找到需要修改的商品的索引const index = cart.findIndex(v => v.goods_id === id);// 4 判断是否要执行删除if (cart[index].num === 1 && operation === -1) {// 4.1 弹窗提示const res = await showModal({ content: "您是否要删除?" });if (res.confirm) {cart.splice(index, 1);this.setCart(cart);}} else {// 4 进行修改数量cart[index].num += operation;// 5 设置回缓存和data中this.setCart(cart);}},
个人中心
收藏
订单
搜索
1.输入框绑定 值改变事件 input事件
- 获取到输入框的值
- 合法性判断 (非空)
- 检验通过 把输入框的值 发送到后台
- 返回的数据打印到页面上
2.防抖 (防止抖动) 定时器 节流
- 防抖 一般 输入框中 防止重复输入 重复发送请求
- 节流 一般是用在页面下拉和上拉
- 定义全局的定时器id
// 输入框的值改变 就会触发的事件handleInput(e){// 1 获取输入框的值const {value}=e.detail;// 2 检测合法性if(!value.trim()){this.setData({goods:[],isFocus:false})// 值不合法return;}// 3 准备发送请求获取数据this.setData({isFocus:true})clearTimeout(this.TimeId);this.TimeId=setTimeout(() => {this.qsearch(value);}, 1000);},// 发送请求获取搜索建议 数据async qsearch(query){const res=await request({url:"/goods/qsearch",data:{query}});console.log(res);this.setData({goods:res})},
意见反馈
1 点击 “+” 触发tap点击事件
1 调用小程序内置的 选择图片的 api
2 获取到 图片的路径 数组
3 把图片路径 存到 data的变量中
4 页面就可以根据 图片数组 进行循环显示 自定义组件
// 点击 “+” 选择图片
handleChooseImg() {// 2 调用小程序内置的选择图片api
wx.chooseImage({// 同时选中的图片的数量count: 9,// 图片的格式 原图 压缩sizeType: ['original', 'compressed'],// 图片的来源 相册 照相机sourceType: ['album', 'camera'],success: (result) => {this.setData({// 图片数组 进行拼接 chooseImgs: [...this.data.chooseImgs, ...result.tempFilePaths]})}
});},
2 点击 自定义图片 组件
1 获取被点击的元素的索引
2 获取 data中的图片数组
3 根据索引 数组中删除对应的元素
4 把数组重新设置回data中
// 点击 自定义图片组件handleRemoveImg(e) {// 2 获取被点击的组件的索引const { index } = e.currentTarget.dataset;// 3 获取data中的图片数组let { chooseImgs } = this.data;// 4 删除元素chooseImgs.splice(index, 1);this.setData({chooseImgs})},
3 提交
获取文本域的内容 类似 输入框的获取
- data中定义变量 表示 输入框内容
- 文本域 绑定 输入事件 事件触发的时候 把输入框的值 存入到变量中
对这些内容 合法性验证
验证通过 用户选择的图片 上传到专门的图片的服务器 返回图片外网的链接
遍历图片数组
挨个上传
自己再维护图片数组 存放 图片上传后的外网的链接
文本域 和 外网的图片的路径 一起提交到服务器 前端的模拟 不会发送请求到后台
清空当前页面
返回上一页
// 提交按钮的点击handleFormSubmit() {// 1 获取文本域的内容 图片数组const { textVal, chooseImgs } = this.data;// 2 合法性的验证if (!textVal.trim()) {// 不合法wx.showToast({title: '输入不合法',icon: 'none',mask: true});return;}// 3 准备上传图片 到专门的图片服务器 // 上传文件的 api 不支持 多个文件同时上传 遍历数组 挨个上传 // 显示正在等待的图片wx.showLoading({title: "正在上传中",mask: true});// 判断有没有需要上传的图片数组if (chooseImgs.length != 0) {chooseImgs.forEach((v, i) => {wx.uploadFile({// 图片要上传到哪里url: 'http://img.coolcr.cn/index/api.html',// 被上传的文件的路径filePath: v,// 上传的文件的名称 后台来获取文件 filename: "image",// 顺带的文本信息formData: {},success: (result) => {console.log(result);let url = JSON.parse(result.data).url;this.UpLoadImgs.push(url);// 所有的图片都上传完毕了才触发 if (i === chooseImgs.length - 1) {wx.hideLoading();console.log("把文本的内容和外网的图片数组 提交到后台中");// 提交都成功了// 重置页面this.setData({textVal: "",chooseImgs: []})// 返回上一个页面wx.navigateBack({delta: 1});}}});})}else{wx.hideLoading();console.log("只是提交了文本");wx.navigateBack({delta: 1});}}
登录
结算
因为支付功能需要权限,所以这部分没有做,除了支付其他的部分是都可以做的,大家加油!
黑马小程序品优购商城项目分析相关推荐
- 小程序swiper怎么让内容撑开高度_[视频]微信小程序实战优购商城,涵盖你所学的技能点...
很多友友都在找视频教程学习,IT技术教程分享网[http://www.mano100.cn]已经为你收集了各种各样的视频教程,不用再到处找视频教程学习了.无论是免费的,还是收费的,都在这里了.只要你注 ...
- uniapp微信小程序项目-优购商城
原网页笔记文档: https://www.escook.cn/docs-uni-shop/ 1. 起步 #1.1 uni-app 简介 uni-app 是一个使用 Vue.js 开发所有前端应用的框架 ...
- 品优购商城——列表页
效果图: 列表页文件 list.html <!DOCTYPE html> <html lang="en"> <head><meta cha ...
- 品优购商城——手机详情页(作业)
效果图: 手机详情页文件 detail.html <!DOCTYPE html> <html lang="en"> <head><meta ...
- 品优购商城——注册页
效果图: 注册页文件 register.html <!DOCTYPE html> <html lang="en"> <head><meta ...
- pink老师【品优购商城】
最初 好久之前学过H5 CSS JS,跟着黑马的pink老师写了品优购商城的静态界面,复习一下的同时也学到了许多东西! 收获 链接:https://pan.baidu.com/s/1P5FautCJC ...
- IDEA 搭建黑马品优购商城
前言 由于刚开始用 eclipse 跟着视频开发品优购,开发到中期发现 eclipse 用的还是JDK7无法使用Lambda表达式,而且在公司里面用的都是IDEA,所以趁着还没写多少代码,赶紧更换开发 ...
- 大学web基础期末大作业~仿品优购商城页面制作(HTML+CSS+JavaScript)
HTML网页设计期末课程大作业~~仿品优购页面制作(HTML+CSS+JavaScript) 关于HTML期末网页制作,大作业A+水平 ~仿品优购网页作业HTML+CSS+JavaScript实现,共 ...
- 纯HTML、CSS实现搭建品优购商城的静态网站 这布局还好吗?超适合前端入门者
这个静态网站非常适合前端入门者,我们很多时候学习的都是理论知识,我们应该多动手,把理论转化为实践,前端知识多,多动手才能加深印象. 网站地址:在PC端,点击这里,查看完整静态网站. 下面我们先来看看静 ...
最新文章
- 实现一个完美符合Promise/A+规范的Promise
- 机器学习_周志华_问题汇总_第2周
- 【mysql】二级索引----聚簇索引和非聚簇索引-----
- PS教程第九课:背景色
- “约见”面试官系列之常见面试题第四十一篇之VUE生命周期(建议收藏)
- 任务计划、chkconfig工具、systemd管理服务、unit、target
- java,js获取数组最大/小值
- maven配置sqlServer的依赖
- 【Level 08】U08 Positive Attitude L3 What a life
- 从程序员到项目经理(13):如何管理自己的时间(下)【转载】
- Android异常处理——try、catch、finally、throw、throws
- linux学习笔记:磁盘格式化与磁盘检验命令
- VC中自动改变控件位置和大小的对话框类
- js 全国城市地区编码+拼音+大写首字母
- 药事管理学名词解释和问答题题集
- 人到中年想学一门手艺自己创业好不好
- 【高数复盘】2.1导数概念
- swiper 上滑触发_在绝地求生加入滑铲等战术动作会怎么样?你们想过吗?
- 昨夜“星城”昨夜“疯”
- Git常用命令有哪些?
热门文章
- ai描边工具怎么打开_ai描边面板怎么调出来? ai找不到描边面板的解决办法
- debian linux 硬盘,Debian硬盘安装
- C++基础编程题(27)输入一个数字,为其高,一个符号*,输出该符号组成的平行四边形形状
- PWM 调光的线性降压 LED 恒流驱动器 OC7130B
- java迭代器删除元素_java迭代器中删除元素的操作
- 【ZYNQ】T9+控制板硬件概览与修复 (持续更新中)
- 《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | waitnotify | ParkUnpark | 线程状态转换 | 活跃性 | ReentrantLock)
- 首家优秀型厂商,百度智能云智能对话通过信通院权威评测!
- android 定时静音,Android实现定时自动静音小助手
- Android 信号查看,安卓Android手机怎么快速查看系统信号强度