优购商城项目讲解
项目目录:
1.首先创建项目,然后在微信公众平台官网配置白名单
2.在全局的app.json里面配置需要的路由
"pages":[
"pages/index/index",
"pages/category/category",
"pages/goods_list/goods_list",
"pages/goods_detail/goods_detail",
"pages/cart/cart",
"pages/collect/collect",
"pages/order/order",
"pages/search/search",
"pages/user/user",
"pages/feedback/feedback",
"pages/login/login",
"pages/auth/auth",
"pages/pay/pay"
],
3.在app.json里面设置底部的tabBar跳转路由
"tabBar": {
"list": [{
"pagePath": "pages/index/index",//页面路径
"text": "首页",
"iconPath": "/assets/tabbar/home.png",//icon-font图标
"selectedIconPath": "/assets/tabbar/home-o.png"//切换的变色图标
},
{
"pagePath": "pages/category/category",
"text": "分类",
"iconPath": "/assets/tabbar/category.png",
"selectedIconPath": "/assets/tabbar/category-o.png"
},
{
"pagePath": "pages/cart/cart",
"text": "购物车",
"iconPath": "/assets/tabbar/cart.png",
"selectedIconPath": "/assets/tabbar/cart-o.png"
},
{
"pagePath": "pages/user/user",
"text": "我的",
"iconPath": "/assets/tabbar/my.png",
"selectedIconPath": "/assets/tabbar/my-o.png"
}
]
},
4.创建request文件夹封装接口的baseUrl,在request文件夹里创建retch.js、api.js和http.js,详情请看我写的博客
点击查看:Promise封装wx.request
index首页
1.首页里面分4部分,搜索组件、轮播图组件、导航和楼层
2.首先先写头部的搜索子组件,创建components文件夹用来放子组件,在里面创建search子组件
在子组件中写完之后在首页的json中引入,
{
"usingComponents": {
"search-input":"/components/search/searchInput",
"w-swiper":"/components/swiper/swiper"
},
"navigationBarTitleText":"优购首页"
}
然后在首页的wxml里面标签引入
点击search搜索框跳转到搜索页面,使用小程序内置的跳转按钮navigator,url是需要跳转的路径,
跳到搜索页面
搜索
在input框中输入字符,下面显示搜索的内容,具体有以下步骤:
首先在search.wxml的input标签里添加一个事件bindinput
<input type="text" placeholder="请输入您要搜索的商品" class="tet"
bindinput="input" value="{{value}}"/>//value是input标签特有的属性,bindinput可以实时监听输入的内容
然后在js中写功能,
data: {
val:[],//空的数组接受数据
value:''//接收输入框的内容
},
//点击事件
input(e){
console.log(e);
//打印出来e.detail.value就是input里面输入的内容
app.http.searchs(e.detail.value).then((res)=>{
console.log(res);
//打印出来搜索接口里面的数据
//只要数据有改变就要放在setData里面
this.setData({
val:res.data.message,
value:e.detail.value
})
})
},
然后在页面渲染数据
//循坏数组
<view wx:for="{{val}}" wx:key="index">
//跳转搜索出来的内容的页面详情
<navigator class="sear" url="/pages/goods_detail/goods_detail?goods_id={{item.goods_id}}">
{{item.goods_name}}//渲染的内容
</navigator>
</view>
最后点击取消,清空搜索内容和搜索框
//如果input框输入字符长度为0就隐藏,bindtap点击事件,点击就清空内容
<view class="btn" bindtap="del" hidden="{{value.length==0}}">取消</view>
del(){
this.setData({
value:'',
val:[]
})
},
轮播图
在components文件夹里面配置轮播图子组件
在页面中写轮播图有三个属性不能少
<swiper autoplay="true" interval="2000" indicator-dots="true" >
<swiper-item wx:for="{{list}}" wx:key="index">
<image src="{{item.image_src}}" class="im"></image>
</swiper-item>
</swiper>
在子组件中写完之后在首页的json中引入,
{
"usingComponents": {
"search-input":"/components/search/searchInput",
"w-swiper":"/components/swiper/swiper"
},
"navigationBarTitleText":"优购首页"
}
然后在首页的wxml里面标签引入,然后父传子
<!-- 轮播图 -->
<w-swiper list="{{sw}}"></w-swiper>//自定义属性list
//js
data: {
sw:[],//轮播图数组
},
//接收轮播图接口的数据
app.http.banner().then((res)=>{
// console.log(res);
let{data:{message}}=res //结构赋值
this.setData({
sw:message
})
})
在子组件中接收父组件传过来的数据,然后进行页面渲染
properties: {
list:{
type:Array,
value:[]
}
},
导航
data: {
navs:[],//导航数组
},
//接收导航接口的数据
app.http.nav().then((res)=>{
// console.log(res);
let{data:{message}}=res
this.setData({
navs:message
})
})
页面进行渲染
<view class="box">
<navigator wx:for="{{navs}}" wx:key="index" class="box1" url="/pages/category/category" open-type="switchTab">
<image src="{{item.image_src}}" class="icon"></image>
</navigator>
</view>
楼层
data: {
floos:[],//楼层数组
},
//接收楼层接口的数据
app.http.floor().then((res)=>{
console.log(res);
let{data:{message}}=res
this.setData({
floors:message
})
})
然后页面进行渲染
<!-- 楼层 -->
<view class="floor-top">
<view wx:for="{{floors}}" wx:key="floor_title" wx:for-item="tt1" wx:index-index="index1">
<!-- 标题 -->
<view class="floor-title">
<image mode="widthFix" src="{{tt1.floor_title.image_src}}"></image>
</view>
<!-- 内容 -->
<view class="floor-center">
<navigator wx:for="{{tt1.product_list}}" wx:key="name" wx:for-item="tt2" wx:index-index="index2">
<image src="{{tt2.image_src}}"></image>
</navigator>
</view>
</view>
</view>
分类页面
1.分类页面分为搜索组件、左侧导航和右边内容区域
首先引入搜索子组件
用scroll-view标签来实现滑动效果,点击左侧的标题右侧出现对应的内容
页面渲染
//左侧导航
<view class="cate-left">
<scroll-view scroll-y class="cate-left1">
//自定义data-index属性
<view wx:for="{{cates}}" data-index="{{index}}" wx:key="index" bindtap="taps"
class="{{curtap===index?'active':''}}">{{item.cat_name}}</view>
</scroll-view>
</view>
//右侧内容
<view class="cate-right">
<scroll-view scroll-y="true" class="iu">
<view wx:for="{{childs}}" wx:key="index" wx:for-item="item1" wx:for-index="index1">
<view class="cate-u"> /{{item1.cat_name}}/</view>
<view class="aa">
<navigator wx:for="{{item1.children}}" wx:key="index" wx:for-item="item2" wx:for-index="index2" class="bb" url="/pages/goods_list/goods_list?cid={{item2.cat_id}}">
<image src="{{item2.cat_icon}}" class="im"></image>
<view>{{item2.cat_name}}</view>
</navigator>
</view>
</view>
</scroll-view>
</view>
在js中写逻辑代码
//点击事件
taps(e){
console.log(e.currentTarget);
console.log(this.data.curtap);
app.http.cate().then((res)=>{
console.log(res);
this.setData({
curtap:e.currentTarget.dataset.index, //找对应的元素的下标
childs:res.data.message[e.currentTarget.dataset.index].children
//根据获取的下标来获取对应的数据
})
})
},
onl oad: function (options) {
app.http.cate().then((res)=>{
console.log(res);
this.setData({
cates:res.data.message,
childs:res.data.message[0].children
})
})
},
商品列表、上拉加载、下拉刷新
首先渲染出来页面
下拉刷新、上拉加载,点击查看详情
上拉加载:
公式:总页数 / 每页多少条数据 = 一共有多少页
注意:因为我们页数如果是10 / 3 肯定有小数点,所以这里我们需要向上取整的。
let page = Math.ceil(total / 10); // 当然,这个10也可以是个变量的嘛。
我们在监听到用户触底的时候,首先让当前页num+1,然后判断一下是否大于我们计算出来的总页就可以了。下面我们就去请求num页的数据
商品详情、收藏、分享、客服、加入购物车
首先渲染出来页面
收藏、分享、客服
点击查看详情
加入购物车,写一个点击事件
//加入购物车
add(){
//从本地拿购物车的数组
let cart=wx.getStorageSync('cart') ||[]
//根据id来找到该商品的下标
let index =cart.findIndex(v=>v.goods_id===this.data.all.goods_id)
//判断商品是否已经在购物车
if(index===-1){
//第一次添加
this.data.all.num=1
this.data.all.checked=false //给一个checked用来之后购物车的选中
cart.push(this.data.all) //添加的新商品push进数组
wx.setStorageSync('cart',cart) //存在本地
}else{
//商品存在就数量++
cart[index].num++
wx.setStorageSync('cart',cart)
}
//小程序内置方法 消息提示框
wx.showToast({
title: '加入成功',
icon:'success',
mask:true
})
},
购物车
首先是头部的获取取货地址,查看详情点击
然后写我们的购物车列表页面,之前在详情页已经写过加入购物车,所以我们只需要拿本地存储的购物车数据渲染出来即可:
// pages/cart/cart.js
Page({
/**
* 页面的初始数据
*/
data: {
cart:[],
ckAll:false,
price:0,
num:0,
address:{},
},
// 复选框
ck(e){
console.log(e);
const cks=e.currentTarget.dataset.id
let{cart}=this.data
let index=cart.findIndex(v=>v.goods_id===cks)
cart[index].checked=!cart[index].checked
this.shopcar(cart)
},
// 全选
ckall(){
let{cart,ckAll}=this.data
ckAll=!ckAll
cart.forEach(v=>v.checked=ckAll)
this.shopcar(cart)
},
// 封装调用函数
shopcar(cart){
let ckAll=true
let price=0
let num=0
cart.forEach(v=>{
if(v.checked){
price+=v.num*v.goods_price
num+=v.num
}else{
ckAll=false
}
})
ckAll=cart.length!=0?ckAll:false
this.setData({
cart,
price,
num,
ckAll
})
wx.setStorageSync('cart', cart)
},
// 减
red(e){
const id=e.currentTarget.dataset.id
let{cart}=this.data
let index=cart.findIndex(v=>v.goods_id===id)
if(cart[index].num<=1){
cart[index].num=1
}else{
cart[index].num--
}
this.shopcar(cart)
},
// 添加
add(e){
const id=e.currentTarget.dataset.id
let{cart}=this.data
let index=cart.findIndex(v=>v.goods_id===id)
cart[index].num++
this.shopcar(cart)
},
// 收货地址
gomap(){
wx.chooseAddress({
success: (result) => {
console.log(result);
let address=result;
address.all=address.provinceName+address.cityName+address.countyName+address.detailInfo
wx.setStorageSync('address', address)
},
})
},
//跳转支付页面
gopays(){
if(!this.data.address.userName){
wx.showToast({
title: '您没有选择地址',
})
return
}
if(this.data.num==0){
wx.showToast({
title: '您没有选择商品',
})
return
}
wx.navigateTo({
url: '/pages/pay/pay',
})
},
/**
* 生命周期函数--监听页面加载
*/
onl oad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
const cart=wx.getStorageSync('cart')|| []
const address=wx.getStorageSync('address') ||[]
this.setData({
cart:cart,
address
})
this.shopcar(cart)
},
然后我们在结算时会写支付的流程点击查看详情
我的
首先是登录页面,使用button的open-type的内置属性值来实现获取登录的个人信息查看详情
除登录外还有一些页面:
收藏页面,从本地拿到我们收藏的列表进行渲染即可