wishlist.vue 4.63 KB
<template>
  <view class="page-shell wishlist-page">
    <view class="page-blur"></view>
    <view class="page-blur-secondary"></view>
    <view class="page-blur-tertiary"></view>

    <view class="page-content subpage-content">
      <view class="subpage-nav">
        <view class="subpage-back" @tap="goBack">‹</view>
        <view class="subpage-title-wrap">
          <text class="subpage-title">心愿单</text>
          <text class="subpage-subtitle">把想慢慢挑选的护理好物,先轻轻收进这里</text>
        </view>
      </view>

      <view v-if="wishlistProducts.length" class="wishlist-list">
        <view v-for="item in wishlistProducts" :key="item.id" class="wish-card glass-card" @tap="goDetail(item)">
          <image class="wish-image" :src="item.image" mode="aspectFill" />
          <view class="wish-copy">
            <text class="wish-badge">{{ item.badge }}</text>
            <text class="wish-name">{{ item.name }}</text>
            <text class="wish-desc">{{ item.desc }}</text>
            <text class="wish-price">¥{{ item.price }}</text>
            <view class="wish-actions">
              <view class="secondary-button wish-btn" @tap.stop="removeItem(item)">移出心愿单</view>
              <view class="primary-button wish-btn" @tap.stop="goDetail(item)">查看详情</view>
            </view>
          </view>
        </view>
      </view>

      <view v-else class="subpage-card empty-card">
        <text class="empty-title">心愿单还是空的</text>
        <text class="empty-desc">遇见喜欢的护理好物时,可以先放进这里,之后再慢慢决定。</text>
        <view class="primary-button empty-button" @tap="goMall">去逛商城</view>
      </view>
    </view>
  </view>
</template>

<script>
import { products } from '@/packageMall/data/products'

export default {
  data() {
    return {
      wishlistProducts: []
    }
  },
  onShow() {
    this.loadWishlist()
  },
  methods: {
    loadWishlist() {
      const ids = uni.getStorageSync('lf_wishlist') || []
      this.wishlistProducts = products.filter(item => ids.indexOf(item.id) > -1)
    },
    goBack() {
      uni.navigateBack({
        fail: () => {
          uni.redirectTo({ url: '/pages/profile/profile' })
        }
      })
    },
    goDetail(item) {
      uni.navigateTo({
        url: `/packageMall/product-detail/product-detail?id=${item.id}`
      })
    },
    removeItem(item) {
      const ids = uni.getStorageSync('lf_wishlist') || []
      const next = ids.filter(id => id !== item.id)
      uni.setStorageSync('lf_wishlist', next)
      this.loadWishlist()
      uni.showToast({
        title: '已移出心愿单',
        icon: 'none'
      })
    },
    goMall() {
      uni.reLaunch({
        url: '/packageMall/main/main'
      })
    }
  }
}
</script>

<style lang="scss" scoped>
@import '@/styles/mixins.scss';
@import '@/styles/subpage.scss';

.wish-card {
  display: flex;
  padding: 28rpx;
  margin-bottom: 22rpx;
  transition: transform 340ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 340ms ease;
  animation: lfRevealUp 760ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

.wish-card:nth-of-type(1) { animation-delay: 0.08s; }
.wish-card:nth-of-type(2) { animation-delay: 0.16s; }
.wish-card:nth-of-type(3) { animation-delay: 0.24s; }
.wish-card:nth-of-type(4) { animation-delay: 0.32s; }

.wish-card:active {
  transform: translateY(-5rpx);
}

.wish-image {
  width: 188rpx;
  height: 188rpx;
  border-radius: 28rpx;
  flex-shrink: 0;
  transition: transform 1.1s ease;
}

.wish-card:active .wish-image {
  transform: scale(1.04);
}

.wish-copy {
  flex: 1;
  margin-left: 22rpx;
}

.wish-badge,
.wish-name,
.wish-desc,
.wish-price {
  display: block;
}

.wish-badge {
  font-size: 20rpx;
  letter-spacing: 3rpx;
  color: $brand-accent;
  animation: lfRevealUp 760ms cubic-bezier(0.22, 1, 0.36, 1) 0.06s both;
}

.wish-name {
  margin-top: 10rpx;
  font-size: 30rpx;
  line-height: 1.5;
  font-weight: 700;
}

.wish-desc {
  margin-top: 12rpx;
  font-size: 24rpx;
  line-height: 1.75;
  color: $text-secondary;
}

.wish-price {
  margin-top: 16rpx;
  font-size: 34rpx;
  font-weight: 700;
  color: $brand-primary-deep;
}

.wish-actions {
  display: flex;
  gap: 14rpx;
  margin-top: 22rpx;
}

.wish-btn {
  flex: 1;
  width: 0;
  min-width: 0;
  height: 78rpx !important;
  font-size: 24rpx !important;
  letter-spacing: 1rpx !important;
}

.empty-card {
  text-align: center;
}

.empty-title {
  display: block;
  font-size: 34rpx;
  font-weight: 700;
  color: $text-primary;
}

.empty-desc {
  display: block;
  margin-top: 16rpx;
  font-size: 24rpx;
  line-height: 1.8;
  color: $text-secondary;
}

.empty-button {
  width: 100%;
  margin-top: 28rpx;
}
</style>