feat: 原生微信页面基本完成

This commit is contained in:
zc 2025-09-26 21:51:57 +08:00
parent b21f024822
commit ac83ce20f7
23 changed files with 705 additions and 99 deletions

View File

@ -3,5 +3,11 @@
"source.fixAll": "explicit"
},
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[scss]": {
"editor.defaultFormatter": "HookyQR.beautify"
},
"[wxml]": {
"editor.defaultFormatter": "wechat.miniprogram.wxml-language-features"
}
}

View File

@ -14,8 +14,10 @@
},
"requiredPrivateInfos": ["getFuzzyLocation"],
"pages": [
"pages/category/index",
"pages/home/index",
"pages/category/index",
"pages/shopping-cart/index",
"pages/mine/index",
"pages/login/index",
"pages/H5/index",
"pages/setup/index",
@ -33,11 +35,11 @@
"text": "分类"
},
{
"pagePath": "pages/download/index",
"pagePath": "pages/shopping-cart/index",
"text": "购物车"
},
{
"pagePath": "pages/setup/index",
"pagePath": "pages/mine/index",
"text": "我的"
}
]

View File

@ -1,11 +1,11 @@
App({
globalData: {
appName: '优品尚'
appName: "够de着",
},
onLaunch (options) {
const that = this
that.autoUpdate()
onLaunch(options) {
const that = this;
that.autoUpdate();
// wx.getSystemInfo({
// success: function (res) {
// const screenWidth = res.screenWidth
@ -13,46 +13,48 @@ App({
// })
// 获取小程序启动参数
wx.setStorage({ key: 'launch_options', data: options })
wx.setStorage({ key: "launch_options", data: options });
},
autoUpdate () {
autoUpdate() {
// 获取小程序更新机制兼容
if (wx.canIUse('getUpdateManager')) { // 是否支持​​小程序更新管理器
const updateManager = wx.getUpdateManager()
if (wx.canIUse("getUpdateManager")) {
// 是否支持​​小程序更新管理器
const updateManager = wx.getUpdateManager();
// 1. 检查小程序是否有新版本发布
updateManager.onCheckForUpdate(res => {
updateManager.onCheckForUpdate((res) => {
// 请求完新版本信息的回调
if (res.hasUpdate) {
// 2. 小程序有新版本,则静默下载新版本,做好更新准备
updateManager.onUpdateReady(() => {
wx.showModal({
title: '更新提示',
content: '小程序已更新,为不影响您的使用,请点击确定进行更新。',
title: "更新提示",
content: "小程序已更新,为不影响您的使用,请点击确定进行更新。",
showCancel: false,
success(e) {
if (e.confirm) {
// 3. 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
updateManager.applyUpdate();
}
}
})
})
},
});
});
updateManager.onUpdateFailed(() => {
// 新的版本下载失败
wx.showModal({
title: '更新提示',
content: '因网络问题更新失败,请您删除当前小程序,重新搜索打开。',
showCancel: false
})
})
title: "更新提示",
content: "因网络问题更新失败,请您删除当前小程序,重新搜索打开。",
showCancel: false,
});
});
}
})
});
} else {
// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
wx.showModal({
title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
title: "提示",
content:
"当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。",
});
}
}
})
},
});

View File

@ -1,4 +1,6 @@
{
"component": true,
"usingComponents": {}
"usingComponents": {
"van-icon": "@vant/weapp/icon/index"
}
}

View File

