feat: 初次提交我的项目代码
This commit is contained in:
361
pages/mall/consumer/category.uvue
Normal file
361
pages/mall/consumer/category.uvue
Normal file
@@ -0,0 +1,361 @@
|
||||
<!-- pages/mall/consumer/category.uvue -->
|
||||
<template>
|
||||
<view class="category-page">
|
||||
<!-- 顶部搜索栏 -->
|
||||
<view class="search-bar">
|
||||
<view class="search-box" @click="navigateToSearch">
|
||||
<text class="search-icon">🔍</text>
|
||||
<text class="search-placeholder">搜索商品</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 分类内容区 -->
|
||||
<view class="category-content">
|
||||
<!-- 左侧一级分类 -->
|
||||
<scroll-view scroll-y class="primary-category">
|
||||
<view
|
||||
v-for="item in primaryCategories"
|
||||
:key="item.id"
|
||||
:class="['primary-item', { active: activePrimary === item.id }]"
|
||||
@click="selectPrimaryCategory(item.id)"
|
||||
>
|
||||
<text class="primary-name">{{ item.name }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 右侧二级分类和商品 -->
|
||||
<scroll-view scroll-y class="secondary-content">
|
||||
<!-- 二级分类 -->
|
||||
<view v-if="secondaryCategories.length > 0" class="secondary-category">
|
||||
<view
|
||||
v-for="sub in secondaryCategories"
|
||||
:key="sub.id"
|
||||
class="secondary-item"
|
||||
@click="selectSecondaryCategory(sub.id)"
|
||||
>
|
||||
<image
|
||||
class="sub-category-image"
|
||||
:src="sub.image"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<text class="sub-category-name">{{ sub.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品列表 -->
|
||||
<view v-if="productList.length > 0" class="product-list">
|
||||
<view
|
||||
v-for="product in productList"
|
||||
:key="product.id"
|
||||
class="product-item"
|
||||
@click="navigateToProduct(product)"
|
||||
>
|
||||
<view class="product-image-wrapper">
|
||||
<image
|
||||
class="product-image"
|
||||
:src="product.image"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
</view>
|
||||
<text class="product-name">{{ product.name }}</text>
|
||||
<text class="product-price">¥{{ product.price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view v-if="!loading && productList.length === 0 && secondaryCategories.length === 0" class="empty-state">
|
||||
<text class="empty-icon">📁</text>
|
||||
<text class="empty-text">暂无商品</text>
|
||||
<button class="reload-btn" @click="loadData">刷新</button>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
// 响应式数据
|
||||
const primaryCategories = ref<any[]>([])
|
||||
const secondaryCategories = ref<any[]>([])
|
||||
const productList = ref<any[]>([])
|
||||
const activePrimary = ref<string>('1')
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
// Mock 数据
|
||||
const mockCategories = {
|
||||
primary: [
|
||||
{ id: '1', name: '推荐' },
|
||||
{ id: '2', name: '女装' },
|
||||
{ id: '3', name: '男装' },
|
||||
{ id: '4', name: '鞋靴' },
|
||||
{ id: '5', name: '箱包' },
|
||||
{ id: '6', name: '美妆' },
|
||||
{ id: '7', name: '数码' },
|
||||
{ id: '8', name: '家电' },
|
||||
{ id: '9', name: '家居' },
|
||||
{ id: '10', name: '母婴' },
|
||||
{ id: '11', name: '食品' },
|
||||
{ id: '12', name: '运动' },
|
||||
{ id: '13', name: '汽车' },
|
||||
{ id: '14', name: '百货' }
|
||||
],
|
||||
|
||||
secondary: {
|
||||
'1': [
|
||||
{ id: '101', name: '热销推荐', image: 'https://picsum.photos/100/100?random=1' },
|
||||
{ id: '102', name: '新品上市', image: 'https://picsum.photos/100/100?random=2' },
|
||||
{ id: '103', name: '限时特惠', image: 'https://picsum.photos/100/100?random=3' },
|
||||
{ id: '104', name: '精选好物', image: 'https://picsum.photos/100/100?random=4' }
|
||||
],
|
||||
'2': [
|
||||
{ id: '201', name: '连衣裙', image: 'https://picsum.photos/100/100?random=5' },
|
||||
{ id: '202', name: 'T恤', image: 'https://picsum.photos/100/100?random=6' },
|
||||
{ id: '203', name: '裤子', image: 'https://picsum.photos/100/100?random=7' },
|
||||
{ id: '204', name: '外套', image: 'https://picsum.photos/100/100?random=8' },
|
||||
{ id: '205', name: '内衣', image: 'https://picsum.photos/100/100?random=9' }
|
||||
]
|
||||
},
|
||||
|
||||
products: {
|
||||
'101': [
|
||||
{ id: '1001', name: '热销商品1', price: 99.9, image: 'https://picsum.photos/150/150?random=10' },
|
||||
{ id: '1002', name: '热销商品2', price: 199, image: 'https://picsum.photos/150/150?random=11' },
|
||||
{ id: '1003', name: '热销商品3', price: 299, image: 'https://picsum.photos/150/150?random=12' }
|
||||
],
|
||||
'201': [
|
||||
{ id: '2001', name: '连衣裙1', price: 199, image: 'https://picsum.photos/150/150?random=13' },
|
||||
{ id: '2002', name: '连衣裙2', price: 299, image: 'https://picsum.photos/150/150?random=14' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
|
||||
// 加载数据
|
||||
const loadData = () => {
|
||||
loading.value = true
|
||||
|
||||
// 使用模拟数据
|
||||
setTimeout(() => {
|
||||
primaryCategories.value = mockCategories.primary
|
||||
secondaryCategories.value = mockCategories.secondary[activePrimary.value] || []
|
||||
productList.value = mockCategories.products['101'] || []
|
||||
loading.value = false
|
||||
}, 500)
|
||||
}
|
||||
|
||||
// 选择一级分类
|
||||
const selectPrimaryCategory = (categoryId: string) => {
|
||||
activePrimary.value = categoryId
|
||||
secondaryCategories.value = mockCategories.secondary[categoryId] || []
|
||||
productList.value = mockCategories.products[categoryId + '01'] || []
|
||||
}
|
||||
|
||||
// 选择二级分类
|
||||
const selectSecondaryCategory = (subCategoryId: string) => {
|
||||
productList.value = mockCategories.products[subCategoryId] || []
|
||||
}
|
||||
|
||||
// 导航函数
|
||||
const navigateToSearch = () => {
|
||||
uni.navigateTo({ url: '/pages/mall/consumer/search' })
|
||||
}
|
||||
|
||||
const navigateToProduct = (product: any) => {
|
||||
uni.navigateTo({ url: `/pages/mall/consumer/product-detail?id=${product.id}` })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.category-page {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 搜索栏 */
|
||||
.search-bar {
|
||||
padding: 10px 15px;
|
||||
background-color: white;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 20px;
|
||||
padding: 10px 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
color: #999;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.search-placeholder {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 分类内容区 */
|
||||
.category-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 左侧一级分类 */
|
||||
.primary-category {
|
||||
width: 100px;
|
||||
background-color: white;
|
||||
border-right: 1px solid #eee;
|
||||
}
|
||||
|
||||
.primary-item {
|
||||
padding: 15px 10px;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
}
|
||||
|
||||
.primary-item.active {
|
||||
background-color: #fff0e8;
|
||||
color: #ff5000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.primary-item.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 3px;
|
||||
background-color: #ff5000;
|
||||
}
|
||||
|
||||
.primary-name {
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* 右侧内容区 */
|
||||
.secondary-content {
|
||||
flex: 1;
|
||||
padding: 15px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 二级分类 */
|
||||
.secondary-category {
|
||||
background-color: white;
|
||||
border-radius: 10px;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.secondary-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sub-category-image {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 30px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.sub-category-name {
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 商品列表 */
|
||||
.product-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.product-item {
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.product-image-wrapper {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
overflow: hidden;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 13px;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
height: 36px;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 16px;
|
||||
color: #ff5000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 50px 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 60px;
|
||||
color: #ccc;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 16px;
|
||||
color: #999;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.reload-btn {
|
||||
background-color: #ff5000;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
padding: 8px 25px;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user