五、收藏页面
关键点
本地存储加载收藏数据
1、获取缓存中的商品收藏的数组
let collect = wx.getStorageSync("collect") || [];
2、判断当前商品是否被收藏
let isCollect = collect.some(v=> v.goods_id === this.GoodsInfo.goods_id);
// 点击 商品收藏图标
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中的属性 isCollect
this.setData({
isCollect
})
}
效果图
六、购物车页面——逻辑难点
关键点
1、收货地址
2、复选框组件
3、结算
import { getSetting, chooseAddress, openSetting, showModal ,showToast} from "../../utils/asyncWx.js";
Page({
data: {
address: {},
cart: [],
allChecked: false,
totalPrice: 0,
totalNum: 0
},
onShow() {
// 获取缓存中的收货地址信息
const address = wx.getStorageSync("address");
// 获取缓存中的购物车数据
const cart = wx.getStorageSync("cart") || [];
this.setData({ address });
this.setCart(cart);
},
// 点击 收货地址
async handleChooseAddress() {
try {
// 1 获取 权限状态
const res1 = await getSetting();
const scopeAddress = res1.authSetting["scope.address"];
// 2 判断 权限状态
if (scopeAddress === false) {
await openSetting();
}
// 4 调用获取收货地址的 api
let address = await chooseAddress();
address.all = address.provinceName + address.cityName + address.countyName + address.detailInfo;
// 5 存入到缓存中
wx.setStorageSync("address", address);
} catch (error) {
console.log(error);
}
},
// 商品的选中
handeItemChange(e) {
// 1 获取被修改的商品的id
const goods_id = e.currentTarget.dataset.id;
// 2 获取购物车数组
let { cart } = this.data;
// 3 找到被修改的商品对象
let index = cart.findIndex(v => v.goods_id === goods_id);
// 4 选中状态取反
cart[index].checked = !cart[index].checked;
this.setCart(cart);
},
// 设置购物车状态同时 重新计算 底部工具栏的数据 全选 总价格 购买的数量
setCart(cart) {
let allChecked = true;
// 1 总价格 总数量
let totalPrice = 0;
let totalNum = 0;
cart.forEach(v => {
if (v.checked) {
totalPrice += v.num * v.goods_price;
totalNum += v.num;
} else {
allChecked = false;
}
})
// 判断数组是否为空
allChecked = cart.length != 0 ? allChecked : false;
this.setData({
cart,
totalPrice, totalNum, allChecked
});
wx.setStorageSync("cart", cart);
},
// 商品全选功能
handleItemAllCheck() {
// 1 获取data中的数据
let { cart, allChecked } = this.data;
// 2 修改值
allChecked = !allChecked;
// 3 循环修改cart数组 中的商品选中状态
cart.forEach(v => v.checked = allChecked);
// 4 把修改后的值 填充回data或者缓存中
this.setCart(cart);
},
// 商品数量的编辑功能
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);
}
},
// 点击 结算
async handlePay(){
// 1 判断收货地址
const {address,totalNum}=this.data;
if(!address.userName){
await showToast({title:"您还没有选择收货地址"});
return;
}
// 2 判断用户有没有选购商品
if(totalNum===0){
await showToast({title:"您还没有选购商品"});
return ;
}
// 3 跳转到 支付页面
wx.navigateTo({
url: '/pages/pay/index'
});
}
})
效果图
七、订单列表页面
关键点
时间戳 格式化处理
1、时间戳 格式化处理
// 获取订单列表的方法
async getOrders(type) {
const res = await request({ url: "/my/orders/all", data: { type } });
this.setData({
orders: res.orders.map(v=>({...v,create_time_cn:(new Date(v.create_time*1000).toLocaleString())}))
})
},
八、搜索页面
关键点
防抖——防止每次输入都要发重复请求,疯狂请求
1、输入框
① 获取输入框的值
const {value}=e.detail;
② 准备发送请求获取数据
this.qsearch(value);
② 发送请求获取搜索数据
async qsearch(query){
const res=await request({url:"/goods/qsearch",data:{query}});
this.setData({
goods:res.data.message
})
},
2、防抖,利用定时器处理,一段时间确定之后加载数据
// 输入框的值改变 就会触发的事件
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);
},
效果图
九、意见反馈页面
关键点
图⽚上传
1、在wxml中
<view class="fb_tool">
<button bindtap="handleChooseImg">+</button>
<view class="up_img_item"
wx:for="{{chooseImgs}}"
wx:key="*this"
bindtap="handleRemoveImg"
data-index="{{index}}"
>
<UpImg src="{{item}}"></UpImg>
</view>
</view>
2、点击 “+” 选择图片
handleChooseImg() {
// 2 调用小程序内置的选择图片api
wx.chooseImage({
// 同时选中的图片的数量
count: 9,
// 图片的格式 原图 压缩
sizeType: ['original', 'compressed'],
// 图片的来源 相册 照相机
sourceType: ['album', 'camera'],
success: (result) => {
this.setData({
// 图片数组 进行拼接
chooseImgs: [...this.data.chooseImgs, ...result.tempFilePaths]
})
}
});
},
3、删除图片
handleRemoveImg(e) {
// 2 获取被点击的组件的索引
const { index } = e.currentTarget.dataset;
// 3 获取data中的图片数组
let { chooseImgs } = this.data;
// 4 删除元素
chooseImgs.splice(index, 1);
this.setData({
chooseImgs
})
},
4、提交图片
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: 'https://images.ac.cn/Home/Index/UploadAction/',
// 被上传的文件的路径
filePath: v,
// 上传的文件的名称 后台来获取文件 file
name: "file",
// 顺带的文本信息
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
});
}
}
效果图