@ -18,10 +18,7 @@
position: relative;
}
.icon {
width: 48rpx;
height: 48rpx;
background: #ddd;
.van-icon {
margin-bottom: 6rpx;
}

View File

@ -12,27 +12,23 @@ Component<TabBarData, TabBarProperties, TabBarMethods>({
list: [
{
pagePath: "/pages/home/index",
// iconPath: "/images/tab/home.png",
// selectedIconPath: "/images/tab/home-active.png",
iconPath: "home-o",
text: "首页",
},
{
pagePath: "/pages/category/index",
// iconPath: "/images/tab/category.png",
// selectedIconPath: "/images/tab/category-active.png",
iconPath: "apps-o",
text: "分类",
},
{
pagePath: "/pages/cart/cart",
// iconPath: "/images/tab/cart.png",
// selectedIconPath: "/images/tab/cart-active.png",
pagePath: "/pages/shopping-cart/index",
iconPath: "shopping-cart-o",
text: "购物车",
badge: 3,
},
{
pagePath: "/pages/user/user",
// iconPath: "/images/tab/user.png",
// selectedIconPath: "/images/tab/user-active.png",
pagePath: "/pages/mine/index",
iconPath: "friends-o",
text: "我的",
},
] as TabBarItem[],
@ -41,11 +37,9 @@ Component<TabBarData, TabBarProperties, TabBarMethods>({
methods: {
switchTab(e: WechatMiniprogram.TouchEvent) {
const { path, index } = e.currentTarget.dataset as {
const { path } = e.currentTarget.dataset as {
path: string;
index: number;
};
this.setData({ active: index });
wx.switchTab({ url: path });
},
},

View File

@ -1,13 +1,13 @@
<view class="tab-bar">
<view
class="tab-item {{active === index ? 'active' : ''}}"
class="tab-item {{cartCount === index ? 'active' : ''}}"
wx:for="{{list}}"
wx:key="pagePath"
bindtap="switchTab"
data-path="{{item.pagePath}}"
data-index="{{index}}"
>
<image class="icon" src="{{active === index ? item.selectedIconPath : item.iconPath}}" />
<van-icon name="{{ item.iconPath }}" size="50rpx" color="{{ cartCount === index ? '#07c160' : ''}}" />
<text class="text">{{item.text}}</text>
<view class="badge" wx:if="{{item.badge}}">{{item.badge}}</view>
</view>

View File

@ -52,13 +52,27 @@ $theme-color: #02ce26;
align-items: center;
flex-shrink: 0;
.category-icon {
background: #e3e3e3;
border-radius: 32rpx;
border: 6rpx solid #e3e3e3;
font-size: 48rpx;
margin-bottom: 10rpx;
}
.category-name {
padding: 4rpx 8rpx;
font-size: 24rpx;
color: #333;
}
&.active{
.category-icon{
border: 6rpx solid $theme-color;
}
.category-name{
color: #fff;
background: $theme-color;
border-radius: 24rpx;
}
}
}
}
}

View File

@ -1,3 +1,5 @@
import { getGlobalData } from "../../utils/common";
// pages/index/index.ts
Page({
data: {
@ -5,13 +7,14 @@ Page({
statusBarHeight: 0,
navBarHeight: 44,
searchValue: "",
curCategoryId: NaN,
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: "🍱" },
{ id: 1, name: "水果鲜花", icon: "🍎", categoryId: 1 },
{ id: 2, name: "蔬菜豆制品", icon: "🥬", categoryId: 2 },
{ id: 3, name: "肉禽蛋", icon: "🥩", categoryId: 3 },
{ id: 4, name: "海鲜水产", icon: "🐟", categoryId: 4 },
{ id: 5, name: "乳品烘焙", icon: "🥛", categoryId: 5 },
{ id: 6, name: "熟食快", icon: "🍱", categoryId: 6 },
],
recommendTags: ["销量", "折扣", "价格"],
activeTag: "荐 时令推荐",
@ -85,6 +88,7 @@ Page({
},
onLoad() {
this.setData({ curCategoryId: getGlobalData("categoryId") });
const app = getApp();
this.setData({ appName: app.globalData.appName });
this.getSystemInfo();
@ -112,24 +116,33 @@ Page({
}
},
onCategoryTap(e: WechatMiniprogram.TouchEvent) {
// 选择大类目
onChooseCategory(e: any) {
this.setData({ curCategoryId: e.currentTarget.dataset.id });
// testzc 请求接口,获取左类目
},
// 选择左边的类目
onChooseLeftCategory(e: WechatMiniprogram.TouchEvent) {
const { index } = e.currentTarget.dataset;
const categories = this.data.leftCategories.map((item, i) => ({
...item,
active: i === index,
}));
this.setData({ leftCategories: categories });
// testzc 请求接口,获取商品列表
},
onTagTap(e: WechatMiniprogram.TouchEvent) {
// 选择排序
onChooseTab(e: WechatMiniprogram.TouchEvent) {
const { tag } = e.currentTarget.dataset;
this.setData({ activeTag: tag });
},
onProductTap(e: WechatMiniprogram.TouchEvent) {
const { id } = e.currentTarget.dataset;
onGoCommodity(e: WechatMiniprogram.TouchEvent) {
wx.navigateTo({
url: `/pages/product/detail?id=${id}`,
url: `/pages/H5/index?url=${encodeURIComponent(
`https://www.baidu.com?id=${e.currentTarget.dataset.id}`
)}`,
});
},

View File

@ -15,7 +15,7 @@
<!-- 分类导航 -->
<scroll-view class="category-scroll" scroll-x>
<view class="category-list">
<view class="category-item" wx:for="{{categories}}" wx:key="id">
<view class="category-item {{curCategoryId === item.id ? 'active' : ''}}" wx:for="{{categories}}" wx:key="id" data-id="{{ item.id }}" bindtap="onChooseCategory">
<text class="category-icon">{{item.icon}}</text>
<text class="category-name">{{item.name}}</text>
</view>
@ -30,7 +30,7 @@
class="left-category-item {{item.active ? 'active' : ''}}"
wx:for="{{leftCategories}}"
wx:key="id"
bindtap="onCategoryTap"
bindtap="onChooseLeftCategory"
data-index="{{index}}"
>
<text>{{item.name}}</text>
@ -45,7 +45,7 @@
class="tag-item {{activeTag === item ? 'active' : ''}}"
wx:for="{{recommendTags}}"
wx:key="*this"
bindtap="onTagTap"
bindtap="onChooseTab"
data-tag="{{item}}"
>
<text>{{item}}</text>
@ -57,7 +57,7 @@
class="product-card"
wx:for="{{products}}"
wx:key="id"
bindtap="onProductTap"
bindtap="onGoCommodity"
data-id="{{item.id}}"
>
<image class="product-image" src="{{item.image}}" mode="aspectFill" />
@ -82,5 +82,5 @@
</scroll-view>
</view>
<!-- 自定义底部 TabBar -->
<custom-tabbar />
<custom-tabbar cartCount="{{ 1 }}" />
</view>

View File

@ -5,6 +5,7 @@
"usingComponents": {
"van-button": "@vant/weapp/button/index",
"van-icon": "@vant/weapp/icon/index",
"van-notice-bar": "@vant/weapp/notice-bar/index",
"custom-tabbar": "/components/custom-tabbar/index"
},
"navigationStyle": "custom"

View File

@ -4,14 +4,15 @@ $primary-color: #ff3040;
$text-color: #333;
$light-text: #999;
$white: #ffffff;
$theme-color: #02ce26;
$theme-color: #06CD31;
// 通用样式
.home-page {
padding-top: 250rpx;
background: linear-gradient(
to bottom,
$primary-color 0%,
#f5f5f5 20%,
$primary-color 250rpx,
#f5f5f5 50%,
#f5f5f5 100%
);
padding-bottom: 100rpx;
@ -19,6 +20,19 @@ $theme-color: #02ce26;
margin: 16rpx 24rpx 0;
border-radius: 24rpx;
}
.home-page__header{
position: fixed;
top: 0;
left: 0;
padding-bottom: 20rpx;
width: 100%;
background: $primary-color;
z-index: 10000;
transition: background 0.3s ease;
}
.scrolled-style{
background: $white;
}
}
// 包名
.header-appName {
@ -49,6 +63,11 @@ $theme-color: #02ce26;
.placeholder {
color: #ccc;
}
.van-button{
min-width: 120rpx;
height: 58rpx;
font-size: 30rpx;
}
}
}
// 分类网格
@ -66,7 +85,7 @@ $theme-color: #02ce26;
width: 100rpx;
height: 100rpx;
background-color: #bbb;
border-radius: 50%;
border-radius: 40rpx;
margin-bottom: 8rpx;
}
.category-name {
@ -77,12 +96,12 @@ $theme-color: #02ce26;
}
// 促销横幅
.promo-banner {
&.home-page-block-gap {
.van-notice-bar{
padding: 0 16rpx;
border-radius: 16rpx;
}
background: #daf5e2;
padding: 16rpx 24rpx;
font-size: 24rpx;
height: 60rpx;
}
}
// 限时秒杀
.flash-sale {

View File

@ -1,17 +1,24 @@
// pages/index/index.ts
import { setGlobalData } from "../../utils/common";
Page({
data: {
appName: "",
cartCount: 1,
searchValue: "",
isScrolled: false,
categories: [
{ id: 1, name: "七夕花礼", icon: "/icons/flower.png" },
{ id: 2, name: "水果鲜花", icon: "/icons/fruit.png" },
{ id: 3, name: "蔬菜豆制品", icon: "/icons/vegetable.png" },
{ id: 4, name: "肉禽蛋", icon: "/icons/meat.png" },
{ id: 5, name: "海鲜水产", icon: "/icons/seafood.png" },
{ id: 6, name: "乳品烘焙", icon: "/icons/milk.png" },
{ id: 7, name: "巧克力", icon: "/icons/chocolate.png" },
{ id: 2, name: "水果鲜花", categoryId: 1, icon: "/icons/fruit.png" },
{
id: 3,
name: "蔬菜豆制品",
categoryId: 2,
icon: "/icons/vegetable.png",
},
{ id: 4, name: "肉禽蛋", categoryId: 3, icon: "/icons/meat.png" },
{ id: 5, name: "海鲜水产", categoryId: 4, icon: "/icons/seafood.png" },
{ id: 6, name: "乳品烘焙", categoryId: 5, icon: "/icons/milk.png" },
{ id: 7, name: "巧克力", categoryId: 6, icon: "/icons/chocolate.png" },
{ id: 8, name: "薯片", icon: "/icons/chips.png" },
{ id: 9, name: "饮料", icon: "/icons/drink.png" },
{ id: 10, name: "休闲零食", icon: "/icons/snack.png" },
@ -82,6 +89,42 @@ Page({
},
],
},
// 搜索框输入事件
onSearchInput(e: any) {
this.setData({
searchValue: e.detail.value,
});
},
// 搜索按钮点击事件
onSearch() {
// 请求接口
console.warn("----- my data is this.searchValue: ", this.data.searchValue);
},
onPageScroll(e) {
const scrollTop = e.scrollTop;
const targetPx = 50 * 0.5;
if (scrollTop >= targetPx && !this.data.isScrolled) {
this.setData({ isScrolled: true });
} else if (scrollTop < targetPx && this.data.isScrolled) {
this.setData({ isScrolled: false });
}
},
// 去分类
onGoCategory(e: any) {
setGlobalData("categoryId", e.currentTarget.dataset.id);
wx.switchTab({
url: "/pages/category/index",
});
},
// testzc 去商品详情
onGoCommodity(e: any) {
wx.navigateTo({
url: `/pages/H5/index?url=${encodeURIComponent(
`https://www.baidu.com?id=${e.currentTarget.dataset.id}`
)}`,
});
},
onLoad() {
const app = getApp();

View File

@ -1,7 +1,7 @@
<!-- pages/index/index.wxml -->
<view class="home-page">
<!-- 头部 -->
<view class="home-page__header {{isScrolled ? 'scrolled-style' : ''}}">
<view class="header-appName">
<text class="appName">{{ appName }}</text>
</view>
@ -9,20 +9,24 @@
<view class="home-search home-page-block-gap">
<view class="search-bar">
<icon type="search" size="14" color="#999" />
<input placeholder="搜索" placeholder-class="placeholder" />
<van-button round type="primary" size="small">搜索</van-button>
<input placeholder="搜索" placeholder-class="placeholder" bindinput="onSearchInput" />
<van-button round type="primary" size="small" bind:click="onSearch">搜索</van-button>
</view>
</view>
</view>
<!-- 分类图标区 -->
<view class="category-grid home-page-block-gap">
<view class="category-item" wx:for="{{categories}}" wx:key="id">
<view class="category-item" wx:for="{{categories}}" wx:key="id" data-id="{{item.categoryId}}" bindtap="onGoCategory">
<image class="category-icon" src="{{item.icon}}" />
<text class="category-name">{{item.name}}</text>
</view>
</view>
<!-- 促销横幅 -->
<view class="promo-banner home-page-block-gap">
<text>2025年8月31日进入</text>
<van-notice-bar
left-icon="volume-o" background="#daf5e2" color="#333" speed="50"
text="在代码阅读过程中人们说脏话的频率是衡量代码质量的唯一标准。"
/>
</view>
<!-- 限时秒杀 -->
<view class="flash-sale home-page-block-gap">
@ -47,7 +51,7 @@
</view>
<view class="recommendation home-page-block-gap">
<view class="product-list">
<view class="product-item" wx:for="{{recommendedProducts}}" wx:key="id">
<view class="product-item" wx:for="{{recommendedProducts}}" wx:key="id" bindtap="onGoCommodity" data-id="{{item.id}}">
<image class="item-image" src="{{item.image}}" />
<text class="item-name">{{item.name}}</text>
<!-- <view class="item-tags" wx:if="{{item.tags}}">

View File

@ -0,0 +1,11 @@
{
"component": true,
"enablePullDownRefresh": true,
"backgroundTextStyle": "dark",
"usingComponents": {
"van-button": "@vant/weapp/button/index",
"van-icon": "@vant/weapp/icon/index",
"custom-tabbar": "/components/custom-tabbar/index"
},
"navigationStyle": "custom"
}

View File

@ -0,0 +1,84 @@
/* pages/my/my.scss */
.my-page {
min-height: 100vh;
padding-top: 60rpx;
background: linear-gradient(to bottom, #eff6ee 0%, #f5f5f5 50%, #f5f5f5 100%);
.user-section {
padding: 32rpx 32rpx 0;
display: flex;
align-items: center;
.user-image {
width: 100rpx;
height: 100rpx;
// background: #ddd;
border: 8rpx solid #fff;
border-radius: 50%;
}
.user-name {
margin-left: 24rpx;
font-size: 32rpx;
}
}
.order-enter-container {
padding: 40rpx 24rpx 24rpx;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 24rpx;
.order-enter {
padding: 32rpx 0;
min-width: calc(50% - 16rpx);
background: #fff;
border-radius: 12rpx;
display: flex;
align-items: center;
justify-content: center;
}
.order-enter__img {
width: 80rpx;
height: 80rpx;
// border-radius: 50%;
// border: 8rpx solid #ddd;
font-size: 56rpx;
// background-color: #ddd;
}
.order-enter__text {
margin-left: 12rpx;
font-size: 24rpx;
}
}
.other-enter__title {
padding-left: 32rpx;
font-size: 28rpx;
}
.other-enter-container {
margin: 24rpx;
padding: 24rpx;
border-radius: 12rpx;
background: #fff;
.other-enter {
// margin-top: 32rpx;
display: flex;
align-items: center;
gap: 40rpx;
.other-enter__item {
display: flex;
flex-direction: column;
align-items: center;
}
.other-enter__img {
width: 80rpx;
height: 80rpx;
font-size: 54rpx;
// border-radius: 50%;
// border: 8rpx solid #fff;
// background: #ddd;
}
.other-enter__text {
margin-top: 6rpx;
font-size: 24rpx;
}
}
}
}

View File

@ -0,0 +1,29 @@
// pages/my/my.ts
Page({
data: {
currentTab: 2, // 当前选中的tab2表示"我的"页面
},
onLoad() {
// 页面加载时的逻辑
},
switchTab(e: any) {
const index = parseInt(e.currentTarget.dataset.index);
this.setData({
currentTab: index,
});
// 实际项目中这里应该跳转到对应页面
if (index === 0) {
wx.redirectTo({
url: "/pages/index/index",
});
} else if (index === 1) {
wx.redirectTo({
url: "/pages/credit/credit",
});
}
// index为2时是当前页面不需要跳转
},
});

View File

@ -0,0 +1,53 @@
<!-- pages/my/my.wxml -->
<view class="my-page">
<!-- 主要内容区域 -->
<!-- 用户信息区域 -->
<view class="user-section">
<van-icon class="user-image" name="user-o" size="66rpx" />
<!-- <image class="user-image" src="{{item.image}}" /> -->
<view class="user-name">XXX</view>
</view>
<view class="order-enter-container">
<view class="order-enter">
<!-- <image class="order-enter__img" src=""></image> -->
<van-icon class="order-enter__img" name="records-o" />
<view class="order-enter__text">待支付</view>
</view>
<view class="order-enter">
<van-icon class="order-enter__img" name="certificate" />
<!-- <image class="order-enter__img" src=""></image> -->
<view class="order-enter__text">已支付</view>
</view>
<view class="order-enter">
<van-icon class="order-enter__img" name="orders-o" />
<!-- <image class="order-enter__img" src=""></image> -->
<view class="order-enter__text">全部订单</view>
</view>
<view class="order-enter">
<van-icon class="order-enter__img" name="apps-o" />
<!-- <image class="order-enter__img" src=""></image> -->
<view class="order-enter__text">评价中心</view>
</view>
</view>
<view class="other-enter__title">常用功能</view>
<view class="other-enter-container">
<view class="other-enter">
<view class="other-enter__item">
<van-icon class="other-enter__img" name="free-postage" />
<!-- <image class="other-enter__img" src=""></image> -->
<view class="other-enter__text">收获地址</view>
</view>
<view class="other-enter__item">
<van-icon class="other-enter__img" name="phone-o" />
<!-- <image class="other-enter__img" src=""></image> -->
<view class="other-enter__text">联系客服</view>
</view>
<view class="other-enter__item">
<van-icon class="other-enter__img" name="setting-o" />
<!-- <image class="other-enter__img" src=""></image> -->
<view class="other-enter__text">设置</view>
</view>
</view>
</view>
<custom-tabbar cartCount="{{ 3 }}" />
</view>

View File

@ -0,0 +1,9 @@
{
"usingComponents": {
"van-checkbox": "@vant/weapp/checkbox/index",
"van-button": "@vant/weapp/button/index",
"van-icon": "@vant/weapp/icon/index",
"custom-tabbar": "/components/custom-tabbar/index"
},
"navigationStyle": "custom"
}

View File

@ -0,0 +1,186 @@
.shopping-cart-page {
padding-top: 80rpx;
padding-bottom: 160rpx;
.shopping-cart__header {
font-size: 36rpx;
padding-left: 32rpx;
.header__manege {
margin-left: 30rpx;
font-size: 28rpx;
}
}
.shopping-cart__container {
height: 100vh;
background: #f5f5f5;
.shopping-cart__item {
position: relative;
display: flex;
align-items: center;
max-width: 100%;
background: #fff;
padding: 16rpx 24rpx;
left: 0;
transition: all 0.3s ease;
&.active{
left: -90rpx;
}
&+.shopping-cart__item {
margin-top: 20rpx;
}
.item__image {
display: flex;
align-items: center;
.image__icon {
width: 160rpx;
height: 160rpx;
background: #ddd;
border-radius: 16rpx;
}
}
.item__texts {
margin-left: 24rpx;
flex: 1;
width: 0;
font-size: 28rpx;
.item__title {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.item__attribute {
margin-top: 12rpx;
color: #888;
}
.item__line {
display: flex;
align-items: center;
justify-content: space-between;
.line__price {
display: flex;
align-items: flex-end;
.line__price__actual {
color: #FD6301;
text {
font-size: 40rpx;
}
}
.line__price__origin {
font-size: 24rpx;
margin-left: 12rpx;
margin-bottom: 6rpx;
text-decoration-line: line-through;
color: #999;
}
}
.line__num {
display: flex;
align-items: center;
font-size: 28rpx;
border: 2rpx solid #ddd;
border-radius: 8rpx;
.num__number {
padding: 4rpx 0;
width: 72rpx;
text-align: center;
border-left: 2rpx solid #ddd;
border-right: 2rpx solid #ddd;
}
.van-icon {
padding: 12rpx 8rpx 8rpx;
font-size: 28rpx;
font-weight: bold;
}
}
}
}
.item__btns{
position: absolute;
right: -90rpx;
top: 0;
height: 100%;
.item__btns__wrap{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 90rpx;
height: 100%;
background: #fd3301;
color: #fff;
font-size: 22rpx;
text{
margin-top: 8rpx;
}
}
}
}
}
.shopping-cart__footer {
position: fixed;
left: 0;
bottom: 100rpx;
padding: 16rpx 16rpx 16rpx 32rpx;
box-sizing: border-box;
width: 100%;
display: flex;
align-items: center;
background: #fff;
.footer__center {
font-size: 32rpx;
flex: 1;
.footer__center__line {
display: flex;
align-items: flex-end;
flex-direction: row-reverse;
.footer__center__price {
font-weight: bold;
color: #FD6301;
text {
font-size: 48rpx;
}
}
&+.footer__center__line {
color: #FD6301;
.van-icon {
font-size: 24rpx;
margin-bottom: 10rpx;
}
}
}
}
.van-button {
margin-left: 16rpx;
color: #fff;
background: #01cf24;
border-radius: 40rpx;
padding: 8rpx 60rpx;
height: 80rpx;
}
}
}

View File

@ -0,0 +1,65 @@
// pages/index/index.ts
Page({
data: {
isManage: false,
startX: 0,
commodities: [
{
id: 1,
name: "水果鲜花是非得失发多少覅是范德萨司法的",
icon: "🍎",
active: false,
},
{ id: 2, name: "蔬菜豆制品", icon: "🥬", active: false },
{ id: 3, name: "肉禽蛋", icon: "🥩", active: false },
{ id: 4, name: "海鲜水产", icon: "🐟", active: false },
{ id: 5, name: "乳品烘焙", icon: "🥛", active: false },
{ id: 6, name: "熟食快", icon: "🍱", active: false },
],
},
onLoad() {},
// 点击管理按钮
onManage() {
this.setData({ isManage: !this.data.isManage });
this.setData({
commodities: this.data.commodities.map((item) => ({
...item,
active: this.data.isManage,
})),
});
},
// 触摸开始
handleTouchStart(e: any) {
this.setData({
startX: e.touches[0].clientX, // 记录起始X坐标
});
},
// 触摸移动
handleTouchMove(e: any) {
const { id, active } = e.currentTarget.dataset.item;
const moveX = e.touches[0].clientX - this.data.startX;
// 只响应向左滑动moveX为负值
if (moveX < -20) {
if (active) return;
const data = this.data.commodities.map((item) => {
item.active = item.id === id;
return item;
});
this.setData({ commodities: data });
} else {
this.setData({
commodities: this.data.commodities.map((item) => ({
...item,
active: false,
})),
});
}
},
// 删除商品
onDeleteItem(e: any) {
const { id } = e.currentTarget.dataset;
const data = this.data.commodities.filter((item) => item.id !== id);
this.setData({ commodities: data });
},
});

View File

@ -0,0 +1,54 @@
<view class="shopping-cart-page">
<view class="shopping-cart__header">
<text class="header__name">购物车</text>
<text class="header__manege" bindtap="onManage">{{!isManage ?'管理' : '退出管理'}}</text>
</view>
<view class="shopping-cart__container">
<view class="shopping-cart__item {{ item.active ? 'active' : '' }}" wx:for="{{commodities}}" wx:key="id" data-item="{{ item }}" bindtouchstart="handleTouchStart" bindtouchmove="handleTouchMove">
<view class="item__image">
<van-checkbox value="{{ checked }}" bind:change="onChange">
</van-checkbox>
<image class="image__icon" src="{{item.icon}}" />
</view>
<view class="item__texts">
<view class="item__title">{{item.name}}</view>
<view class="item__attribute">我是属性</view>
<view class="item__line">
<view class="line__price">
<view class="line__price__actual">¥<text>20</text>.00</view>
<view class="line__price__origin">¥39.00</view>
</view>
<view class="line__num">
<van-icon name="minus" />
<view class="num__number">1</view>
<van-icon name="plus" />
</view>
</view>
</view>
<view class="item__btns">
<view class="item__btns__wrap" data-id="{{ item.id }}" bindtap="onDeleteItem">
<van-icon name="delete-o" color="#fff" size="32rpx" />
<text>删除</text>
</view>
</view>
</view>
</view>
<view class="shopping-cart__footer">
<van-checkbox value="{{ checked }}" bind:change="onChange"></van-checkbox>
<view class="footer__center">
<view class="footer__center__line">
<view class="footer__center__price">
¥<text>50</text>.52
</view>
<text class="footer__center__title">合计:</text>
</view>
<view class="footer__center__line">
<van-icon name="arrow-up" />
<text class="footer__center__detail-btn">| 明细</text>
<text>红包共减 ¥30.34 </text>
</view>
</view>
<van-button>结算(2)</van-button>
</view>
<custom-tabbar cartCount="{{ 2 }}" />
</view>

View File

@ -0,0 +1,18 @@
// 存储 TabBar 跳转参数
export const setGlobalData = (key: string, data: any) => {
if (!data) {
console.error("参数必须是一个对象");
return;
}
getApp().globalData[key] = data;
};
// 获取 TabBar 跳转参数(并自动清除)
export const getGlobalData = (key: string) => {
const params = getApp().globalData[key];
if (params) {
delete getApp().globalData[key]; // 获取后自动清理
return params;
}
return null;
};