黑马优购项目讲解

2023-10-18 20:10
文章标签 讲解 黑马 项目 优购

本文主要是介绍黑马优购项目讲解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

黑马优购项目讲解

一. 准备工作

  我们首先拿到一个项目会看到他的一个文档,里面有他所需要接受的数据的接口,然后我们在微信开发程序中创建好项目文件夹。1)先把我们所需要的的接口请求用promise进行封装 ,

封装一个函数,把它们写在一个文件夹里,当那个页面需要那里的数据就进行调用就可以。
2)把我们所必须要的页面也先配置好,当然还有底部导航,以及路由的配置,以及一些全局的配置。
3)看项目文档时,查看每个页面是否有共同的地方,如果有就用把相同的地方封装成一个组件,进行调用

二. 首页的操作

1) 当我们的准备工作完成后,当然先写的就是首页,
在黑马优购中,页有一个搜索框,和一个Swiper,在这里我分别封装了一个组件,进行了调用。

在这里插入图片描述

2)然后还有中间的导航,和下面楼层的渲染,在这里只要用app.http接受下你封装的接口数据就行在,再放一个数组,在页面循环进行渲染,在这里我们的导航点击可以跳转到下一个页面---------分类页面,所以我们要给导航注册个点击事件。

分类页面的主要操作

对于分类页面,主要难点是在,导航的切换引起所需商品的改变,
1)在这里我们请求完数据后,把左边的导航数据储存在一个数组内渲染页面,右边商品也有一个数组进行储存,但渲染,先渲染的是第一页的数据。
这里简单的就是来说一个tab切换,不过我在这里用到了微信小程序中的swiper属性中的current属性
1)在导航上设置了一个自定义属性,我这里要的是下标,然后用三元表达式,来判断class类名,并给他绑定一个点击事件
2) 再写一个current事件, current事件只在change发生改变时才会触发。
在导航的点击事件中的操作是,先获取下标我这里是e.currentTarget.dataset.index,
然后his.data.navleft[index].children储存商品下面导航的数据,点击下标,然后然那个current和那个index有同样的值,进行储存,渲染就可以了。
js代码如下

