|
|
- <template>
- <view class="product"
- @touchstart="onTouchstart"
- @touchmove="onTouchmove"
- @touchend="onTouchend"
- >
- <image class="product-img" :src="data.image" mode="aspectFill"></image>
- <view class="flex flex-column product-info">
- <view class="product-info-top">
- <view class="product-name text-ellipsis-2">{{ data.name }}</view>
- <view class="product-desc text-ellipsis">{{ data.desc }}</view>
- </view>
- <view class="flex product-info-bottom">
- <view class="product-detail">
- <view class="flex product-price">
- <view class="product-price-val">
- <text>¥</text>
- <text class="highlight">{{ priceInt }}</text>
- <text>{{ `${priceFrac}起` }}</text>
- </view>
- <view class="product-price-bef" v-if="data.originalPrice">
- {{ `¥${data.originalPrice}` }}
- </view>
- </view>
- <view class="product-registered">
- {{ `${data.registered}人已报名` }}
- </view>
- </view>
- <button class="btn" @click="onRegistrate">报名</button>
- </view>
- </view>
-
- <button class="flex btn-collect"
- :style="collectBtnStyle"
- @click.stop="onCollect"
- @touchstart.stop="() => {}"
- >
- <view>{{ isCollected ? '移除收藏' : '收藏' }}</view>
- </button>
- </view>
- </template>
-
- <script>
- export default {
- props: {
- data: {
- type: Object,
- default() {
- return {}
- }
- },
- isCollected: {
- type: Boolean,
- default: false,
- }
- },
- data() {
- return {
- isMove: false,
- startClientX: null,
- displayX: 0,
- }
- },
- computed: {
- priceInt() {
- return parseInt(this.data.currentPrice)
- },
- priceFrac() {
- return (this.data.currentPrice % this.priceInt).toFixed(2).slice(1)
- },
- collectBtnStyle() {
- const width = this.isCollected ? 80 : 56
- const background = this.isCollected ? '#26334E' : '#FF9035'
-
- let display = Math.ceil(this.displayX / this.collectBtnWidth * 100)
-
- display > 100 && (display = 100)
-
- const translateX = 100 - display
-
- return `width: ${width}px; transform: translateX(${translateX}%); background: ${background};`
- }
- },
- methods: {
- onTouchstart(e) {
- const clientX = e.changedTouches[0].clientX
-
- this.isMove = false
- this.startClientX = clientX
- this.displayX = 0
- },
- onTouchmove(e) {
- const clientX = e.changedTouches[0].clientX
-
- if (clientX < this.startClientX) {
- this.displayX = this.startClientX - clientX
- } else {
- this.displayX = 0
- }
-
- this.isMove = true
- },
- onTouchend() {
- if (this.displayX < 100) {
- this.displayX = 0
- }
-
- this.isMove = false
- },
- showCollectBtn() {
- this.displayX = 100
- },
- hiddenCollectBtn() {
- this.displayX = 0
- },
- onCollect() {
- console.log('onCollect')
-
- if (this.isCollected) {
- // todo: fetch cancel collect
- uni.showToast({
- icon: 'success',
- title: '已移除收藏',
- });
- } else {
- // todo: fetch collect
- uni.showToast({
- icon: 'success',
- title: '已收藏',
- });
- }
- this.hiddenCollectBtn()
- },
- onRegistrate() {
- this.$utils.navigateTo(`/pages_order/product/productDetail?id=${this.data.id}`)
- },
- },
- }
- </script>
-
- <style scoped lang="scss">
- .product {
- position: relative;
- height: 464rpx;
- background: #FFFFFF;
- border: 2rpx solid #FFFFFF;
- border-radius: 32rpx;
- overflow: hidden;
- font-size: 0;
-
- &-img {
- width: 100%;
- height: 220rpx;
- }
-
- &-info {
- height: 244rpx;
- padding: 16rpx 16rpx 24rpx 16rpx;
- box-sizing: border-box;
- justify-content: space-between;
-
- &-top {
-
- }
-
- &-bottom {
- width: 100%;
- justify-content: space-between;
- }
-
- }
-
- &-name {
- font-size: 28rpx;
- font-weight: 500;
- color: #000000;
- }
-
- &-desc {
- margin-top: 8rpx;
- font-size: 24rpx;
- color: #8B8B8B;
- }
-
- &-detail {
-
- }
-
- &-price {
- justify-content: flex-start;
- align-items: baseline;
- column-gap: 12rpx;
-
- &-val {
- font-size: 24rpx;
- font-weight: 500;
- color: #FF4800;
-
- .highlight {
- font-size: 32rpx;
- }
-
- }
-
- &-bef {
- text-decoration: line-through;
- font-size: 24rpx;
- color: #8B8B8B;
- }
- }
-
- &-registered {
- font-size: 24rpx;
- color: #8B8B8B;
- }
-
- .btn {
- padding: 11rpx 16rpx;
- font-size: 26rpx;
- font-weight: 500;
- color: #FFFFFF;
- background: #00A9FF;
- border-radius: 24rpx;
- }
-
- }
-
- .btn-collect {
- position: absolute;
- top: 0;
- right: 0;
- row-gap: 8rpx;
- // width: 112rpx;
- height: 100%;
- font-size: 24rpx;
- line-height: 1;
- color: #FFFFFF;
- // background: #FF9035;
- }
-
- </style>
|