微信小程序功能:商品收藏-图片预览-客服-分享-加入购物车

微信小程序–商品详情页面

包含功能点:

  • 商品收藏
  • 图片预览
  • 客服
  • 分享
  • 加入购物车
  • 跳转到购物车页面(注意:open-type="switchTab"

结构:goods_detail.wxml

<!-- 轮播图 -->
<view class="detail_swiper">
  <swiper autoplay="{{true}}" circular="{{true}}" indicator-dots="{{true}}">
    <swiper-item wx:for="{{goodsObj.pics}}" wx:key="pics_id" bindtap="handlePrevewImage" data-url="{{item.pics_mid}}">
      <image src="{{item.pics_mid}}" mode="widthFix" />
    </swiper-item>
  </swiper>
</view>
<!-- 商品价格 -->
<view class="goods_price">¥{{goodsObj.goods_price}}</view>
<!-- 商品名称和收藏 -->
<view class="goods_name_row">
  <view class="goods_name">{{goodsObj.goods_name}}{{goodsObj.goods_name}}</view>
  <view class="goods_collect" bindtap="handleCollect">
    <text class="iconfont {{isCollect?'icon-shoucang1':'icon-shoucang'}}"></text>
    <view class="collect_text">收藏</view>
  </view>
</view>
<!-- 商品详情 -->
<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>
<!-- 底部tab栏 -->
<view class="btm_tool">
  <view class="tool_item">
    <view class="iconfont icon-kefu"></view>
    <view>客服</view>
    <button open-type="contact"></button>
  </view>
  <view class="tool_item">
    <view class="iconfont  icon-fenxiang"></view>
    <view>分享</view>
    <button open-type="share"></button>
  </view>
  <navigator class="tool_item" url="/pages/cart/cart" open-type="switchTab">
    <view class="iconfont  icon-gouwuche"></view>
    <view>购物车</view>
  </navigator>
  <view class="tool_item btn_cart" bindtap="handleCartAdd">加入购物车</view>
  <view class="tool_item btn_buy">立即购买</view>
</view>

样式:goods_detail.less

// 底部tab栏:固定定位--遮挡内容
page {
  padding-bottom: 90rpx;
}

// 轮播图
.detail_swiper {

  // 原图:400 * 400px,比例:1-1
  swiper {
    // 高 = 宽,也是比例:1-1;根据需要微调为65vw(该写:100vw)
    height: 65vw;
    text-align: center;

    swiper-item {
      image {
        width: 60%;
      }
    }
  }
}

// 商品价格
.goods_price {
  padding: 15rpx;
  font-size: 32rpx;
  font-weight: 600;
  color: var(--themeColor);
}

// 商品名称和收藏
.goods_name_row {
  border-top: 5rpx solid #dedede;
  border-bottom: 5rpx solid #dedede;
  padding: 10rpx 0;
  display: flex;

  .goods_name {
    flex: 5;
    color: #000;
    font-style: 30rpx;
    padding: 0 10rpx;

    // 文字溢出--省略号代替...
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .goods_collect {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    border-left: 1rpx solid #000;

    .icon-shoucang1 {
      color: orangered;
    }
    .collect_text {}
  }
}

// 商品详情
.goods_info {
  .goods_info_title {
    font-size: 32rpx;
    font-weight: 600;
    color: var(--themeColor);
    padding: 20rpx;
  }

  .goods_info_content {}
}

// 底部tab栏
.btm_tool {
  position: fixed;
  left: 0;
  bottom: 0;
  // 块级元素:添加绝对、固定定位之后,需要给一个宽度;否则宽度由内容撑开了
  width: 100%;
  height: 90rpx;
  background-color: #fff;
  border-top: 1rpx solid #ccc;
  display: flex;

  .tool_item {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    font-size: 24rpx;
    position: relative;

    // 隐形的button按钮:绝对定位,继承父元素宽高,不透明
    button {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      opacity: 0;
    }
  }

  .btn_cart {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    flex: 2;
    background-color: #ffa500;
    color: #fff;
    font-size: 30rpx;
    font-weight: 600;
  }

  .btn_buy {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    flex: 2;
    background-color: #eb4450;
    color: #fff;
    font-size: 30rpx;
    font-weight: 600;
  }
}

逻辑:goods_detail.js文件

// pages/goods_detail/goods_detail.js
import { request } from "../../request/index.js";
Page({

  /**
   * 页面的初始数据
   */
  data: {
    // 接口:商品详情数据
    goodsObj: {},
    // 商品是否被收藏
    isCollect: false
  },
  // 商品对象--全局变量
  GoodsInfo: {},

  // 点击轮播图 放大预览
  handlePrevewImage(e) {

    // 1.先构造要预览的图片数组
    const urls = this.GoodsInfo.pics.map(v => v.pics_mid);

    // 2.接收传递过来的图片url
    const current = e.currentTarget.dataset.url;

    wx.previewImage({
      current,
      urls,
      success: (result) => {
        console.log(result)
      }
    });
  },
  // 点击  加入购物车
  handleCartAdd() {

    // 1.获取缓存中的购物车 数组格式
    let cart = wx.getStorageSync("cart") || [];

    // 2.先判断  当前的商品是否已经存在于 购物车 (缓存中的商品id === 商品对象的id)
    let index = cart.findIndex(v => v.goods_id === this.GoodsInfo.goods_id);

    if (index === -1) {
      // 3. 不存在于购物车的数组中  直接给购物车数组添加一个新元素  新元素带上购买数量属性 num 重新把购物车数组  填充回缓存中
      this.GoodsInfo.num = 1;

      // 重点:添加属性--商品选中状态--为购物车页面准备
      this.GoodsInfo.checked = true;
      cart.push(this.GoodsInfo)

    } else {

      // 4. 已经存在  修改商品数据  执行购物车数量++ 重新把购物车数组  填充回缓存中
      cart[index].num++;

    }

    // 5. 不管该商品是否存在于购物车数组中,都需要把购物车数组填充回缓存中
    wx.setStorageSync("cart", cart);

    // 6. 弹框提示
    wx.showToast({
      title: '加入成功',
      icon: 'success',
      // 防止用户手抖  疯狂点击按钮
      mask: true
    });

  },
  // 获取商品详情数据
   getGoodsDetail(goods_id) {

     request({ url: "/goods/detail", data: { goods_id } }).then(goodsObj=>{

      // 将接口数据赋值给全局变量
      this.GoodsInfo = goodsObj;

      // 1.获取缓存中的商品收藏的按钮
      let collect = wx.getStorageSync("collect") || [];

      // 2.判断当前商品是否被收藏
      let isCollect = collect.some(v => v.goods_id === this.GoodsInfo.goods_id);

      // 3. 提取有用信息
      this.setData({
        goodsObj: {
          goods_name: goodsObj.goods_name,
          goods_price: goodsObj.goods_price,
          /**
           * iphone 部分手机  不识别webp图片格式
           * 最好找到后台  让他做修改
           * 临时自己修改  确保后台存在 1.webp => 1.jpg
           */
          goods_introduce: goodsObj.goods_introduce.replace(/\.webp/g, '.jpg'),
          pics: goodsObj.pics
        },
        isCollect
      })

    });
  },
  /**
   * 点击收藏按钮
   * 1. 判断该商品是否存在于缓存数组中
   * 2. 已经存在  把该商品删除
   * 3. 没有存在  把该商品添加到收藏数组中  存入缓存中即可。
   */
  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中的数据
    this.setData({
      isCollect
    })

  },
/**
 * 生命周期函数--监听页面显示
 */
  onLoad: function (options) {
    console.log(options.goods_id)
  },
  /**
   * 生命周期函数--监听页面显示
   * 
   * 页面 onShow 的时候:收藏逻辑放在了 this.getGoodsDetail() 函数里面
   * 1. 加载缓存中的商品收藏的数据
   * 2. 判断当前商品是不是被收藏
   *    是  改变页面的图标
   *  不是  继续执行下面操作
   */
  onShow: function (options) {

    // 获取页面栈
    let pages = getCurrentPages();
    
    // 获取当前页面
    let currentPages = pages[pages.length - 1]

    // 获取url中传递过来的参数
    const { goods_id } = currentPages.options;

    // 发请求获取该商品的详情信息
    this.getGoodsDetail(goods_id)

  }
})

页面配置文件:goods_detail.json文件

{
  "usingComponents": {},
  "navigationBarTitleText": "商品详情"
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落花流雨

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值