Page({/*** 页面的初始数据*/data: {navleft: [],index: "",resulty: [],currentTab: 0,},menu: function (e) {// 先获取下标let index = e.currentTarget.dataset.index// 储存下标对应的数据let resulty = this.data.navleft[index].childrenconsole.log(index);this.setData({currentTab: e.currentTarget.dataset.index,resulty: resulty})},}
 wxml代码
<view class="nav_big"><scroll-view scroll-y class="navleft_big"><view wx:for="{{navleft}}" class="nav_left {{currentTab==index ? 'on' : ''}}" wx:key="item" data-index="{{index}}"bindtap="menu">{{item.cat_name}}</view></scroll-view><scroll-view scroll-y class="nav_right" current="{{currentTab}}"><view wx:for="{{resulty}}" wx:key="index" class="swiperl-box"><text>/{{item.cat_name}}/</text><view class="nav"><block wx:for="{{item.children}}" wx:key="index"><view class="nav_img" bindtap="listchange" data-id="{{item.cat_id}}"><image src="{{item.cat_icon}}" class="images"></image><text>{{item.cat_name}}</text></view></block></view></view></scroll-view>
</view>

列表页面

在列表页面最关键的也就是下拉刷新和上拉加载
对于下拉刷新的具体操作
1)现在要实现下拉刷新的页面的json中定义 “enablePullDownRefresh”:true,
“backgroundTextStyle”:"dark"这两个属性,他才能实现下拉
2)在data写一个数组来接受第一次接口接收到的数据,

data{lister: [ ],    //第一次请求到页面的数据  
}

3)在onPullDownRefresh中写入具体的操作
先写一个wx.showLoading在 数据请求之前, 写一个关闭在数据请求结束后
用展开运算符来写把第一次请求的数据和第二次请求来的数据进行拼接
并储存渲染

  onPullDownRefresh: function () {let that = this;//加载数据中的的Laodingwx.showLoading({title: '加载中...',})//再次向接口请求的数据
app.http.goods_lists({cid: that.options.cid}, 'get').then(res => {//  数据请求出来后关闭Lladingwx.hideLoading()let {data: {message: {goods}}} = res//定义res 数组 里面的数据是consloe.log(res)下的data下的message下goods//利用展开运算符将之前保留的数据和又请求到的数据进行新的存储that.setData({// 用展开运算符 保存数据shopListlister: [...goods, ...that.data.lister]})wx.stopPullDownRefresh();   //数据请求成功后就停止下拉wx.hideLoading()             //隐藏动画},

上拉加载
1)首先我们先写一个对象用来存取从接口中请求来我们所需要的数据,例如我写的一个项目中,

  data{lister: [ ],    //第一次请求到页面的数据  newsquery: {query: "",      cid: "",      pagesize: 10,   // 每页的条数pagenum: 1,     // 当前页数},totalnum: "",  // 总条数totalsize: 3,  // 总页数
}

在 onReachBottom写具体的操作步骤

 onReachBottom: function () {that.totalsize = Math.ceil(res.data.message.total / that.data.newsquery.pagesize)console.log(this.totalsize, this.data.newsquery.pagenum);// 当前总条数   和   当前每页的条数if (this.totalsize == this.data.newsquery.pagenum) {wx.showToast({title: '没有更多数据',})//弹出提示框} else {// 页数增加this.data.newsquery.pagenum++app.http.goods_lists({cid: that.options.cid}, 'get').then(res => {//  数据请求出来后关闭Lladingwx.hideLoading()let {data: {message: {goods}}} = res//定义res 数组 里面的数据是consloe.log(res)下的data下的message下goods//利用展开运算符将之前保留的数据和又请求到的数据进行新的存储that.setData({// 用展开运算符 保存数据shopListlister: [...goods, ...that.data.lister]})}wx.hideLoading()  // 数据请求成功后隐藏请提示},

再给每个商品注册个点击事件,跳转到详情页

详情页的主要内容

详情页的主要内容也就是个添加到购物车,收藏,以及分享,联系客服
1)其中对于分享和联系客服的实现比较简单,只要写个button按钮,
设置个
open-type属性就可以了,share为分享,contact为联系客服
Wxml代码如下

<button class="nav_left" open-type="contact"><text class="iconfont icon-kefu"> </text><view>客服</view>
</button ><button class="nav_left" open-type="share"><text class="iconfont icon-kefu"> </text><view>分享</view>
</button >

2)而我写的添加购物车和,收藏数据又有些类似,都是声明一个对象,对需要的数据进行接收储存,用数据的下标判断他是否被加入购物车(收藏),在购物车(收藏)中如果没有加入,就添加, 如果有,在在购物车数量加一,不进行数据的添加,而收藏,如果下标相同,说明已添加过了,再次点击就是删除
具体代码如下

js

Page({/*** 页面的初始数据*/data: {Snum:0,isCollect:false,},obj:{collect:[]},collect() {let collect = wx.getStorageSync('collect') || []console.log(collect);
let names=this.data.message.goods_name;
let price=this.data.message.goods_price;
let imgs=this.data.message.goods_big_logo;
let  id=this.data.message.goods_id;
let k=false;
let num=1;
let flag=false;
collect.forEach((item,index)=>{
if(item.id==id){k=trueconsole.log();collect.splice(index,1)wx.showToast({title: '收藏取消',}) this.setData({isCollect:false})
}
});
if(!k){collect.push({
imgs,
num ,
id,
names,
flag,
price  
})wx.showToast({title: '收藏成功',
})
this.setData({isCollect:true
})}
console.log(collect);
wx.setStorageSync('collect', collect);
this.getTotalPrice()
},//在数据请求完成后,再次调用下收藏数据,让一进页面就行判断看是否储存过,判断图标的显示状态
onLoad: function (options) {let  id=this.data.message.goods_id;let arrs=wx.getStorageSync('collect') ||[]console.log(arrs);arrs.forEach(item=>{if(item.id=id){this.setData({isCollect:true})}})})},
}
  getTotalPrice() {let arr = wx.getStorageSync("collect");
console.log(arr);let Snum = 0for (let i = 0; i < arr.length; i++) {Snum += arr[i].num}console.log(Snum)
wx.setStorageSync('Snum', Snum)},
})

