第一次上传
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<view class="points-mall-page">
|
||||
<!-- 全新方案:纯 CSS 手动构建的骨架屏 -->
|
||||
<view v-if="loading" class="skeleton-wrapper">
|
||||
<view class="skeleton-item skeleton-rect" style="height: 300rpx; margin: 24rpx; border-radius: 16rpx;"></view>
|
||||
<view class="skeleton-content">
|
||||
<view class="skeleton-left-panel">
|
||||
<view v-for="i in 6" :key="i" class="skeleton-item skeleton-text" style="width: 80%; height: 60rpx; margin-bottom: 50rpx;"></view>
|
||||
</view>
|
||||
<view class="skeleton-right-panel">
|
||||
<view v-for="i in 4" :key="i" class="skeleton-card">
|
||||
<view class="skeleton-item skeleton-rect" style="width: 160rpx; height: 160rpx;"></view>
|
||||
<view style="flex:1; margin-left: 24rpx;">
|
||||
<view class="skeleton-item skeleton-text" style="width: 90%; height: 30rpx;"></view>
|
||||
<view class="skeleton-item skeleton-text" style="width: 60%; height: 32rpx; margin-top: 40rpx;"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 页面实际内容 -->
|
||||
<view v-else class="page-content">
|
||||
<!-- 1. 顶部轮播图 (原生 <swiper> 实现) -->
|
||||
<view class="swiper-section">
|
||||
<swiper class="swiper-container" circular autoplay :interval="3000" :duration="500" @change="e => swiperCurrent = e.detail.current">
|
||||
<swiper-item v-for="(item, index) in swiperList" :key="index">
|
||||
<view class="swiper-item">
|
||||
<view class="image-placeholder swiper-image">
|
||||
<image :src="item" style="width: 100%; height: 100%;" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<!-- 自定义指示点 -->
|
||||
<view class="swiper-dots">
|
||||
<view class="dot" :class="{ active: index === swiperCurrent }" v-for="(item, index) in swiperList" :key="index"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 2. 主体内容:左右联动 -->
|
||||
<view class="main-content">
|
||||
<!-- 左侧分类栏 -->
|
||||
<scroll-view class="left-panel" scroll-y>
|
||||
<view
|
||||
class="category-item"
|
||||
:class="{ active: currentCategory === index }"
|
||||
v-for="(cat, index) in categories"
|
||||
:key="cat.id"
|
||||
@click="selectCategory(index)"
|
||||
>
|
||||
<text class="name">{{ cat.name }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 右侧商品列表 -->
|
||||
<scroll-view class="right-panel" scroll-y>
|
||||
<view class="product-list">
|
||||
<view class="product-card" v-for="product in products" :key="product.id" @click="Service.GoPage('/pages/goods/integralGoods')">
|
||||
<view class="image-placeholder product-image">
|
||||
<image :src="product.img" style="width: 100%; height: 100%; border-radius: 20rpx;" mode=""></image>
|
||||
</view>
|
||||
<view class="product-info">
|
||||
<text class="name">{{ product.name }}</text>
|
||||
<view class="price-line">
|
||||
<text class="points">{{ product.points }} 积分</text>
|
||||
<text class="original-price" v-if="product.originalPrice">+ ¥{{ product.originalPrice }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<up-loadmore status="nomore" nomoreText="没有更多商品了"></up-loadmore>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import { Service } from "@/Service/Service";
|
||||
|
||||
const loading = ref<boolean>(true);
|
||||
const currentCategory = ref(0);
|
||||
const swiperCurrent = ref(0);
|
||||
|
||||
// 轮播图数据
|
||||
const swiperList = reactive([
|
||||
'/static/dele/dele1.jpg',
|
||||
'/static/dele/dele2.jpg',
|
||||
'/static/dele/dele3.png',
|
||||
]);
|
||||
|
||||
// 分类数据
|
||||
const categories = reactive([
|
||||
{ id: 1, name: '热门兑换' }, { id: 2, name: '生活家居' }, { id: 3, name: '数码家电' },
|
||||
{ id: 4, name: '美妆个护' }, { id: 5, name: '食品饮料' }, { id: 6, name: '虚拟卡券' },
|
||||
]);
|
||||
|
||||
// 商品数据
|
||||
const products = reactive([
|
||||
{ id: 101, name: '品牌充电宝 10000mAh 金属外壳 超薄便携', img:'/static/dele/dele1.jpg', points: 2000, originalPrice: 19.9 },
|
||||
{ id: 102, name: '声波震动电动牙刷 智能计时', img:'/static/dele/dele2.jpg', points: 5000 },
|
||||
{ id: 103, name: '知名视频网站月度会员卡 直充', img:'/static/dele/dele3.png', points: 1500, originalPrice: 5 },
|
||||
{ id: 104, name: '“天命打工人”限定版帆布袋', img:'/static/dele/dele4.jpg', points: 800 },
|
||||
]);
|
||||
|
||||
const selectCategory = (index: number) => {
|
||||
if (currentCategory.value === index) return;
|
||||
currentCategory.value = index;
|
||||
console.log(`切换到分类: ${categories[index].name}`);
|
||||
};
|
||||
|
||||
onLoad(() => {
|
||||
setTimeout(() => { loading.value = false; }, 1500);
|
||||
});
|
||||
onShow(() => {});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 骨架屏样式 */
|
||||
.skeleton-wrapper {
|
||||
background-color: #f7f7f7;
|
||||
.skeleton-content { display: flex; }
|
||||
.skeleton-left-panel { width: 180rpx; padding: 30rpx 20rpx; background: #f7f7f7; }
|
||||
.skeleton-right-panel { flex: 1; padding: 30rpx; background: #fff; }
|
||||
.skeleton-card { display: flex; align-items: center; gap: 24rpx; padding-bottom: 30rpx; margin-bottom: 30rpx; border-bottom: 1rpx solid #f0f0f0;}
|
||||
}
|
||||
|
||||
.points-mall-page {
|
||||
background-color: #f7f7f7; height: 100vh;
|
||||
display: flex; flex-direction: column;
|
||||
}
|
||||
|
||||
.swiper-section {
|
||||
padding: 24rpx;
|
||||
position: relative;
|
||||
.swiper-container {
|
||||
height: 300rpx;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
.swiper-item {
|
||||
width: 100%; height: 100%;
|
||||
.swiper-image { width: 100%; height: 100%; }
|
||||
}
|
||||
.swiper-dots {
|
||||
position: absolute;
|
||||
bottom: 40rpx; left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex; gap: 12rpx;
|
||||
.dot {
|
||||
width: 12rpx; height: 12rpx;
|
||||
border-radius: 50%; background-color: rgba(255, 255, 255, 0.5);
|
||||
transition: all 0.3s;
|
||||
&.active { width: 30rpx; background-color: #fff; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1; display: flex; overflow: hidden;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
width: 180rpx; background-color: #f7f7f7; height: 100%;
|
||||
.category-item {
|
||||
padding: 30rpx 20rpx; font-size: 28rpx; color: #666;
|
||||
text-align: center; position: relative;
|
||||
&.active {
|
||||
background-color: #fff; color: #333; font-weight: bold;
|
||||
&::before {
|
||||
content: ''; position: absolute; left: 0; top: 50%;
|
||||
transform: translateY(-50%); width: 8rpx; height: 40rpx;
|
||||
background-color: #fa6400;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-panel {
|
||||
flex: 1; background-color: #fff; height: 100%; padding: 30rpx;
|
||||
.product-list { display: flex; flex-direction: column; gap: 30rpx; }
|
||||
.product-card {
|
||||
display: flex; gap: 24rpx; align-items: center;
|
||||
border-bottom: 1rpx solid #e2e2e2;
|
||||
padding-bottom: 10rpx;
|
||||
.product-image {
|
||||
width: 160rpx; height: 160rpx;
|
||||
border-radius: 12rpx; flex-shrink: 0;
|
||||
}
|
||||
.product-info {
|
||||
flex: 1; min-width: 0;
|
||||
.name {
|
||||
font-size: 28rpx; color: #333; font-weight: 500;
|
||||
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
|
||||
overflow: hidden; text-overflow: ellipsis;
|
||||
}
|
||||
.price-line {
|
||||
margin-top: 20rpx; display: flex; align-items: baseline;
|
||||
.points { font-size: 32rpx; font-weight: bold; color: #fa6400; }
|
||||
.original-price { font-size: 22rpx; color: #999; margin-left: 8rpx; }
|
||||
}
|
||||
}
|
||||
.exchange-btn {
|
||||
background-color: #fa6400; color: #fff;
|
||||
border-radius: 30rpx; font-size: 24rpx;
|
||||
padding: 10rpx 24rpx; margin: 0;
|
||||
height: fit-content; line-height: 1.5;
|
||||
&::after { border: none; }
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user