更新记录

1.0.1(2025-04-12) 下载此版本

增加插槽使用说明

1.0.0(2025-04-11) 下载此版本

新增组件


平台兼容性

Vue2 Vue3
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 3.1.0 × × × × ×
钉钉小程序 快手小程序 飞书小程序 京东小程序 鸿蒙元服务
× × × × ×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari
× × × × × × × × ×

hbxw-shop-cart-ani 购物车动画组件

购物车动画组件,可用于购物车商品飞入动画效果。

使用示例

推荐先直接复制示例代码到工程中看效果了解下使用方法再投入项目使用。

<template>
  <view class="container">
    <!-- 商品列表 -->
     <!-- 通过实例调用 推荐,这样可以节省元素数量,所有添加到购物车共用一个组件 -->
    <view class="goods-list">
      <view class="goods-item" v-for="(item, index) in goodsList" :key="index">
        <image class="goods-image" :src="item.image" mode="aspectFill"></image>
        <view class="goods-action">
          <view class="goods-info">
            <text class="goods-name">{{item.name}}</text>
            <text class="goods-price">¥{{item.price}}</text>
          </view>
          <view class="goods-action-btn" @tap="addToCart(item, $event)">添加到购物车</view>
        </view>
      </view>
    </view>

    <!-- 组件直接包含子元素,子元素会被作为触发元素 -->
    <view class="goods-item">
        <image class="goods-image" src="https://dummyimage.com/400x400/000/fff.png&text=test_img" mode="aspectFill"></image>
        <view class="goods-action">
          <view class="goods-info">
            <text class="goods-name">商品0</text>
            <text class="goods-price">168</text>
          </view>
          <hbxw-shop-cart-ani :item="{'test': 12345}" :targetX="cartLeft" :targetY="cartTop" @end="onAniEnd">
            <view class="goods-action-btn">添加到购物车</view>
          </hbxw-shop-cart-ani>
        </view>
      </view>

    <!-- 购物车按钮 -->
    <view class="cart-btn" :style="{left: cartLeft + 'px', top: cartTop + 'px'}">
      <text class="cart-num" v-if="cartNum > 0">{{cartNum}}</text>
      <text class="iconfont icon-cart">🛒</text>
    </view>

    <!-- 动画组件 -->
    <hbxw-shop-cart-ani ref="cartAni" :targetX="cartLeft" :targetY="cartTop" @end="onAniEnd">
      <template #aniItem>
        <view class="ani-ball"></view>
      </template>
    </hbxw-shop-cart-ani>
  </view>
</template>

<script>
export default {
  data() {
    return {
      // 购物车位置
      cartLeft: 300,
      cartTop: 600,
      // 购物车数量
      cartNum: 0,
      // 商品列表
      goodsList: [
        {
          id: 1,
          name: '商品1',
          price: 99,
          image: 'https://dummyimage.com/400x400/000/fff.png&text=test_img'
        },
        {
          id: 2, 
          name: '商品2',
          price: 199,
          image: 'https://dummyimage.com/400x400/000/fff.png&text=test_img'
        },
        {
          id: 3,
          name: '商品3', 
          price: 299,
          image: 'https://dummyimage.com/400x400/000/fff.png&text=test_img'
        },
        {
          id: 4,
          name: '商品4',
          price: 399,
          image: 'https://dummyimage.com/400x400/000/fff.png&text=test_img'
        }
      ]
    }
  },
  methods: {
    // 添加到购物车
    addToCart(item, event) {
      // 获取点击位置
      const { x, y } = event.detail
      // 开始动画
      this.$refs.cartAni.start(x, y)
    },
    // 动画结束
    onAniEnd() {
      this.cartNum++
    }
  }
}
</script>

<style>
.container {
  padding: 20rpx;
}

.goods-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.goods-item {
  width: 45%;
  margin-bottom: 20rpx;
  background: #fff;
  border-radius: 12rpx;
  overflow: hidden;
  box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.1);
}

.goods-image {
  width: 100%;
  height: 200rpx;
}

.goods-info {
  padding: 16rpx;
}

.goods-name {
  font-size: 28rpx;
  color: #333;
}

.goods-price {
  font-size: 32rpx;
  color: #f00;
  margin-top: 8rpx;
  display: block;
}

.cart-btn {
  position: fixed;
  width: 80rpx;
  height: 80rpx;
  background: #f00;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.cart-num {
  position: absolute;
  top: -6rpx;
  right: -6rpx;
  min-width: 32rpx;
  height: 32rpx;
  line-height: 32rpx;
  text-align: center;
  background: #ff0;
  color: #f00;
  border-radius: 16rpx;
  font-size: 24rpx;
  padding: 0 6rpx;
}

.icon-cart {
  color: #fff;
  font-size: 40rpx;
}

.ani-ball {
  width: 30rpx;
  height: 30rpx;
  background: #f00;
  border-radius: 50%;
}
.goods-action{
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.goods-action-btn{
  background-color: mediumslateblue;
  font-size: 12px;
  text-align: center;
  padding: 8px;
  color: #fff;
  border-radius: 4px
}
</style>

参数说明

参数名 类型 默认值 说明
targetX Number 0 目标点X坐标(屏幕绝对位置,单位px)
targetY Number 0 目标点Y坐标(屏幕绝对位置,单位px)
duration Number 600 动画时长(ms)
item Object null 关联商品数据对象

事件说明

事件名 说明 参数
@end 动画结束时触发

插槽说明

插槽名 说明
default 默认插槽,用于包裹触发动画的元素
aniItem 自定义动画元素的样式,不设置则使用默认样式

坐标获取说明

// 在onReady生命周期获取目标位置
onReady() {
  const query = uni.createSelectorQuery().in(this);
  query.select('#cartIcon').boundingClientRect(data => {
    this.cartPos = {
      x: data.left + data.width/2,
      y: data.top + data.height/2
    }
  }).exec()
}

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问