feat: 分类开发
This commit is contained in:
parent
6bcdb0cdcc
commit
b21f024822
@ -14,6 +14,7 @@
|
||||
},
|
||||
"requiredPrivateInfos": ["getFuzzyLocation"],
|
||||
"pages": [
|
||||
"pages/category/index",
|
||||
"pages/home/index",
|
||||
"pages/login/index",
|
||||
"pages/H5/index",
|
||||
@ -28,7 +29,7 @@
|
||||
"text": "首页"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/H5/index",
|
||||
"pagePath": "pages/category/index",
|
||||
"text": "分类"
|
||||
},
|
||||
{
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
// components/custom-tabbar/index.js
|
||||
Component({
|
||||
properties: {
|
||||
cartCount: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
},
|
||||
|
||||
data: {
|
||||
list: [
|
||||
{
|
||||
pagePath: "/pages/home/home",
|
||||
iconPath: "/images/tab/home.png",
|
||||
selectedIconPath: "/images/tab/home-active.png",
|
||||
text: "首页",
|
||||
},
|
||||
{
|
||||
pagePath: "/pages/category/category",
|
||||
iconPath: "/images/tab/category.png",
|
||||
selectedIconPath: "/images/tab/category-active.png",
|
||||
text: "分类",
|
||||
},
|
||||
{
|
||||
pagePath: "/pages/cart/cart",
|
||||
iconPath: "/images/tab/cart.png",
|
||||
selectedIconPath: "/images/tab/cart-active.png",
|
||||
text: "购物车",
|
||||
},
|
||||
{
|
||||
pagePath: "/pages/user/user",
|
||||
iconPath: "/images/tab/user.png",
|
||||
selectedIconPath: "/images/tab/user-active.png",
|
||||
text: "我的",
|
||||
},
|
||||
],
|
||||
active: 0,
|
||||
},
|
||||
|
||||
methods: {
|
||||
switchTab(e) {
|
||||
const { path, index } = e.currentTarget.dataset;
|
||||
this.setData({ active: index });
|
||||
wx.switchTab({ url: path });
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -17,7 +17,7 @@ Component<TabBarData, TabBarProperties, TabBarMethods>({
|
||||
text: "首页",
|
||||
},
|
||||
{
|
||||
pagePath: "/pages/category/category",
|
||||
pagePath: "/pages/category/index",
|
||||
// iconPath: "/images/tab/category.png",
|
||||
// selectedIconPath: "/images/tab/category-active.png",
|
||||
text: "分类",
|
||||
|
||||
8
miniprogram/pages/category/index.json
Normal file
8
miniprogram/pages/category/index.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"van-button": "@vant/weapp/button/index",
|
||||
"van-icon": "@vant/weapp/icon/index",
|
||||
"custom-tabbar": "/components/custom-tabbar/index"
|
||||
},
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
175
miniprogram/pages/category/index.scss
Normal file
175
miniprogram/pages/category/index.scss
Normal file
@ -0,0 +1,175 @@
|
||||
$theme-color: #02ce26;
|
||||
|
||||
// pages/index/index.scss
|
||||
.category-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 100rpx);
|
||||
overflow: hidden;
|
||||
// 包名
|
||||
.category-header {
|
||||
padding-top: 100rpx;
|
||||
background: #fbeccb;
|
||||
.appName {
|
||||
padding-left: 40rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
// 搜索区域
|
||||
.category-search {
|
||||
margin: 16rpx 16rpx 0;
|
||||
.search-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
border-radius: 50rpx;
|
||||
padding: 10rpx 6rpx 10rpx 24rpx;
|
||||
.search-button {
|
||||
padding-right: 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: $theme-color;
|
||||
}
|
||||
input {
|
||||
flex: 1;
|
||||
padding-right: 40rpx;
|
||||
margin-left: 15rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.placeholder {
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 分类导航
|
||||
.category-scroll {
|
||||
.category-list {
|
||||
display: flex;
|
||||
padding: 16rpx 30rpx;
|
||||
gap: 40rpx;
|
||||
.category-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
.category-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
.category-name {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 主内容区
|
||||
.main-content {
|
||||
flex: 1;
|
||||
height: calc(100vh - 100rpx - 360rpx);
|
||||
display: flex;
|
||||
.left-categories {
|
||||
max-width: 200rpx;
|
||||
background: #f8f8f8;
|
||||
.left-category-item {
|
||||
padding: 30rpx 16rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
border-left: 6rpx solid transparent;
|
||||
&.active {
|
||||
background: white;
|
||||
color: $theme-color;
|
||||
border-left-color: $theme-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
.right-products {
|
||||
flex: 1;
|
||||
background: white;
|
||||
// 推荐标签
|
||||
.tag-list {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
.tag-item {
|
||||
padding: 24rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
&.active {
|
||||
color: $theme-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
.products-grid {
|
||||
.product-card {
|
||||
padding: 20rpx;
|
||||
display: flex;
|
||||
.product-image {
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 24rpx;
|
||||
background: #ddd;
|
||||
}
|
||||
.product-info {
|
||||
margin-left: 20rpx;
|
||||
border-bottom: 2rpx solid #eee;
|
||||
.product-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
.product-desc {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
.product-tags {
|
||||
margin-top: 4rpx;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10rpx;
|
||||
.tag {
|
||||
background: #fff2f0;
|
||||
color: #ff4d4f;
|
||||
padding: 4rpx 8rpx;
|
||||
border-radius: 6rpx;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
}
|
||||
.price-section {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.price-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.current-price {
|
||||
font-size: 32rpx;
|
||||
color: #ff3b30;
|
||||
font-weight: bold;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.original-price {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
.add-cart-btn {
|
||||
color: $theme-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
184
miniprogram/pages/category/index.ts
Normal file
184
miniprogram/pages/category/index.ts
Normal file
@ -0,0 +1,184 @@
|
||||
// pages/index/index.ts
|
||||
Page({
|
||||
data: {
|
||||
appName: "",
|
||||
statusBarHeight: 0,
|
||||
navBarHeight: 44,
|
||||
searchValue: "",
|
||||
categories: [
|
||||
{ id: 1, name: "水果鲜花", icon: "🍎" },
|
||||
{ id: 2, name: "蔬菜豆制品", icon: "🥬" },
|
||||
{ id: 3, name: "肉禽蛋", icon: "🥩" },
|
||||
{ id: 4, name: "海鲜水产", icon: "🐟" },
|
||||
{ id: 5, name: "乳品烘焙", icon: "🥛" },
|
||||
{ id: 6, name: "熟食快", icon: "🍱" },
|
||||
],
|
||||
recommendTags: ["销量", "折扣", "价格"],
|
||||
activeTag: "荐 时令推荐",
|
||||
leftCategories: [
|
||||
{ id: 1, name: "鲜花/绿植", active: true },
|
||||
{ id: 2, name: "西梅/桃李枣", active: false },
|
||||
{ id: 3, name: "橘/柚/橙/柑", active: false },
|
||||
{ id: 4, name: "苹果/新梨/蕉", active: false },
|
||||
{ id: 5, name: "石榴/龙眼", active: false },
|
||||
{ id: 6, name: "西瓜/蜜瓜", active: false },
|
||||
{ id: 7, name: "严选", active: false },
|
||||
{ id: 8, name: "果切/小番茄", active: false },
|
||||
{ id: 9, name: "榴莲/热带果", active: false },
|
||||
{ id: 7, name: "严选", active: false },
|
||||
{ id: 8, name: "果切/小番茄", active: false },
|
||||
{ id: 9, name: "榴莲/热带果", active: false },
|
||||
],
|
||||
products: [
|
||||
{
|
||||
id: 1,
|
||||
name: "【五彩心语】洋桔梗混色5枝",
|
||||
desc: "绚烂多姿 | 无刺玫瑰",
|
||||
tags: ["近90天最低价"],
|
||||
currentPrice: 7.96,
|
||||
originalPrice: 19.9,
|
||||
image: "/images/product1.jpg",
|
||||
badge: "出清价",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "【节节高升】剑兰粉色 5枝",
|
||||
desc: "淡粉色颜值高 | 温柔浪漫",
|
||||
tags: ["近90天最低价"],
|
||||
currentPrice: 7.96,
|
||||
originalPrice: 19.9,
|
||||
image: "/images/product2.jpg",
|
||||
badge: "出清价",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "时令【小玲珑】雏菊混搭花束",
|
||||
desc: "文艺装扮 | 玲珑可爱",
|
||||
tags: ["近30天最低价"],
|
||||
currentPrice: 3.95,
|
||||
originalPrice: 7.9,
|
||||
image: "/images/product3.jpg",
|
||||
badge: "出清价",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "【清香宜人】茉莉花30枝",
|
||||
desc: "百个花头 | 芳香怡人",
|
||||
tags: ["近90天最低价"],
|
||||
currentPrice: 10.68,
|
||||
originalPrice: 17.8,
|
||||
image: "/images/product4.jpg",
|
||||
badge: "出清价",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "时令【粉韵流光】粉色吸色牡丹菊 3枝",
|
||||
desc: "8cm大花头 | 菊花吸色工艺",
|
||||
tags: ["限时特价"],
|
||||
currentPrice: 15.8,
|
||||
originalPrice: 25.8,
|
||||
image: "/images/product5.jpg",
|
||||
badge: "秒杀",
|
||||
countdown: "01:18:44",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
const app = getApp();
|
||||
this.setData({ appName: app.globalData.appName });
|
||||
this.getSystemInfo();
|
||||
},
|
||||
|
||||
getSystemInfo() {
|
||||
const systemInfo = wx.getSystemInfoSync();
|
||||
this.setData({
|
||||
statusBarHeight: systemInfo.statusBarHeight,
|
||||
});
|
||||
},
|
||||
|
||||
onSearchInput(e: WechatMiniprogram.InputInput) {
|
||||
this.setData({
|
||||
searchValue: e.detail.value,
|
||||
});
|
||||
},
|
||||
|
||||
onSearch() {
|
||||
if (this.data.searchValue.trim()) {
|
||||
wx.showToast({
|
||||
title: `搜索: ${this.data.searchValue}`,
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onCategoryTap(e: WechatMiniprogram.TouchEvent) {
|
||||
const { index } = e.currentTarget.dataset;
|
||||
const categories = this.data.leftCategories.map((item, i) => ({
|
||||
...item,
|
||||
active: i === index,
|
||||
}));
|
||||
this.setData({ leftCategories: categories });
|
||||
},
|
||||
|
||||
onTagTap(e: WechatMiniprogram.TouchEvent) {
|
||||
const { tag } = e.currentTarget.dataset;
|
||||
this.setData({ activeTag: tag });
|
||||
},
|
||||
|
||||
onProductTap(e: WechatMiniprogram.TouchEvent) {
|
||||
const { id } = e.currentTarget.dataset;
|
||||
wx.navigateTo({
|
||||
url: `/pages/product/detail?id=${id}`,
|
||||
});
|
||||
},
|
||||
|
||||
onAddToCart(e: WechatMiniprogram.TouchEvent) {
|
||||
const { id } = e.currentTarget.dataset;
|
||||
wx.showToast({
|
||||
title: "已加入购物车",
|
||||
icon: "success",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
interface PageData {
|
||||
statusBarHeight: number;
|
||||
navBarHeight: number;
|
||||
searchValue: string;
|
||||
categories: Category[];
|
||||
recommendTags: string[];
|
||||
activeTag: string;
|
||||
leftCategories: LeftCategory[];
|
||||
products: Product[];
|
||||
}
|
||||
|
||||
interface Category {
|
||||
id: number;
|
||||
name: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
interface LeftCategory {
|
||||
id: number;
|
||||
name: string;
|
||||
active: boolean;
|
||||
}
|
||||
|
||||
interface Product {
|
||||
id: number;
|
||||
name: string;
|
||||
desc: string;
|
||||
tags: string[];
|
||||
currentPrice: number;
|
||||
originalPrice: number;
|
||||
image: string;
|
||||
badge: string;
|
||||
countdown?: string;
|
||||
}
|
||||
|
||||
interface Coupon {
|
||||
title: string;
|
||||
status: string;
|
||||
expireTime: string;
|
||||
}
|
||||
86
miniprogram/pages/category/index.wxml
Normal file
86
miniprogram/pages/category/index.wxml
Normal file
@ -0,0 +1,86 @@
|
||||
<!-- pages/index/index.wxml -->
|
||||
<view class="category-page">
|
||||
<!-- 头部 -->
|
||||
<view class="category-header">
|
||||
<text class="appName">{{ appName }}</text>
|
||||
<!-- 搜索框 -->
|
||||
<view class="category-search">
|
||||
<view class="search-bar">
|
||||
<icon type="search" size="14" color="#999" />
|
||||
<input placeholder="搜索" placeholder-class="placeholder" bindinput="onSearchInput"
|
||||
bindconfirm="onSearch" />
|
||||
<text class="search-button">搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 分类导航 -->
|
||||
<scroll-view class="category-scroll" scroll-x>
|
||||
<view class="category-list">
|
||||
<view class="category-item" wx:for="{{categories}}" wx:key="id">
|
||||
<text class="category-icon">{{item.icon}}</text>
|
||||
<text class="category-name">{{item.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<!-- 主内容区 -->
|
||||
<view class="main-content">
|
||||
<!-- 左侧分类 -->
|
||||
<scroll-view class="left-categories" scroll-y>
|
||||
<view
|
||||
class="left-category-item {{item.active ? 'active' : ''}}"
|
||||
wx:for="{{leftCategories}}"
|
||||
wx:key="id"
|
||||
bindtap="onCategoryTap"
|
||||
data-index="{{index}}"
|
||||
>
|
||||
<text>{{item.name}}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 右侧商品列表 -->
|
||||
<scroll-view class="right-products" scroll-y>
|
||||
<!-- 推荐标签 -->
|
||||
<view class="tag-list">
|
||||
<view
|
||||
class="tag-item {{activeTag === item ? 'active' : ''}}"
|
||||
wx:for="{{recommendTags}}"
|
||||
wx:key="*this"
|
||||
bindtap="onTagTap"
|
||||
data-tag="{{item}}"
|
||||
>
|
||||
<text>{{item}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 商品网格 -->
|
||||
<view class="products-grid">
|
||||
<view
|
||||
class="product-card"
|
||||
wx:for="{{products}}"
|
||||
wx:key="id"
|
||||
bindtap="onProductTap"
|
||||
data-id="{{item.id}}"
|
||||
>
|
||||
<image class="product-image" src="{{item.image}}" mode="aspectFill" />
|
||||
<view class="product-info">
|
||||
<text class="product-name">{{item.name}}</text>
|
||||
<text class="product-desc">{{item.desc}}</text>
|
||||
<view class="product-tags">
|
||||
<text class="tag" wx:for="{{item.tags}}" wx:key="*this">{{item}}</text>
|
||||
</view>
|
||||
<view class="price-section">
|
||||
<view class="price-left">
|
||||
<view class="current-price">¥{{item.currentPrice}}</view>
|
||||
<view class="original-price" wx:if="{{item.originalPrice}}">
|
||||
¥{{item.originalPrice}}
|
||||
</view>
|
||||
</view>
|
||||
<van-icon class="add-cart-btn" name="add" bindtap="onAddToCart" data-id="{{item.id}}" size="48rpx" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<!-- 自定义底部 TabBar -->
|
||||
<custom-tabbar />
|
||||
</view>
|
||||
@ -1,7 +1,5 @@
|
||||
// pages/index/index.ts
|
||||
|
||||
const app = getApp();
|
||||
|
||||
Page({
|
||||
data: {
|
||||
appName: "",
|
||||
@ -86,6 +84,7 @@ Page({
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
const app = getApp();
|
||||
// 页面加载时逻辑
|
||||
this.setData({ appName: app.globalData.appName });
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user