加入购物车的js代码

  add() {console.log(this.data.message)
let names=this.data.message.goods_name;
let price=this.data.message.goods_price;
let imgs=this.data.message.goods_big_logo;
let  id=this.data.message.goods_id;
let k=false;
let num=1;
let flag=false;
this.obj.cart.forEach(item=>{if(item.id==id){k=trueitem.num++}
});
if(!k){
this.obj.cart.push({imgs,num ,id,names,flag,price  
})}wx.setStorageSync('cart', this.obj.cart);wx.showToast({title: '数据成功',})
},

然后点击购物车可以跳转到购物车页面

购物车页面
主要内容也就是全选反选,总价以及计数器和,获取地址
在全选和复选框的交互中,对于全选,我们可以给每一个复选框都设置一个属性例如flag,未选中时为false ,当全选选中时,把它们的flag都变true 并进行渲染,这样实现了全选
而交互运用了checkbox-group标签,给他绑定了一个bindchange事件,给每个复选框都绑定一个value值,用一个数组进行储存,然后判断储存数据的数组长度是否等于这个长度,如果等于就让flag=true,
后面让复选框数组的数据进行循环,让flag都false,再把选中的数据进行循环让flag都为true并进行储存
代码入下(其中包含了进步器以及总价)
Wxml中

    <view wx:else><view><view>{{address.userName}}</view><view>{{address.all}}</view></view><view>{{address.telNumber}}</view></view>
</view><view class="left">优购生活馆</view>
<scroll-view scroll-y>
<checkbox-group bindchange="changes"><view wx:for="{{arr}}" wx:key="index" class="shopcar"><view class="son"><checkbox checked="{{item.flag}}" value="{{index}}" bindtap="change"></checkbox></view><view class="bigs"><image src="{{item.imgs}}"></image><view class="text"><text class="top">{{item.names}}</text><text class="foot">{{item.price}}</text><view class="leep"><text class="btn1" bindtap="reduce"  data-index="{{index}}">-</text><text class="lsp">{{item.num}}</text><text class="btn2" bindtap="plus" data-index="{{index}}">+</text></view></view></view></view>
</checkbox-group></scroll-view>
<view class="footer"><view class="all" ><checkbox bindtap="all"  checked="{{checked}}" ></checkbox>全选</view><view class="snum"><view class="box"><view class="top"> 合计:<text>{{totalPrice}}</text></view><view class="foots">包含运费</view></view></view><view class="zong" bindtap="pay">结算<text>({{Snum}})</text></view>
</view>

