上一篇文章:微信小程序开发一个小型商城(四、商品列表)
在从上一个界面跳转过来,会看到商品详情这个界面goods_detail :如下图所示:
页面分析:从上到下:一个轮播图+一个view标签存储商品名和价格等信息,再下面就是把数据渲染出来的图片,最后面就是几个按钮组成的一个绝对定位的view。
轮播图组件
轮播图组件在先前已经使用过了,在这里也就不做过多的介绍;轮播图,单击前往
<view class="detail_swiper">
<swiper autoplay circular indicator-dots interval="2000">
<!--给轮播图的子选项绑定事件。-->
<swiper-item wx:for="{{goodsObj.pics}}" wx:key="pics_id" data-url="{{item.pics_mid}}" bindtap="handlePrevewImage">
<image src="{{item.pics_mid}}" mode="widthFix" />
</swiper-item>
</swiper>
</view>
添加样式:是的图片宽占据全屏,同样是使用less文件进行编辑
page{
padding-bottom: 90rpx;
}
.detail_swiper{
swiper{
height: 70vw;
text-align: center;
image{
height: 60%;
}
}
}
商品名称+价格
先使用 view标签对其进行包裹,里面的收藏是需要引入外部图标,
<!--商品数据-->
<view class="goods_price">¥{{goodsObj.goods_price}}</view>
<view class="goods_name_row">
<view class="goods_name">{{goodsObj.goods_name}}</view>
<view class="goods_collect" bindtap = "handlecollect">
<text class="iconfont {{isCollect?'icon-xingzhuanggongnengtubiao-':'icon-shoucang'}}">
<view class="collect_test">收藏</view>
</text>
</view>
</view>
给其加上定位和样式:
.goods_price{
padding: 15rpx;
font-size: 32rpx;
font-weight: 600;
color: var(--themeColor);
}
.goods_name_row{
border-top: 5px solid #dedede;
border-bottom: 5px solid #dedede;
display: flex;
padding: 10rpx 0;
.goods_name{
flex: 5;
color: black;
font-size: 30rpx;
padding: 0 10rpx;
display: -webkit-box;
overflow: hidden;
-webkit-box-orient:vertical;
-webkit-line-clamp: 2;
}
.goods_collect{
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-left: 1px solid #000;
.icon-xingzhuanggongnengtubiao-{
color: red; }}}
图文详情
对接口获取过来的数据直接进行渲染,使用富文本标签使其不解析,直接在页面上显示效果:
<view class="goods_info">
<view class="goods_info_title">图文详情</view>
<view class="goods_info_content">
<rich-text nodes="{{goodsObj.goods_introduce}}">
</rich-text>
</view>
</view>
加上样式:
.goods_info{
.goods_info_title{
font-size: 32rpx;
color: var(--themeColor);
font-weight: 600;
padding: 20rpx;
}
}
按钮
在最下方的客服、分享、立即购买的组件,嫁过来的外部图标根据自己所选择的图标需要有所修改:比如 icon-fenxiang 是在style
文件夹下的iconfont.wxss
当中可以看到的
<view class="btm_tool">
<view class="toll_item">
<view class="iconfont icon-htmal5icon31"></view>
<view>客服</view>
<button open-type="contact"></button>
</view>
<view class="toll_item">
<view class="iconfont icon-fenxiang"></view>
<view>分享</view>
<button open-type="share"></button>
</view>
<!--使用open-type="switchTab"表示允许跳转到tabar页面-->
<navigator url="/pages/cart/index" class="toll_item" open-type="switchTab">
<view class="iconfont icon-gouwuche2"></view>
<view>购物车</view>
</navigator>
<view class="tool_item btn_cart" bindtap = "handleCartAdd">加入购物车</view>
<view class="tool_item btn_buy">立即购买</view>
</view>
给下方的view加上样式:使用绝对定位将其固定在最下方;
.btm_tool{
border-top: 1px solid #ccc;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 90rpx;
background-color: #fff;
display: flex;
.toll_item{
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 24rpx;
position: relative;
button{
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
opacity: 0; //透明度
}
}
.btn_cart{
flex: 2;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #ffa500;
color: #fff;
font-size: 30rpx;
font-weight: 600;
}
.btn_buy{
flex: 2;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: red;
color: #fff;
font-size: 32rpx;
font-weight: 600;
}
}
获取接口数据进行动态渲染
在先前的基础上发送请求获取数据,现在data下面定义存储数据的变量:
goodsObj: [], //存储数据的数组
isCollect: false,//表示是否被收藏过。
以及一个全局变量:
GoodsInfo: {}, //商品对象
发送请求获取接口返回的数据,并且将数据给goodsObj赋值:在这里使用了es7语法和外部的resquest文件,需要在最前面进行引入:使用代码段:import { request } from "../../request/index.js"; import regeneratorRuntime from "../../lib/runtime/runtime";
获取接口的时候需要传递参数,商品id
async getGoodsDetail(goods_id) {
const goodsObj = await request({
url: "/goods/detail",
data: { goods_id },
});
console.log(goodsObj);
this.GoodsInfo = goodsObj;
//获取缓存中收藏的数组
let collect = wx.getStorageSync("collect") || [];
let isCollect = collect.some((v) => v.goods_id === this.GoodsInfo.goods_id);
this.setData({
goodsObj: {
goods_name: goodsObj.goods_name,
goods_price: goodsObj.goods_price,
//在获取返回的数据当中存在webp图片格式,将其转化为jpg格式
goods_introduce: goodsObj.goods_introduce.replace(/\.webp/g, ".jpg"),
pics: goodsObj.pics,
},
});
},
怎么获取id呢?在onShow方法当中的形参options当中即带有goods_id的值,因此,我们在onShow方法当中给一个变量goods_id进行赋值获取options的值,再调用getGoodsDetail的方法,给其一个goods_id的值即可;
onShow: function (options) {
//获取去页面栈的options值传给变量current
let pages = getCurrentPages();
const current = pages[pages.length - 1].options;
const { goods_id } = current;
console.log(goods_id);
this.getGoodsDetail(goods_id);
},
在完成上述步骤之后,在APPdata当中就可以看到goodsObj的值:图下图所示:
单击轮播图预览大图
单击前往:预览大图
本质上就是获取单击轮播图图片之后获取图片的url,再传递js,根据jd当中的方法预览图片;
收藏商品事件
在appdata当中可以看到isCollect的值还是false,这时候是没有收藏,给收藏按钮绑定一个单击事件,被单击后修改isCollect的值(每一此单击后进行取反),并且修改图标的背景颜色(在less文件中已定义)。以及使用一个交互的api showToast
进行给出提示:
handlecollect(e) {
//获取isCollect的值,设置为flase,在后面修改值
let isCollect = false;
//获取缓存当中的商品收藏数组
let collect = wx.getStorageSync("collect") || [];
//判断是否被选中收藏过
let index = collect.findIndex(
(v) => v.goods_id === this.GoodsInfo.goods_id
);
//index!=-1的时候表示收藏过了
if (index !== -1) {
//表示可以找到这个商品,即被收藏过了
collect.splice(index, 1);
isCollect = false;
wx.showToast({
title: "取消收藏",
mask: true,
});
} else {
//没有收藏过,
collect.push(this.GoodsInfo);
isCollect = true;
wx.showToast({
title: "收藏成功",
mask: true,
});
}
//将数组存入缓存
wx.setStorageSync("collect", collect);
//修改isCollect的值,并且填充到data中
this.setData({
isCollect,
});
},
加入购物车
在单击购物车图标的时候给其绑定一个单击事件,使用缓存对其进行存放,
handleCartAdd(e) {
console.log("添加到购物车");
//获取缓存数据
let cart = wx.getStorageSync("cart") || []; //数据类型转换
//判断 商品对象是否存在于购物车数组内
let index = cart.findIndex((v) => v.goods_id === this.GoodsInfo.goods_id);
if (index === -1) {
//不存在,第一次添加
this.GoodsInfo.num = 1;
//第一次添加的时候,给定一个复选框的默认值为true
this.GoodsInfo.checked = true;
cart.push(this.GoodsInfo);
} else {
//已经存在
cart[index].num++;
}
//把数据重新缓存到数据当中
wx.setStorageSync("cart", cart);
wx.showToast({
title: "加入成功",
icon: "sucess",
mask: true,
//给定时间间隔
});
},
到后面可以在network当中看到缓存值:如下图:cart
文章持续更新中…