/>
<image src=“{{item.cover}}”
mode=“aspectFill” />
删除
合计:
结算
底部操作栏样式
.user-operation{
width: 100%;
height: 100rpx;
line-height: 100rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
position: fixed;
left: 0;
bottom: 0;
}
.select-all,.total-price,.btn-primary.pay{
flex: 1; //三个盒子等分所有设备宽度
font-size: 12pt;
text-align: center;
}
加入购物车操作
逻辑分析:之前解决数据缓存问题,是为加入购物车功能做铺垫。在商品属性的级联选择中,已经获得了用户的所有要加入购物车的数据,这时候,把数据取出来在绑定到购物车页面上就可以了。
实现代码:
data: {
cart_list: [], //初始化一个空数组用来存放购物车列表
},
goIndex() { //如果购物车为空,则让用户去首页
wx.switchTab({
url: “…/index/index”
})
},
onShow: function () {
const attr_item = wx.getStorageSync(‘attr_item’); //获取数据缓存里将要加入购物车的数据
let cart_list = this.data.cart_list;
cart_list = […attr_item]; //把缓存里的数据加到购物车列表里
const select_num = cart_list.map(item => { //获取用户每次选择的数量
return item.select_num;
})
let goods_sum=select_num.reduce(function(prev,cur){
return prev+cur; //用es6的reduce()方法把用户每次选择的数量相加
});
wx.setStorageSync(‘goods_sum’, goods_sum); //再次存入缓存
this.setData({ //更新购物车列表
cart_list
});
}
购物车全选、反选、计算总价功能
这是一个很经典的问题,凡事涉及到购物车的操作,这个功能都是少不了的。
data: {
cart_list: [],
totalPrice: 0,
},
selectList(e) {
let selectAllStatus = this.data.selectAllStatus;
const index = e.currentTarget.dataset.index;
let cart_list = this.data.cart_list;
// console.log(cart_list[index].selected);
const selected = cart_list[index].selected;
cart_list[index].selected = !selected;
console.log(selected);
//购物车列表里的条目只要有一个取消,全选就取消
const symbol = cart_list.some(cart => { //这里用es6的some()函数
return cart.selected === false;
});
if (symbol) { //如果找到false,全选就取消
this.data.selectAllStatus = false;
} else {
this.data.selectAllStatus = true;
}
this.setData({ //更新数据
cart_list,
selectAllStatus: this.data.selectAllStatus
});
this.getTotalPrice();
},
getTotalPrice() { //定义一个计算总价的方法
let cart_list = this.data.cart_list;
let totalPrice = 0;
for (let i = 0; i < cart_list.length; i++) {
if (cart_list[i].selected) {
totalPrice += parseInt(cart_list[i].select_num) * parseInt(cart_list[i].price); //注意这里要用parseInt()把数量和价格取出来
}
}
//更新总价
this.setData({
totalPrice
});
},
selectAll(e) {
let selectAllStatus = this.data.selectAllStatus;
selectAllStatus = !selectAllStatus;
let cart_list = this.data.cart_list;
for (let i = 0; i < cart_list.length; i++) {
cart_list[i].selected = selectAllStatus; //全选为true,则所有购物车列表为true,全选为false,则所有购物车列表为false
}
//更新数据
this.setData({
cart_list,
selectAllStatus
});
this.getTotalPrice();
}
删除购物车操作
data: {
startX: 0, //开始坐标
startY: 0,
},
//滑动事件处理
touchmove(e) {
let
index = e.currentTarget.dataset.index, //获取当前索引
startX = this.data.startX, //获取开始X坐标
startY = this.data.startY, //获取开始Y坐标
touchMoveX = e.changedTouches[0].clientX, //滑动变化坐标
touchMoveY = e.changedTouches[0].clientY, //滑动变化坐标
//获取滑动角度
angle = this.getAngle({
X: startX,
Y: startY
}, {
X: touchMoveX,
Y: touchMoveY
});
this.data.cart_list.forEach(function (v, i) {
v.isTouchMove = false
if (Math.abs(angle) > 30) return;//用户滑动超过30度,删除按钮就不出来
if (i == index) {
if (touchMoveX > startX) //右滑
v.isTouchMove = false
else //左滑
v.isTouchMove = true
}
})
//更新数据
this.setData({
cart_list: this.data.cart_list
})
},
getAngle(start, end) {
let X = end.X - start.X,
Y = end.Y - start.Y
//返回角度 /Math.atan()返回数字的反正切值
return 360 * Math.atan(Y / X) / (2 * Math.PI);
},
delCartItem(e) {
const index=e.currentTarget.dataset.index; //获取购物车要删除商品的下标
this.data.cart_list.splice(index, 1);
wx.clearStorageSync(“select_num”);
this.setData({
cart_list: this.data.cart_list
});
}
七、商品的匹配及搜索功能实现
页面结构分析:先把搜索提示框固定定位到搜索栏下方,如果搜索到商品,则用商品展示模版输出该数据
搜索
逻辑分析:
我的实现思路是:
-
如果匹配到商品,搜索框下方就要让搜索提示框显示;
-
当用户输入搜索的内容为空,搜索提示框隐藏
-
用户点击搜索按钮,则把所有匹配到的商品列表显示出来,注意要模糊搜索,不区分大小写,提高用户体验;
-
用户点击匹配到的商品条目,则搜索该商品
实现方法:
filter()
+indexOf()
+toLowerCase()
;
代码如下:
import showDetail from “…/…/modules/showDetail”;
const app=getApp();
Page({
/**
- 页面的初始数据
*/
data: {
goods_list:[],
search_list:[],
is_hidden:true
},
searchInput(e){
let search_list=this.getList(e.detail.value); //获取用户的输入值
if(e.detail.value==“”){ //如果用户没输入,搜索提示列表置空,并且让搜索提示框隐藏
search_list=[];
this.data.is_hidden=true;
}else{
this.data.is_hidden=false;
}
//更新数据
this.setData({
search_list,
is_hidden:this.data.is_hidden
});
},
search(e){
//按关键字筛选商品,如果关键字匹配到商品名称,则返回该商品列表
const keywords=wx.getStorageSync(‘keywords’);
wx.showLoading({
title: ‘请稍等’,
});
setTimeout(()=>{
this.setData({
goods_list:this.getList(keywords),
is_hidden:true //如果搜索到了商品,就让搜索框隐藏
});
wx.hideLoading();
},500);
},
showDetail,
showItemDetail(e){
//按关键字筛选商品,如果关键字匹配到商品名称,则返回该商品列表
const header=e.currentTarget.dataset.header.toLowerCase();
console.log(header);
wx.showLoading({
title: ‘请稍等’,
})
setTimeout(()=>{
wx.hideLoading()
this.setData({
goods_list:this.getList(header),
is_hidden:true
});
},500)
},
/**
- attr:需要匹配筛选的数据
*/
getList(attr){ //定义一个获取商品标题的方法
return app.globalData.phone.goods_list.filter(item=>{
return item.header.toString().toLowerCase().indexOf(attr)>-1;
});
}
})
八、收货地址页
实现思路:用数据缓存和数据绑定来控制input的disabled实现实时编辑
代码如下:
// pages/address/address.js
Page({
data: {
receiverName: “”,
mobile: “”,
addressDetail: “”,
postCode: “”,
isDisabled: false,
isComplete: false,
buttonTitle: “保存”
},
formSubmit(e) {
const addrInfo = e.detail.value;
let {receiverName,mobile,addressDetail,postCode}=addrInfo; //把data里的数据结构出来
if(receiverName==“”||mobile==“”||addressDetail==“”||postCode==“”){
this.data.isComplete=false;
wx.showModal({
title:“提示”,
content:“请完善信息”,
showCancel:false
});
}else if(!/1[3,4,5,7,8]\d{9}$/.test(mobile)){ //判断手机号格式
wx.showModal({
title:“提示”,
content:“手机号格式不规范”,
showCancel:false
});
}else if(!/2{6}$/.test(postCode)){
wx.showModal({
title:“提示”,
content:“邮政编码不规范”,
showCancel:false
});
}else{
this.data.isComplete=true;
wx.setStorageSync(‘addrInfo’, addrInfo);
}
this.setData({
isDisabled: true,
isComplete: this.data.isComplete
});
},
updateAddr(e){
this.setData({
isDisabled:false,
isComplete:false,
buttonTitle: “保存”
});
},
/**
- 生命周期函数–监听页面加载
*/
onLoad: function (options) {
let addrInfo=wx.getStorageSync(“addrInfo”);
console.log(addrInfo);
let {receiverName,mobile,addressDetail,postCode}=addrInfo;
this.setData({
receiverName,
mobile,
addressDetail,
postCode,
isDisabled: true,
isComplete:true,
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
总结
我在成长过程中也是一路摸爬滚打,没有任何人的指点,所以走的很艰难。例如在大三的时候,如果有个学长可以阶段性的指点一二,如果有已经工作的师兄可以告诉我工作上需要什么,我应该前面的三年可以缩短一半;后来去面试bat,失败了有5、6次,每次也不知道具体是什么原因,都是靠面试回忆去猜测可能是哪方面的问题,回来学习和完善,当你真正去招人的时候,你就会知道面试记录是多么重要,面试官可以从面试记录里看到你的成长,总是去面试,总是没有成长,就会被定义为缺乏潜力。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
外链图片转存中…(img-2QCbTk4q-1712594583035)]
[外链图片转存中…(img-1f2MPbm0-1712594583036)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-4VlVxqrS-1712594583037)]
总结
我在成长过程中也是一路摸爬滚打,没有任何人的指点,所以走的很艰难。例如在大三的时候,如果有个学长可以阶段性的指点一二,如果有已经工作的师兄可以告诉我工作上需要什么,我应该前面的三年可以缩短一半;后来去面试bat,失败了有5、6次,每次也不知道具体是什么原因,都是靠面试回忆去猜测可能是哪方面的问题,回来学习和完善,当你真正去招人的时候,你就会知道面试记录是多么重要,面试官可以从面试记录里看到你的成长,总是去面试,总是没有成长,就会被定义为缺乏潜力。
[外链图片转存中…(img-Kp5230Nk-1712594583037)]
[外链图片转存中…(img-w6DVH166-1712594583038)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-Tz4DbQ9m-1712594583038)]