js代码如下

  data: {address: {},Snum: 0,arr: [],totalPrice: 0,checked: false,// min:[]},pay() {if (this.data.Snum == 0) {wx.showToast({title: "您还没有选购商品"});return;} else {wx.navigateTo({url: '/pages/pay/pay'});}},changes(e) {console.log(e);let arr = this.data.arrlet min = e.detail.value;let flag = false;if (min.length == arr.length) flag = true;arr.forEach(item => {item.flag = false;})min.forEach(item => {this.data.arr[item].flag = true;})this.setData({checked: flag,arr: arr})this.getTotalPrice()},all() {this.setData({checked: !this.data.checked})if (this.data.checked == true) {this.data.arr.forEach((item) => {item.flag = true})this.setData({arr: this.data.arr})} else {this.data.arr.forEach((item) => {item.flag = false})this.setData({arr: this.data.arr})}this.getTotalPrice()},plus(e) {console.log(e);let index = e.currentTarget.dataset.indexlet arr = this.data.arrconsole.log(arr)let num = arr[index].num;num = num + 1;arr[index].num = num;console.log(arr);this.setData({arr: arr});this.getTotalPrice()},reduce(e) {let index = e.currentTarget.dataset.indexlet arr = this.data.arrlet num = arr[index].num;num = num - 1;let that = thisarr[index].num = num;if (arr[index].num <= 0) {wx.showModal({title: "是否删除",success(res) {if (res.confirm) {arr.splice(index, 1)that.setData({arr: arr});return} else if (res.cancel) {}}})}console.log(arr);this.setData({arr: arr});this.getTotalPrice()},getTotalPrice() {let arr = this.data.arr;let total = 0;let Snum = 0console.log(arr)let  shoppay=arr.filter(item=>{return   item.flag==true})let shoppays=wx.setStorageSync('shoppay', shoppay)console.log(shoppay);for (let i = 0; i < arr.length; i++) {if (arr[i].flag) {total += arr[i].num * arr[i].price;Snum += arr[i].num}}console.log(total)this.setData({shoppay:shoppays,arr: arr,Snum: Snum,totalPrice: total.toFixed(2)});},

获取地址详情

这个页面写完后会进入支付页面,支付之前会先让你登录,而你登录的具体操作是:
在你的登录按钮注册个点击事件,然后在点击事件中用微信中的wx.login的方法来
获取code,创建一个对象来收需要的值 ,然后把这个对象作为参数去请求登录接口,
如果登录成功就会返回一个token的值,储存并返回一下支付页面就行了。 我用的原生写了个promise封装
详情

登录的具体js js详情

在我的页面会有一个获取头像的操作,具体j代码如下

  data: {userInfo: {},hasUserInfo: false,},getUserProfile(e){console.log(e);wx.getUserProfile({desc: '用于完善会员资料',success: (res) => {console.log(res);this.setData({userInfo: res.userInfo,hasUserInfo: true})wx.navigateBack({delta: 1});wx.setStorageSync('user', res.userInfo)} })wx.setStorageSync('user', this.data.userInfo)
},

WXml

<button bindtap="getUserProfile">登录</button>

这篇关于黑马优购项目讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/234897

相关文章

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

SpringBoot项目中Maven剔除无用Jar引用的最佳实践

《SpringBoot项目中Maven剔除无用Jar引用的最佳实践》在SpringBoot项目开发中,Maven是最常用的构建工具之一,通过Maven,我们可以轻松地管理项目所需的依赖,而,... 目录1、引言2、Maven 依赖管理的基础概念2.1 什么是 Maven 依赖2.2 Maven 的依赖传递机

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

Python 中 requests 与 aiohttp 在实际项目中的选择策略详解

《Python中requests与aiohttp在实际项目中的选择策略详解》本文主要介绍了Python爬虫开发中常用的两个库requests和aiohttp的使用方法及其区别,通过实际项目案... 目录一、requests 库二、aiohttp 库三、requests 和 aiohttp 的比较四、requ

SpringBoot项目启动后自动加载系统配置的多种实现方式

《SpringBoot项目启动后自动加载系统配置的多种实现方式》:本文主要介绍SpringBoot项目启动后自动加载系统配置的多种实现方式,并通过代码示例讲解的非常详细,对大家的学习或工作有一定的... 目录1. 使用 CommandLineRunner实现方式:2. 使用 ApplicationRunne

使用IntelliJ IDEA创建简单的Java Web项目完整步骤

《使用IntelliJIDEA创建简单的JavaWeb项目完整步骤》:本文主要介绍如何使用IntelliJIDEA创建一个简单的JavaWeb项目,实现登录、注册和查看用户列表功能,使用Se... 目录前置准备项目功能实现步骤1. 创建项目2. 配置 Tomcat3. 项目文件结构4. 创建数据库和表5.

Python项目打包部署到服务器的实现

《Python项目打包部署到服务器的实现》本文主要介绍了PyCharm和Ubuntu服务器部署Python项目,包括打包、上传、安装和设置自启动服务的步骤,具有一定的参考价值,感兴趣的可以了解一下... 目录一、准备工作二、项目打包三、部署到服务器四、设置服务自启动一、准备工作开发环境:本文以PyChar

多模块的springboot项目发布指定模块的脚本方式

《多模块的springboot项目发布指定模块的脚本方式》该文章主要介绍了如何在多模块的SpringBoot项目中发布指定模块的脚本,作者原先的脚本会清理并编译所有模块,导致发布时间过长,通过简化脚本... 目录多模块的springboot项目发布指定模块的脚本1、不计成本地全部发布2、指定模块发布总结多模

SpringBoot项目删除Bean或者不加载Bean的问题解决

《SpringBoot项目删除Bean或者不加载Bean的问题解决》文章介绍了在SpringBoot项目中如何使用@ComponentScan注解和自定义过滤器实现不加载某些Bean的方法,本文通过实... 使用@ComponentScan注解中的@ComponentScan.Filter标记不加载。@C

javafx 如何将项目打包为 Windows 的可执行文件exe

《javafx如何将项目打包为Windows的可执行文件exe》文章介绍了三种将JavaFX项目打包为.exe文件的方法:方法1使用jpackage(适用于JDK14及以上版本),方法2使用La... 目录方法 1:使用 jpackage(适用于 JDK 14 及更高版本)方法 2:使用 Launch4j(