打包文件
This commit is contained in:
parent
64d0010303
commit
be76c9ccc4
|
@ -1,7 +1,7 @@
|
||||||
# 预发布环境的环境变量(命名必须以 VITE_ 开头)
|
# 预发布环境的环境变量(命名必须以 VITE_ 开头)
|
||||||
|
|
||||||
## 后端接口地址(如果解决跨域问题采用 CORS 就需要写绝对路径)
|
## 后端接口地址(如果解决跨域问题采用 CORS 就需要写绝对路径)
|
||||||
VITE_BASE_URL = https://apifoxmock.com/m1/2930465-2145633-default/api/v1
|
VITE_BASE_URL = '/shop-api/api'
|
||||||
|
|
||||||
## 打包构建静态资源公共路径(例如部署到 https://un-pany.github.io/ 域名下就需要填写 /)
|
## 打包构建静态资源公共路径(例如部署到 https://un-pany.github.io/ 域名下就需要填写 /)
|
||||||
VITE_PUBLIC_PATH = /
|
VITE_PUBLIC_PATH = /shop/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { demoRoutes, emptyDemoRoutes, systemRoutes } from "@/router"
|
import { systemRoutes } from "@/router"
|
||||||
import Description from "@@/components/Description.vue"
|
import Description from "@@/components/Description.vue"
|
||||||
import Cell from "./components/Cell.vue"
|
import Cell from "./components/Cell.vue"
|
||||||
import Title from "./components/Title.vue"
|
import Title from "./components/Title.vue"
|
||||||
|
@ -11,17 +11,7 @@ import Title from "./components/Title.vue"
|
||||||
<div un-mt-40px>
|
<div un-mt-40px>
|
||||||
<Title text="示例集合" />
|
<Title text="示例集合" />
|
||||||
<Cell
|
<Cell
|
||||||
v-for="route in [...demoRoutes, ...systemRoutes]"
|
v-for="route in [...systemRoutes]"
|
||||||
:key="route.path"
|
|
||||||
:title="route.meta?.title || ''"
|
|
||||||
:path="route.path"
|
|
||||||
un-mt-12px
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div un-my-20px>
|
|
||||||
<Title text="更多示例" />
|
|
||||||
<Cell
|
|
||||||
v-for="route in emptyDemoRoutes"
|
|
||||||
:key="route.path"
|
:key="route.path"
|
||||||
:title="route.meta?.title || ''"
|
:title="route.meta?.title || ''"
|
||||||
:path="route.path"
|
:path="route.path"
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useCartStore } from "@/pinia/stores/cart"
|
||||||
|
import { useProductStore } from "@/pinia/stores/product"
|
||||||
import { throttle } from "lodash-es"
|
import { throttle } from "lodash-es"
|
||||||
import { storeToRefs } from "pinia"
|
import { storeToRefs } from "pinia"
|
||||||
import VanPopup from "vant/es/popup"
|
import VanPopup from "vant/es/popup"
|
||||||
import { computed, onBeforeUnmount, onMounted, ref } from "vue"
|
import { computed, onBeforeUnmount, onMounted, ref } from "vue"
|
||||||
import Detail from "./components/detail.vue"
|
|
||||||
import Cart from "./components/cart.vue"
|
import Cart from "./components/cart.vue"
|
||||||
import { useProductStore } from "@/pinia/stores/product"
|
import Detail from "./components/detail.vue"
|
||||||
import { useCartStore } from "@/pinia/stores/cart"
|
|
||||||
|
|
||||||
// 状态管理
|
// 状态管理
|
||||||
const productStore = useProductStore()
|
const productStore = useProductStore()
|
||||||
|
@ -49,13 +49,16 @@ function handleCategoryClick(index: number) {
|
||||||
|
|
||||||
// 节流的滚动位置计算(用于切换左侧导航激活状态)
|
// 节流的滚动位置计算(用于切换左侧导航激活状态)
|
||||||
const throttledUpdate = throttle(() => {
|
const throttledUpdate = throttle(() => {
|
||||||
if (!scrollContainer.value) return
|
if (!scrollContainer.value || !categoryRefs.value.length) return
|
||||||
|
|
||||||
|
// 添加数组元素存在性检查
|
||||||
|
const validRefs = categoryRefs.value.filter(Boolean)
|
||||||
|
if (!validRefs.length) return
|
||||||
|
|
||||||
const containerTop = scrollContainer.value.getBoundingClientRect().top
|
const containerTop = scrollContainer.value.getBoundingClientRect().top
|
||||||
const offsets = categoryRefs.value.map((el) => {
|
const offsets = validRefs.map((el) => {
|
||||||
return el.getBoundingClientRect().top - containerTop
|
return el.getBoundingClientRect().top - containerTop
|
||||||
})
|
})
|
||||||
|
|
||||||
let activeIndex = 0
|
let activeIndex = 0
|
||||||
for (let i = offsets.length - 1; i >= 0; i--) {
|
for (let i = offsets.length - 1; i >= 0; i--) {
|
||||||
if (offsets[i] < 100) {
|
if (offsets[i] < 100) {
|
||||||
|
@ -87,7 +90,7 @@ function handleRemoveFromCart(product: any) {
|
||||||
cartStore.removeFromCart(product.id)
|
cartStore.removeFromCart(product.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCartItemCount = (productId: number) => {
|
function getCartItemCount(productId: number) {
|
||||||
const item = cartItems.value.find(item => item.product.id === productId)
|
const item = cartItems.value.find(item => item.product.id === productId)
|
||||||
return item ? item.quantity : 0
|
return item ? item.quantity : 0
|
||||||
}
|
}
|
||||||
|
@ -105,11 +108,11 @@ onBeforeUnmount(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// 结算方法
|
// 结算方法
|
||||||
function handleCheckout() {
|
const router = useRouter()
|
||||||
// 这里可以添加结算逻辑
|
|
||||||
console.log('去结算', totalPrice.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
function handleCheckout() {
|
||||||
|
router.push("/product/checkout")
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -180,7 +183,7 @@ function handleCheckout() {
|
||||||
:style="{
|
:style="{
|
||||||
opacity: product.stock === 0 ? 0.6 : 1,
|
opacity: product.stock === 0 ? 0.6 : 1,
|
||||||
}"
|
}"
|
||||||
></van-button>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -190,8 +193,10 @@ function handleCheckout() {
|
||||||
<!-- 底部购物车栏 -->
|
<!-- 底部购物车栏 -->
|
||||||
<div v-if="cartItems.length" class="shopping-cart-bar">
|
<div v-if="cartItems.length" class="shopping-cart-bar">
|
||||||
<div class="cart-info">
|
<div class="cart-info">
|
||||||
<van-badge :content="totalQuantity"
|
<van-badge
|
||||||
@click.stop="showCartPopup = true">
|
:content="totalQuantity"
|
||||||
|
@click.stop="showCartPopup = true"
|
||||||
|
>
|
||||||
<van-icon name="shopping-cart-o" size="24" />
|
<van-icon name="shopping-cart-o" size="24" />
|
||||||
</van-badge>
|
</van-badge>
|
||||||
<div class="total-price">
|
<div class="total-price">
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useCartStore } from "@/pinia/stores/cart"
|
import { useCartStore } from "@/pinia/stores/cart"
|
||||||
import { storeToRefs } from "pinia"
|
import { storeToRefs } from "pinia"
|
||||||
import { showConfirmDialog } from 'vant'
|
import { showConfirmDialog } from "vant"
|
||||||
|
import { useRouter } from "vue-router"
|
||||||
|
|
||||||
// 状态管理
|
// 新增购物车状态
|
||||||
const cartStore = useCartStore()
|
|
||||||
const { cartItems, totalPrice, totalQuantity } = storeToRefs(cartStore) // 新增购物车状态
|
|
||||||
|
|
||||||
// 定义组件事件:关闭详情
|
// 定义组件事件:关闭详情
|
||||||
const emit = defineEmits(["cartClose"])
|
const emit = defineEmits(["cartClose"])
|
||||||
|
const router = useRouter()
|
||||||
// 处理关闭按钮点击事件
|
// 状态管理
|
||||||
|
const cartStore = useCartStore()
|
||||||
|
const { cartItems, totalPrice, totalQuantity } = storeToRefs(cartStore)// 处理关闭按钮点击事件
|
||||||
function handleClose() {
|
function handleClose() {
|
||||||
emit("cartClose")
|
emit("cartClose")
|
||||||
}
|
}
|
||||||
|
@ -24,20 +25,20 @@ function handleRemoveFromCart(product: any) {
|
||||||
|
|
||||||
function handleClearCart() {
|
function handleClearCart() {
|
||||||
showConfirmDialog({
|
showConfirmDialog({
|
||||||
title: '确认清空购物车吗?',
|
title: "确认清空购物车吗?"
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
cartStore.clearCart()
|
cartStore.clearCart()
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
// on cancel
|
// on cancel
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 结算方法
|
// 结算方法
|
||||||
function handleCheckout() {
|
function handleCheckout() {
|
||||||
// 这里可以添加结算逻辑
|
handleClose()
|
||||||
console.log('去结算', totalPrice.value)
|
router.push("/product/checkout")
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -46,8 +47,12 @@ function handleCheckout() {
|
||||||
<!-- 修改后的header结构 -->
|
<!-- 修改后的header结构 -->
|
||||||
<div class="flex-header">
|
<div class="flex-header">
|
||||||
<div class="clear-header">
|
<div class="clear-header">
|
||||||
<van-button size="small" type="primary" class="clear-btn" plain
|
<van-button
|
||||||
@click="handleClearCart">清空购物车</van-button>
|
size="small" type="primary" class="clear-btn" plain
|
||||||
|
@click="handleClearCart"
|
||||||
|
>
|
||||||
|
清空购物车
|
||||||
|
</van-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="product-list">
|
<div class="product-list">
|
||||||
|
@ -76,8 +81,10 @@ function handleCheckout() {
|
||||||
<div class="cart-actions">
|
<div class="cart-actions">
|
||||||
<van-button size="mini" icon="minus" @click.stop="handleRemoveFromCart(item.product)" />
|
<van-button size="mini" icon="minus" @click.stop="handleRemoveFromCart(item.product)" />
|
||||||
<span class="cart-count">{{ item.quantity }}</span>
|
<span class="cart-count">{{ item.quantity }}</span>
|
||||||
<van-button size="mini" type="primary" class="add-cart-btn" icon="plus"
|
<van-button
|
||||||
@click.stop="handleAddToCart(item.product)"></van-button>
|
size="mini" type="primary" class="add-cart-btn" icon="plus"
|
||||||
|
@click.stop="handleAddToCart(item.product)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,251 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useCartStore } from "@/pinia/stores/cart"
|
||||||
|
import { storeToRefs } from "pinia"
|
||||||
|
import { showConfirmDialog } from "vant"
|
||||||
|
import { ref } from "vue"
|
||||||
|
|
||||||
|
const cartStore = useCartStore()
|
||||||
|
const { cartItems, totalPrice } = storeToRefs(cartStore)
|
||||||
|
|
||||||
|
// 支付方式选项
|
||||||
|
const paymentMethods = [
|
||||||
|
{ value: 1, label: "微信支付", icon: "wechat" },
|
||||||
|
{ value: 2, label: "支付宝", icon: "alipay" },
|
||||||
|
{ value: 3, label: "银行卡支付", icon: "credit-pay" }
|
||||||
|
]
|
||||||
|
|
||||||
|
const selectedPayment = ref<number>()
|
||||||
|
const contact = ref("")
|
||||||
|
const remark = ref("")
|
||||||
|
const submitting = ref(false)
|
||||||
|
|
||||||
|
// 提交订单
|
||||||
|
async function handleSubmit() {
|
||||||
|
if (!cartItems.value.length) {
|
||||||
|
return showConfirmDialog({
|
||||||
|
title: "提示",
|
||||||
|
message: "请先选择商品后再结算"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectedPayment.value) {
|
||||||
|
return showConfirmDialog({
|
||||||
|
title: "提示",
|
||||||
|
message: "请选择支付方式"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
submitting.value = true
|
||||||
|
try {
|
||||||
|
// TODO: 调用实际的下单API
|
||||||
|
console.log("提交订单", {
|
||||||
|
items: cartItems.value,
|
||||||
|
total: totalPrice.value,
|
||||||
|
paymentMethod: selectedPayment.value,
|
||||||
|
contact: contact.value,
|
||||||
|
remark: remark.value
|
||||||
|
})
|
||||||
|
|
||||||
|
await showConfirmDialog({
|
||||||
|
title: "提交成功",
|
||||||
|
message: "订单已创建,正在跳转支付..."
|
||||||
|
})
|
||||||
|
|
||||||
|
// 清空购物车
|
||||||
|
cartStore.clearCart()
|
||||||
|
} finally {
|
||||||
|
submitting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="checkout-container">
|
||||||
|
<!-- 新增固定导航栏 -->
|
||||||
|
<van-nav-bar
|
||||||
|
title="结算页面"
|
||||||
|
left-text="返回"
|
||||||
|
left-arrow
|
||||||
|
fixed
|
||||||
|
@click-left="() => $router.go(-1)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 原有内容容器 -->
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<!-- 原有商品列表等代码保持不动 -->
|
||||||
|
<van-cell-group class="product-list">
|
||||||
|
<van-cell
|
||||||
|
v-for="item in cartItems"
|
||||||
|
:key="item.product.id"
|
||||||
|
class="product-item"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<van-image
|
||||||
|
:src="item.product.image"
|
||||||
|
width="60"
|
||||||
|
height="60"
|
||||||
|
class="product-image"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="product-info">
|
||||||
|
<div class="product-name van-ellipsis">
|
||||||
|
{{ item.product.name }}
|
||||||
|
</div>
|
||||||
|
<div class="price-row">
|
||||||
|
<span class="product-price">
|
||||||
|
¥{{ item.product.price.toFixed(2) }}
|
||||||
|
</span>
|
||||||
|
<span class="quantity">
|
||||||
|
×{{ item.quantity }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</van-cell>
|
||||||
|
</van-cell-group>
|
||||||
|
|
||||||
|
<!-- 联系方式与备注 -->
|
||||||
|
<van-cell-group class="contact-form">
|
||||||
|
<van-field
|
||||||
|
v-model="contact"
|
||||||
|
label="联系方式"
|
||||||
|
placeholder="请输入手机号"
|
||||||
|
:rules="[
|
||||||
|
{ required: true, message: '请填写联系方式' },
|
||||||
|
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确' },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
<van-field
|
||||||
|
v-model="remark"
|
||||||
|
label="备注"
|
||||||
|
type="textarea"
|
||||||
|
placeholder="选填,可备注特殊需求"
|
||||||
|
rows="2"
|
||||||
|
autosize
|
||||||
|
/>
|
||||||
|
</van-cell-group>
|
||||||
|
|
||||||
|
<!-- 支付方式选择 -->
|
||||||
|
<van-cell-group title="支付方式" class="payment-methods">
|
||||||
|
<van-radio-group v-model="selectedPayment">
|
||||||
|
<van-cell
|
||||||
|
v-for="method in paymentMethods"
|
||||||
|
:key="method.value"
|
||||||
|
clickable
|
||||||
|
@click="selectedPayment = method.value"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<van-icon :name="method.icon" class="method-icon" />
|
||||||
|
</template>
|
||||||
|
<template #title>
|
||||||
|
<span class="method-label">{{ method.label }}</span>
|
||||||
|
</template>
|
||||||
|
<template #right-icon>
|
||||||
|
<van-radio :name="method.value" />
|
||||||
|
</template>
|
||||||
|
</van-cell>
|
||||||
|
</van-radio-group>
|
||||||
|
</van-cell-group>
|
||||||
|
|
||||||
|
<!-- 提交订单栏 -->
|
||||||
|
<div class="submit-bar">
|
||||||
|
<div class="total-price">
|
||||||
|
合计:¥{{ totalPrice.toFixed(2) }}
|
||||||
|
</div>
|
||||||
|
<van-button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
:loading="submitting"
|
||||||
|
loading-text="提交中..."
|
||||||
|
@click="handleSubmit"
|
||||||
|
>
|
||||||
|
提交订单
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.van-nav-bar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 999;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid #ebedf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
padding-top: 46px; /* 导航栏高度 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkout-container {
|
||||||
|
padding: 12px 16px 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-list {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-item {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-image {
|
||||||
|
margin-right: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-price {
|
||||||
|
color: #e95d5d;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity {
|
||||||
|
color: #666;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-label {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-bar {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 10px 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-price {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #e95d5d;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -8,33 +8,13 @@ export interface Product {
|
||||||
stock: number // 商品库存
|
stock: number // 商品库存
|
||||||
description: string // 商品描述
|
description: string // 商品描述
|
||||||
image: string // 商品图片URL
|
image: string // 商品图片URL
|
||||||
|
label: number // 商品标签
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useProductStore = defineStore("product", () => {
|
export const useProductStore = defineStore("product", () => {
|
||||||
// 商品数据
|
// 商品数据
|
||||||
const labels = ref([
|
const labels = ref<Array<{ id: number, name: string }>>([])
|
||||||
{ id: 1, name: "热门推荐" },
|
const categories = ref<Product[]>([])
|
||||||
{ id: 2, name: "手机数码" },
|
|
||||||
{ id: 3, name: "家用电器" },
|
|
||||||
{ id: 4, name: "电脑办公" }
|
|
||||||
])
|
|
||||||
const categories = ref([
|
|
||||||
{ id: 1, name: "商品1", price: 99.9, image: "/img/1.jpg", label: 1, stock: 10, description: "主动降噪,30小时续航,IPX4防水等级" },
|
|
||||||
{ id: 2, name: "商品2", price: 199.9, image: "/img/2.jpg", label: 1, stock: 990, description: "主动降噪,30小时续航,IPX4防水等级" },
|
|
||||||
{ id: 3, name: "旗舰手机", price: 5999, image: "/img/3.jpg", label: 2, stock: -1, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 4, name: "旗舰手机", price: 5999, image: "/img/4.jpg", label: 2, stock: -1, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 5, name: "旗舰手机", price: 5999, image: "/img/5.jpg", label: 2, stock: -1, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 6, name: "旗舰手机", price: 5999, image: "/img/6.jpg", label: 2, stock: -1, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 7, name: "旗舰手机", price: 5999, image: "/img/7.jpg", label: 2, stock: 999, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 10, name: "旗舰手机", price: 5999, image: "/img/10.jpg", label: 3, stock: 999, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 13, name: "旗舰手机", price: 5999, image: "/img/13.jpg", label: 3, stock: 999, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 14, name: "旗舰手机", price: 5999, image: "/img/14.jpg", label: 3, stock: 999, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 15, name: "旗舰手机", price: 5999, image: "/img/15.jpg", label: 3, stock: 0, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 16, name: "旗舰手机", price: 5999, image: "/img/16.jpg", label: 3, stock: 0, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 17, name: "旗舰手机", price: 5999, image: "/img/17.jpg", label: 3, stock: 0, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 18, name: "旗舰手机", price: 5999, image: "/img/18.jpg", label: 4, stock: 50, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" },
|
|
||||||
{ id: 20, name: "旗舰手机", price: 5999, image: "/img/20.jpg", label: 4, stock: 10, description: "骁龙8 Gen2处理器,1亿像素主摄,120Hz刷新率屏幕" }
|
|
||||||
])
|
|
||||||
|
|
||||||
const getGoods = async () => {
|
const getGoods = async () => {
|
||||||
try {
|
try {
|
||||||
|
@ -57,11 +37,11 @@ export const useProductStore = defineStore("product", () => {
|
||||||
label: g.categoryId
|
label: g.categoryId
|
||||||
}))
|
}))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取商品数据失败:', error)
|
console.error("获取商品数据失败:", error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getGoods();
|
getGoods()
|
||||||
return { labels: labels, categories, getGoods }
|
return { labels, categories, getGoods }
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,6 +29,32 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
|
|
||||||
/** 业务页面 */
|
/** 业务页面 */
|
||||||
export const routes: RouteRecordRaw[] = [
|
export const routes: RouteRecordRaw[] = [
|
||||||
|
{
|
||||||
|
path: "/product/checkout",
|
||||||
|
component: () => import("@/pages/product/components/checkout.vue"),
|
||||||
|
name: "Checkout",
|
||||||
|
meta: {
|
||||||
|
title: "订单结算"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/",
|
||||||
|
component: () => import("@/pages/product/ProductList.vue"),
|
||||||
|
name: "ProductList",
|
||||||
|
meta: {
|
||||||
|
title: "商品列表",
|
||||||
|
keepAlive: true,
|
||||||
|
layout: {
|
||||||
|
navBar: {
|
||||||
|
showNavBar: false,
|
||||||
|
showLeftArrow: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
/* export const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: "/login",
|
path: "/login",
|
||||||
component: () => import("@/pages/login/index.vue"),
|
component: () => import("@/pages/login/index.vue"),
|
||||||
|
@ -76,7 +102,7 @@ export const routes: RouteRecordRaw[] = [
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
/** 示例页面 */
|
// 示例页面
|
||||||
export const demoRoutes: RouteRecordRaw[] = [
|
export const demoRoutes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: "/product",
|
path: "/product",
|
||||||
|
@ -160,9 +186,9 @@ export const demoRoutes: RouteRecordRaw[] = [
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
*/
|
||||||
/** 空示例页面 */
|
/** 空示例页面 */
|
||||||
export const emptyDemoRoutes: RouteRecordRaw[] = [
|
/* export const emptyDemoRoutes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: "/i18n",
|
path: "/i18n",
|
||||||
component: () => import("@/pages/demo/i18n.vue"),
|
component: () => import("@/pages/demo/i18n.vue"),
|
||||||
|
@ -205,12 +231,12 @@ export const emptyDemoRoutes: RouteRecordRaw[] = [
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
] */
|
||||||
|
|
||||||
/** 路由实例 */
|
/** 路由实例 */
|
||||||
export const router = createRouter({
|
export const router = createRouter({
|
||||||
history: VITE_ROUTER_HISTORY === "hash" ? createWebHashHistory(VITE_PUBLIC_PATH) : createWebHistory(VITE_PUBLIC_PATH),
|
history: VITE_ROUTER_HISTORY === "hash" ? createWebHashHistory(VITE_PUBLIC_PATH) : createWebHistory(VITE_PUBLIC_PATH),
|
||||||
routes: [...systemRoutes, ...routes, ...demoRoutes, ...emptyDemoRoutes]
|
routes: [...systemRoutes, ...routes]
|
||||||
})
|
})
|
||||||
|
|
||||||
// 注册路由导航守卫
|
// 注册路由导航守卫
|
||||||
|
|
|
@ -16,19 +16,15 @@ declare module 'vue' {
|
||||||
VanCellGroup: typeof import('vant/es')['CellGroup']
|
VanCellGroup: typeof import('vant/es')['CellGroup']
|
||||||
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
||||||
VanDivider: typeof import('vant/es')['Divider']
|
VanDivider: typeof import('vant/es')['Divider']
|
||||||
VanEmpty: typeof import('vant/es')['Empty']
|
|
||||||
VanField: typeof import('vant/es')['Field']
|
VanField: typeof import('vant/es')['Field']
|
||||||
VanForm: typeof import('vant/es')['Form']
|
|
||||||
VanIcon: typeof import('vant/es')['Icon']
|
VanIcon: typeof import('vant/es')['Icon']
|
||||||
VanImage: typeof import('vant/es')['Image']
|
VanImage: typeof import('vant/es')['Image']
|
||||||
VanLoading: typeof import('vant/es')['Loading']
|
VanLoading: typeof import('vant/es')['Loading']
|
||||||
VanNavBar: typeof import('vant/es')['NavBar']
|
VanNavBar: typeof import('vant/es')['NavBar']
|
||||||
VanNoticeBar: typeof import('vant/es')['NoticeBar']
|
|
||||||
VanRadio: typeof import('vant/es')['Radio']
|
VanRadio: typeof import('vant/es')['Radio']
|
||||||
VanRadioGroup: typeof import('vant/es')['RadioGroup']
|
VanRadioGroup: typeof import('vant/es')['RadioGroup']
|
||||||
VanSidebar: typeof import('vant/es')['Sidebar']
|
VanSidebar: typeof import('vant/es')['Sidebar']
|
||||||
VanSidebarItem: typeof import('vant/es')['SidebarItem']
|
VanSidebarItem: typeof import('vant/es')['SidebarItem']
|
||||||
VanSwitch: typeof import('vant/es')['Switch']
|
|
||||||
VanTabbar: typeof import('vant/es')['Tabbar']
|
VanTabbar: typeof import('vant/es')['Tabbar']
|
||||||
VanTabbarItem: typeof import('vant/es')['TabbarItem']
|
VanTabbarItem: typeof import('vant/es')['TabbarItem']
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ export default defineConfig(({ mode }) => {
|
||||||
const { VITE_PUBLIC_PATH } = loadEnv(mode, process.cwd(), "") as ImportMetaEnv
|
const { VITE_PUBLIC_PATH } = loadEnv(mode, process.cwd(), "") as ImportMetaEnv
|
||||||
return {
|
return {
|
||||||
// 开发或打包构建时用到的公共基础路径
|
// 开发或打包构建时用到的公共基础路径
|
||||||
base: "./",
|
base: VITE_PUBLIC_PATH,
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
// @ 符号指向 src 目录
|
// @ 符号指向 src 目录
|
||||||
|
|
Loading…
Reference in New Issue