feat: cache
This commit is contained in:
parent
bd203f2f22
commit
beded95be0
32
components.d.ts
vendored
Normal file
32
components.d.ts
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
// biome-ignore lint: disable
|
||||
export {}
|
||||
|
||||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
VanArea: typeof import('vant/es')['Area']
|
||||
VanButton: typeof import('vant/es')['Button']
|
||||
VanCell: typeof import('vant/es')['Cell']
|
||||
VanCellGroup: typeof import('vant/es')['CellGroup']
|
||||
VanCheckbox: typeof import('vant/es')['Checkbox']
|
||||
VanCheckboxGroup: typeof import('vant/es')['CheckboxGroup']
|
||||
VanField: typeof import('vant/es')['Field']
|
||||
VanForm: typeof import('vant/es')['Form']
|
||||
VanIcon: typeof import('vant/es')['Icon']
|
||||
VanNoticeBar: typeof import('vant/es')['NoticeBar']
|
||||
VanPopover: typeof import('vant/es')['Popover']
|
||||
VanPopup: typeof import('vant/es')['Popup']
|
||||
VanRate: typeof import('vant/es')['Rate']
|
||||
VanSearch: typeof import('vant/es')['Search']
|
||||
VanTab: typeof import('vant/es')['Tab']
|
||||
VanTabs: typeof import('vant/es')['Tabs']
|
||||
VanTag: typeof import('vant/es')['Tag']
|
||||
VanUploader: typeof import('vant/es')['Uploader']
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,7 @@
|
||||
"format": "prettier --write src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vant/area-data": "^2.1.0",
|
||||
"axios": "^1.11.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lz-utils-lib": "^1.0.60",
|
||||
@ -30,6 +31,7 @@
|
||||
"devDependencies": {
|
||||
"@tsconfig/node22": "^22.0.2",
|
||||
"@types/node": "^22.16.5",
|
||||
"@vant/auto-import-resolver": "^1.3.0",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@vue/eslint-config-prettier": "^10.2.0",
|
||||
"@vue/eslint-config-typescript": "^14.6.0",
|
||||
@ -44,6 +46,7 @@
|
||||
"typescript": "~5.8.0",
|
||||
"unocss": "^66.4.2",
|
||||
"unplugin-auto-import": "^20.0.0",
|
||||
"unplugin-vue-components": "^29.1.0",
|
||||
"vite": "^7.0.6",
|
||||
"vite-plugin-vue-devtools": "^8.0.0",
|
||||
"vue-tsc": "^3.0.4"
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
@import "./base.scss";
|
||||
|
||||
@use './base.scss' as *;
|
||||
@use './variables.scss' as *;
|
||||
|
||||
16
src/assets/variables.scss
Normal file
16
src/assets/variables.scss
Normal file
@ -0,0 +1,16 @@
|
||||
$theme-color: #01cf24;
|
||||
$theme-disabled-color: #cefad5;
|
||||
|
||||
.theme-bg-color {
|
||||
background: $theme-color !important;
|
||||
}
|
||||
.theme-border-color {
|
||||
border-color: $theme-color !important;
|
||||
}
|
||||
.theme-disabled-color {
|
||||
background: $theme-disabled-color !important;
|
||||
}
|
||||
|
||||
.theme-color {
|
||||
color: $theme-color !important;
|
||||
}
|
||||
@ -1,9 +1,16 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{
|
||||
path: '/demo',
|
||||
name: 'demo',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/demo/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/commodity-detail',
|
||||
name: 'commodity-detail',
|
||||
@ -12,6 +19,46 @@ const router = createRouter({
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/commodity-detail/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/order',
|
||||
name: 'order',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/order/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/order/detail',
|
||||
name: 'order/detail',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/order/detail.vue'),
|
||||
},
|
||||
{
|
||||
path: '/search-container',
|
||||
name: 'search-container',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/search-container/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/review/center',
|
||||
name: 'review/center',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/review/center.vue'),
|
||||
},
|
||||
{
|
||||
path: '/review/write',
|
||||
name: 'review/write',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/review/write.vue'),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
7
src/stores/app.ts
Normal file
7
src/stores/app.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useAppStore = defineStore('app', () => {
|
||||
const themeColor = '#01CF24'
|
||||
|
||||
return { themeColor }
|
||||
})
|
||||
@ -1,12 +0,0 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useCounterStore = defineStore('counter', () => {
|
||||
const count = ref(0)
|
||||
const doubleCount = computed(() => count.value * 2)
|
||||
function increment() {
|
||||
count.value++
|
||||
}
|
||||
|
||||
return { count, doubleCount, increment }
|
||||
})
|
||||
87
src/views/commodity-detail/components/address-form.vue
Normal file
87
src/views/commodity-detail/components/address-form.vue
Normal file
@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<van-popup id="address-form" class="flex flex-col" v-model:show="model" closeable round>
|
||||
<h3 class="text-center pt-5 text-base">{{ `${isEdit ? '修改' : '新增'}收货地址` }}</h3>
|
||||
<div class="pt-3 flex-1 overflow-y-scroll">
|
||||
<van-form @submit="onSubmit">
|
||||
<van-cell-group inset>
|
||||
<van-field v-model="formData.name" label="名字" placeholder="请输入收货人名称" :rules="[{ required: true, message: '请输入收货人名称' }]" />
|
||||
<van-field v-model="formData.mobile" label="手机号" placeholder="请输入收货人手机号" :rules="[{ required: true, message: '请输入收货人手机号' }]" />
|
||||
<van-field v-model="formData.area" is-link readonly name="area" label="地区选择" placeholder="点击选择省市区" @click="areaData.show = true" />
|
||||
<van-field v-model="formData.addressDetail" rows="3" autosize label="详细地址" type="textarea" placeholder="请输入详细地址" :rules="[{ required: true, message: '请输入详细地址' }]" />
|
||||
<van-field name="checkboxGroup" label="" class="py-1!">
|
||||
<template #input>
|
||||
<van-checkbox-group v-model="formData.default" direction="horizontal">
|
||||
<van-checkbox :name="1" shape="square" class="text-xs">默认地址</van-checkbox>
|
||||
</van-checkbox-group>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
<div class="bg-white w-full h-12 p-2 box-border">
|
||||
<button class="block w-full h-full border-none theme-bg-color color-white rounded-[.04rem]" native-type="submit">确定</button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</van-popup>
|
||||
<van-popup v-model:show="areaData.show" destroy-on-close position="bottom">
|
||||
<van-area :area-list="areaList" :model-value="areaData.pickerValue" @confirm="onSelectArea" @cancel="areaData.show = false" />
|
||||
</van-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { areaList } from '@vant/area-data'
|
||||
const model = defineModel<boolean>()
|
||||
defineProps<{ isEdit: boolean }>()
|
||||
const formData = reactive({ name: '', mobile: '', area: '', addressDetail: '', province: '', city: '', region: '', default: [] })
|
||||
|
||||
const areaData = reactive({ show: false, pickerValue: '' })
|
||||
|
||||
const onSelectArea = ({ selectedValues, selectedOptions }: { selectedOptions: any; selectedValues: any }) => {
|
||||
areaData.pickerValue = selectedValues.length ? selectedValues[selectedValues.length - 1] : ''
|
||||
areaData.show = false
|
||||
formData.area = selectedOptions.map((item: any) => item.text).join(' ')
|
||||
}
|
||||
|
||||
const onSubmit = () => {
|
||||
model.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
#address-form {
|
||||
&.van-popup--bottom.van-popup--round {
|
||||
border-radius: 0.12rem 0.12rem 0 0;
|
||||
:deep(.van-popup__close-icon) {
|
||||
top: 0.1rem;
|
||||
font-size: 0.2rem;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
.van-cell-group--inset {
|
||||
margin: 0 0.12rem;
|
||||
}
|
||||
:deep(.van-cell) {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
.van-checkbox__icon {
|
||||
height: auto;
|
||||
}
|
||||
.van-checkbox__icon .van-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 0.04rem;
|
||||
}
|
||||
.van-checkbox__label {
|
||||
margin-left: 0.04rem !important;
|
||||
}
|
||||
.van-cell__title {
|
||||
// width: 0;
|
||||
}
|
||||
.van-cell__value {
|
||||
// flex: none;
|
||||
}
|
||||
.van-checkbox__label {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
77
src/views/commodity-detail/components/address-list.vue
Normal file
77
src/views/commodity-detail/components/address-list.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<van-popup id="address-list" class="flex flex-col" v-model:show="model" position="bottom" :style="{ height: '70%' }" closeable round>
|
||||
<h3 class="text-center pt-3 text-base">收货地址管理</h3>
|
||||
<h4 class="flex justify-between items-center px-4 py-4 text-sm font-bold">
|
||||
<span>常用地址</span>
|
||||
<p>
|
||||
<b @click="isManage = !isManage" class="font-bold">{{ !isManage ? '管理' : '退出管理' }}</b
|
||||
><b class="ml-3 theme-color font-bold" @click="showAddAddressFormDialog = true">新增地址</b>
|
||||
</p>
|
||||
</h4>
|
||||
<div class="flex-1 overflow-y-scroll">
|
||||
<van-cell-group class="address-list__container">
|
||||
<van-cell :class="['address-list__item']" v-for="item in addressList" :key="item.id">
|
||||
<template #title>
|
||||
<div class="item__info">
|
||||
<h6 class="text-[.1rem]">浙江省 杭州市 萧山区 宁围街道</h6>
|
||||
<p class="item__info__detail">湘湖路与事假达到交叉口 新希望宁问哦小区2幢2单元202</p>
|
||||
<p class="item__info__subtitle">张丹 15100001111</p>
|
||||
</div>
|
||||
</template>
|
||||
<template #value>
|
||||
<div class="item__editor text-base">
|
||||
<van-icon v-if="!isManage" name="edit" color="#999" @click="onEditAddress" />
|
||||
<van-icon v-else name="delete-o" />
|
||||
</div>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<div class="bg-white w-full h-12 p-2 box-border">
|
||||
<button class="block w-full h-full border-none bg-red color-white rounded-[.04rem]">确定</button>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const model = defineModel<boolean>()
|
||||
const addressFormType = defineModel<'add' | 'edit'>('addressFormType')
|
||||
const showAddAddressFormDialog = defineModel<boolean>('showAddAddressFormDialog')
|
||||
const addressList = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 5 }]
|
||||
|
||||
const isManage = ref(false)
|
||||
|
||||
const onEditAddress = () => {
|
||||
showAddAddressFormDialog.value = true
|
||||
addressFormType.value = 'edit'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
#address-list {
|
||||
&.van-popup--bottom.van-popup--round {
|
||||
border-radius: 0.12rem 0.12rem 0 0;
|
||||
:deep(.van-popup__close-icon) {
|
||||
top: 0.1rem;
|
||||
font-size: 0.2rem;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
:deep(.van-cell) {
|
||||
.van-cell__title {
|
||||
width: 0;
|
||||
}
|
||||
.item__info__detail {
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.van-cell__value {
|
||||
flex: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
59
src/views/commodity-detail/components/all-review.vue
Normal file
59
src/views/commodity-detail/components/all-review.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<van-popup id="all-review" class="flex flex-col" v-model:show="model" position="bottom" :style="{ height: '90%' }" closeable round>
|
||||
<h3 class="text-center pt-3 text-base">评价</h3>
|
||||
<ul class="flex all-review__tab">
|
||||
<li :class="['all-review__tab-li', { active: item.active }]" v-for="item in tabs" :key="item.value">{{ item.name }}</li>
|
||||
</ul>
|
||||
<ul class="all-review__contain flex-1 overflow-y-scroll">
|
||||
<li class="p-3" v-for="item in reviews" :key="item.id">
|
||||
<review-single />
|
||||
</li>
|
||||
</ul>
|
||||
</van-popup>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import reviewSingle from './review-single.vue'
|
||||
|
||||
const model = defineModel<boolean>()
|
||||
const tabs = [
|
||||
{ name: '全部', value: 0, active: true },
|
||||
{ name: '最新评价', value: 3, active: false },
|
||||
{ name: '5/4星好评', value: 1, active: false },
|
||||
{ name: '图/视频', value: 2, active: false },
|
||||
]
|
||||
const reviews = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 5 }]
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
#all-review {
|
||||
&.van-popup--bottom.van-popup--round {
|
||||
border-radius: 0.12rem 0.12rem 0 0;
|
||||
:deep(.van-popup__close-icon) {
|
||||
top: 0.1rem;
|
||||
font-size: 0.2rem;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
.all-review__tab {
|
||||
gap: 0.08rem;
|
||||
flex-wrap: wrap;
|
||||
padding: 0.12rem;
|
||||
.all-review__tab-li {
|
||||
padding: 0.08rem 0.12rem;
|
||||
background: #f2f5f9;
|
||||
border-radius: 0.04rem;
|
||||
&.active {
|
||||
background: #fdf0e4;
|
||||
color: #f3802e;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
.all-review__contain {
|
||||
li + li {
|
||||
border-top: 6px solid #f1f5f8;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div id="review-single">
|
||||
<h3 class="flex items-center ml-2 text-sm">
|
||||
<img class="w-8 h-8 rounded-full" src="" alt="">
|
||||
<h3 class="flex items-center text-sm">
|
||||
<img class="w-8 h-8 rounded-full" src="" alt="" />
|
||||
<div class="ml-1">
|
||||
<p class="">饭**子</p>
|
||||
<p class="mt-0.5 text-xs color-[#666]">2025.08.23</p>
|
||||
</div>
|
||||
</h3>
|
||||
<div class="review-content mt-3">
|
||||
<p class="pl-2">公司大丰收东方闪电防守打法四大分三大胜多负少的</p>
|
||||
<p>公司大丰收东方闪电防守打法四大分三大胜多负少的</p>
|
||||
<p class="flex items-center mt-2">
|
||||
<img class="w-16 h-16 mr-1 rounded-[4px]" src="" alt="" v-for="(item, index) in list" :key="index" />
|
||||
</p>
|
||||
@ -17,9 +17,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const list = ref(['',''])
|
||||
const list = ref(['', ''])
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
<style></style>
|
||||
|
||||
@ -1,73 +1,87 @@
|
||||
<template>
|
||||
<div id="shopping-cart" class="p-2 relative">
|
||||
<div class="mb-8">
|
||||
<div class="cart-wrap">
|
||||
<p class="flex justify-between"><span class="max-w-12 mr-1">张四</span> <b class="font- flex-1">我的详细地址是什么东西的地方的好的么</b></p>
|
||||
</div>
|
||||
<div class="cart-wrap mt-2">
|
||||
<div class="flex">
|
||||
<img class="w-16 h-16 mr-4" style="border-radius: .04rem" src="" alt="">
|
||||
<p>¥<span>29.9</span></p>
|
||||
<van-popup id="shopping-cart" v-model:show="model" position="bottom" :style="{ height: '70%' }" closeable round>
|
||||
<van-notice-bar class="text-xs! h-8!" left-icon="volume-o" text="平台保证 | 假一赔四·极速退款" />
|
||||
<div class="p-2 bg-[#f5f5f5]">
|
||||
<div class="mb-8">
|
||||
<div class="cart-wrap">
|
||||
<p class="flex justify-between" @click="showAddressList = true">
|
||||
<van-icon name="location-o" class="mr-1" /><span class="max-w-12 mr-1">张四</span> <b class="font- flex-1">我的详细地址是什么东西的地方的好的么</b><van-icon name="arrow" />
|
||||
</p>
|
||||
</div>
|
||||
<div class="cart-cagetory-wrap">
|
||||
<h4>更多系列</h4>
|
||||
<div class="cagetory">
|
||||
<p>手表系列</p>
|
||||
<p>手表系列水</p>
|
||||
<p>手表</p>
|
||||
<p>手表123</p>
|
||||
<p>手表12</p>
|
||||
<div class="cart-wrap mt-2">
|
||||
<div class="flex">
|
||||
<img class="w-16 h-16 mr-4" style="border-radius: 0.04rem" src="" alt="" />
|
||||
<p>¥<span>29.9</span></p>
|
||||
</div>
|
||||
<h4>颜色</h4>
|
||||
<div class="cagetory">
|
||||
<p>手表系列</p>
|
||||
<p>手表系列水</p>
|
||||
<p>手表</p>
|
||||
<p>手表123</p>
|
||||
<p>手表12</p>
|
||||
<div class="cart-cagetory-wrap">
|
||||
<h4>更多系列</h4>
|
||||
<div class="cagetory">
|
||||
<p>手表系列</p>
|
||||
<p>手表系列水</p>
|
||||
<p>手表</p>
|
||||
<p>手表123</p>
|
||||
<p>手表12</p>
|
||||
</div>
|
||||
<h4>颜色</h4>
|
||||
<div class="cagetory">
|
||||
<p>手表系列</p>
|
||||
<p>手表系列水</p>
|
||||
<p>手表</p>
|
||||
<p>手表123</p>
|
||||
<p>手表12</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixed bg-white w-full h-12 left-0 bottom-0 p-2 box-border">
|
||||
<button class="block w-full h-full border-none theme-bg-color color-white rounded-[.04rem]">确定</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute w-full h-8 left-0 bottom-0 px-2 box-border">
|
||||
<button class="block w-full h-full border-none bg-red color-white rounded-[.04rem]">确定</button>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
const model = defineModel<boolean>()
|
||||
const showAddressList = defineModel<boolean>('showAddressList')
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#shopping-cart{
|
||||
.cart-wrap{
|
||||
padding: .12rem .08rem;
|
||||
#shopping-cart {
|
||||
.cart-wrap {
|
||||
padding: 0.12rem 0.08rem;
|
||||
background: #fff;
|
||||
border-radius: .04rem;
|
||||
border-radius: 0.04rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
.cart-cagetory-wrap{
|
||||
h4{
|
||||
.cart-cagetory-wrap {
|
||||
h4 {
|
||||
font-weight: bold;
|
||||
margin-top: .16rem;
|
||||
margin-bottom: .12rem;
|
||||
margin-top: 0.16rem;
|
||||
margin-bottom: 0.12rem;
|
||||
}
|
||||
.cagetory {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
& >p{
|
||||
flex-shrink: 0;
|
||||
height: .28rem;
|
||||
line-height: .28rem;
|
||||
& > p {
|
||||
flex-shrink: 0;
|
||||
height: 0.28rem;
|
||||
line-height: 0.28rem;
|
||||
background: #f2f2f2;
|
||||
padding: 0 .2rem;
|
||||
padding: 0 0.2rem;
|
||||
color: #666;
|
||||
border-radius: .04rem;
|
||||
margin-right: .08rem;
|
||||
margin-bottom: .08rem;
|
||||
border-radius: 0.04rem;
|
||||
margin-right: 0.08rem;
|
||||
margin-bottom: 0.08rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.van-popup--bottom.van-popup--round {
|
||||
border-radius: 0.08rem 0.08rem 0 0;
|
||||
:deep(.van-popup__close-icon) {
|
||||
top: 0.06rem;
|
||||
font-size: 0.2rem;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
<template>
|
||||
<div id="commodity-detail">
|
||||
<header class="h-70 bg-black">
|
||||
轮播图
|
||||
</header>
|
||||
<header class="h-70 bg-[#aaa]"></header>
|
||||
<main>
|
||||
<div class="detail-info wrap">
|
||||
<h2 class="text-2xl color-[#000]">陕西珍珠首饰项链</h2>
|
||||
@ -13,7 +11,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div class="review-info wrap">
|
||||
<h3 class="wrap-title"><b>用户评价(45.6万+)</b><span>全部评价</span></h3>
|
||||
<h3 class="wrap-title"><b>用户评价(45.6万+)</b><span @click="onShowAllReview">全部评价 ></span></h3>
|
||||
<div class="mt-5">
|
||||
<review-single />
|
||||
</div>
|
||||
@ -32,107 +30,127 @@
|
||||
<instruction-info class="mt3" />
|
||||
</div>
|
||||
</main>
|
||||
<shopping-cart class="mb-10"></shopping-cart>
|
||||
<footer class="flex fixed bottom-0 left-0 w-full h-10 justify-between items-center pr-2 box-border bg-white">
|
||||
<div class="flex items-center w-[1.6rem] justify-around">
|
||||
<div class="flex items-center w-[1.4rem] justify-around">
|
||||
<p class="icon-wrap">
|
||||
<img src="" alt="">
|
||||
<span>首页</span>
|
||||
</p>
|
||||
<p class="icon-wrap">
|
||||
<img src="" alt="">
|
||||
<van-icon name="phone-o" size=".14rem" />
|
||||
<span>客服</span>
|
||||
</p>
|
||||
<p class="icon-wrap">
|
||||
<img src="" alt="">
|
||||
<van-icon name="like-o" size=".14rem" />
|
||||
<span>收藏</span>
|
||||
</p>
|
||||
<p class="icon-wrap">
|
||||
<van-icon name="shopping-cart-o" size=".14rem" />
|
||||
<span>购物车</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex-1 button-wrap">
|
||||
|
||||
<button class="bg-orange">加入购物车</button>
|
||||
<button class="bg-red color-white">立即购买</button>
|
||||
<button class="bg-orange text-white w-30!">加入购物车</button>
|
||||
<button class="theme-bg-color color-white" @click="onPayNowBtn">立即购买</button>
|
||||
</div>
|
||||
</footer>
|
||||
<shopping-cart v-model="showShopCart" v-model:showAddressList="showAddressList"></shopping-cart>
|
||||
<all-review v-model="showAllReview"></all-review>
|
||||
<address-list v-model="showAddressList" v-model:showAddAddressFormDialog="showAddAddressFormDialog" v-model:addressFormType="addressFormType"></address-list>
|
||||
<address-form v-model="showAddAddressFormDialog" :isEdit="addressFormType === 'edit'"></address-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import allReview from './components/all-review.vue'
|
||||
import reviewSingle from './components/review-single.vue'
|
||||
import infoTable from './components/info-table.vue'
|
||||
import instructionInfo from './components/instruction-info.vue'
|
||||
import shoppingCart from './components/shopping-cart.vue'
|
||||
import addressList from './components/address-list.vue'
|
||||
import addressForm from './components/address-form.vue'
|
||||
|
||||
const showShopCart = ref(false) // 展示购物车
|
||||
const showAllReview = ref(false) // 展示全部评价
|
||||
const showAddressList = ref(false) // 展示收货地址列表
|
||||
const showAddAddressFormDialog = ref(false) // 展示收货地址form
|
||||
const addressFormType = ref<'add' | 'edit'>('add')
|
||||
// 查看全部评价
|
||||
const onShowAllReview = () => {
|
||||
showAllReview.value = true
|
||||
}
|
||||
// 点击立即购买按钮
|
||||
const onPayNowBtn = () => {
|
||||
showShopCart.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scope lang="scss">
|
||||
#commodity-detail{
|
||||
#commodity-detail {
|
||||
background: #f2f2f2;
|
||||
.wrap{
|
||||
margin: .08rem .12rem;
|
||||
border-radius: .12rem;
|
||||
padding: .16rem;
|
||||
.wrap {
|
||||
margin: 0.08rem 0.12rem;
|
||||
border-radius: 0.12rem;
|
||||
padding: 0.16rem;
|
||||
background: #fff;
|
||||
.wrap-title{
|
||||
.wrap-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
b{
|
||||
font-size: .16rem;
|
||||
b {
|
||||
font-size: 0.16rem;
|
||||
color: #000;
|
||||
}
|
||||
span{
|
||||
font-size: .12rem;
|
||||
span {
|
||||
font-size: 0.12rem;
|
||||
color: #777;
|
||||
}
|
||||
}
|
||||
}
|
||||
.detail-info{
|
||||
li{
|
||||
margin-top: .12rem;
|
||||
span{
|
||||
margin-right: .1rem;
|
||||
.detail-info {
|
||||
li {
|
||||
margin-top: 0.12rem;
|
||||
span {
|
||||
margin-right: 0.1rem;
|
||||
color: #888;
|
||||
}
|
||||
em{
|
||||
em {
|
||||
color: #000;
|
||||
font-style: normal;
|
||||
}
|
||||
button{
|
||||
button {
|
||||
border: 1px solid #aaa;
|
||||
border-radius: .02rem;
|
||||
border-radius: 0.02rem;
|
||||
background: #fff;
|
||||
padding: .02rem .04rem;
|
||||
padding: 0.02rem 0.04rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
footer{
|
||||
.icon-wrap{
|
||||
footer {
|
||||
.icon-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
img{
|
||||
width: .1rem;
|
||||
height: .1rem;
|
||||
align-items: center;
|
||||
.van-icon {
|
||||
width: 0.14rem;
|
||||
height: 0.16rem;
|
||||
}
|
||||
span{
|
||||
font-size: .11rem;
|
||||
span {
|
||||
font-size: 0.11rem;
|
||||
}
|
||||
}
|
||||
.button-wrap{
|
||||
.button-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: .04rem;
|
||||
border-radius: 0.04rem;
|
||||
overflow: hidden;
|
||||
height: .32rem;
|
||||
button{
|
||||
height: 0.32rem;
|
||||
button {
|
||||
display: block;
|
||||
height: 100% !important;
|
||||
width: 50%;
|
||||
font-size: .14rem;
|
||||
font-size: 0.14rem;
|
||||
border: none;
|
||||
height: .28rem;
|
||||
height: 0.28rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
25
src/views/demo/index.vue
Normal file
25
src/views/demo/index.vue
Normal file
@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div>
|
||||
<van-cell-group>
|
||||
<van-cell v-for="item in list" :title="item.title" :value="item.path" :key="item.path" @click="onClick(item)" is-link />
|
||||
</van-cell-group>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const list = [
|
||||
{ title: '搜索结果', path: 'search-container' },
|
||||
{ title: '商品详情', path: 'commodity-detail' },
|
||||
{ title: '我的订单', path: 'order' },
|
||||
{ title: '订单详情', path: 'order/detail' },
|
||||
{ title: '评价中心', path: 'review/center' },
|
||||
{ title: '填写评价', path: 'review/write' },
|
||||
]
|
||||
|
||||
const router = useRouter()
|
||||
const onClick = (item: any) => {
|
||||
router.push({ name: item.path })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
79
src/views/order/detail.vue
Normal file
79
src/views/order/detail.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div id="order-detail" class="bg-[#f5f5f5] p-3 pb-0">
|
||||
<div class="bg-white rounded-[.08rem]">
|
||||
<!-- 下单时间 -->
|
||||
<div class="flex justify-between items-center pt-3 px-3">
|
||||
<p class="text-sm">2025-10-20 20:10:20</p>
|
||||
<p class="text-sm text-[#FB6406]">{{ orderDetail.status }}</p>
|
||||
</div>
|
||||
<div class="px-3 pt-3 flex">
|
||||
<img class="w-20 h-20 round-[0.08rem] bg-[#f5f5f5]" />
|
||||
<div class="flex flex-col justify-between flex-1 w-0 ml-3">
|
||||
<div>
|
||||
<p class="product-name text-[.13rem]">{{ orderDetail.productName }}</p>
|
||||
<p class="text-xs text-[#888] mt-2">{{ orderDetail.spec }}</p>
|
||||
</div>
|
||||
<!-- <p class="text-[.13rem] text-right">
|
||||
<span class="">共{{ orderDetail.num }}件商品</span>
|
||||
<span class="ml-3"
|
||||
>实付款<i class="text-xs">¥</i><b class="text-base ml-1">{{ orderDetail.price }}</b></span
|
||||
>
|
||||
</p> -->
|
||||
</div>
|
||||
</div>
|
||||
<van-cell-group class="mt-3">
|
||||
<van-cell title="实付款" value="700.12" />
|
||||
<van-cell title="订单编号" value="4124324234" />
|
||||
<van-cell title="支付方式" value="在线支付" />
|
||||
<van-cell title="支付时间" value="2025-10-12 12:12:12" />
|
||||
<van-cell title="下单时间" value="2025-10-12 12:12:12" />
|
||||
<van-cell title="收货地址" value="浙江省杭州市萧山区信息港小镇" />
|
||||
</van-cell-group>
|
||||
<van-cell-group class="mt-3">
|
||||
<van-cell title="配送快递" value="申通快递" />
|
||||
<van-cell title="快递状态" value="已发货" />
|
||||
<van-cell title="快递单号" value="sdfsdfsdfs23423423423" />
|
||||
<van-cell title="收货人" value="张三" />
|
||||
<van-cell title="收货联系方式" value="13122223333" />
|
||||
<van-cell title="收货地址" value="浙江省杭州市萧山区信息港小镇" />
|
||||
</van-cell-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const orderDetail = ref({
|
||||
id: 1,
|
||||
storeName: '天猫 得力官方旗舰店',
|
||||
status: '交易成功',
|
||||
productName: '得力纳米胶双面胶高粘度防粘防尘始发地水电费水电费',
|
||||
spec: '[基础款长1米] 粘厚1mm宽24mm(1卷装)',
|
||||
num: 1,
|
||||
price: 4.89,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
#order-detail {
|
||||
.product-name {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
.van-hairline--top-bottom:after {
|
||||
border-bottom: 0;
|
||||
}
|
||||
:deep(.van-cell) {
|
||||
.van-cell__value {
|
||||
color: #333;
|
||||
}
|
||||
.van-cell__title {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.van-cell:after {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
171
src/views/order/index.vue
Normal file
171
src/views/order/index.vue
Normal file
@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<div class="order-page">
|
||||
<!-- 搜索栏 -->
|
||||
<div>
|
||||
<van-search show-action v-model="searchValue" placeholder="搜索订单" @search="onSearch" @cancel="onCancel" />
|
||||
</div>
|
||||
<!-- 标签页 -->
|
||||
<van-tabs>
|
||||
<van-tab v-for="tab in tabs" :key="tab.value" :title="tab.name" :name="tab.value" class="tab-item"> </van-tab>
|
||||
</van-tabs>
|
||||
<!-- 订单列表 -->
|
||||
<div class="order-list bg-[#f5f5f5]">
|
||||
<template v-if="orders.length > 0">
|
||||
<div v-for="order in orders" :key="order.id" class="order-card bg-white round-[0.08rem]">
|
||||
<!-- 下单时间 -->
|
||||
<div class="flex justify-between items-center pt-3 px-3">
|
||||
<p class="text-sm">2025-10-20 20:10:20</p>
|
||||
<p class="text-sm text-[#FB6406]">{{ order.status }}</p>
|
||||
</div>
|
||||
<!-- 商品信息 -->
|
||||
<div class="px-3 pt-3 flex" @click="goDetail(order.id)">
|
||||
<img class="w-20 h-20 round-[0.08rem] bg-[#f5f5f5]" />
|
||||
<div class="flex flex-col justify-between flex-1 w-0 ml-3">
|
||||
<div>
|
||||
<p class="product-name text-[.13rem]">{{ order.productName }}</p>
|
||||
<p class="text-xs text-[#888] mt-2">{{ order.spec }}</p>
|
||||
</div>
|
||||
<p class="text-[.13rem] text-right">
|
||||
<span class="">共{{ order.num }}件商品</span>
|
||||
<span class="ml-3"
|
||||
>实付款<i class="text-xs">¥</i><b class="text-base ml-1">{{ order.price }}</b></span
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 操作区域 -->
|
||||
<div class="order-footer flex items-center justify-between p-3">
|
||||
<van-popover class="order-page__popover" v-model:show="showPopover" placement="top-start" :actions="actions" @select="onSelect">
|
||||
<template #reference>
|
||||
<span class="text-[#666]">更多</span>
|
||||
</template>
|
||||
</van-popover>
|
||||
<div class="flex items-center">
|
||||
<van-button size="small" class="h-7!" @click="handleAddToCart(order.id)">加入购物车</van-button>
|
||||
<van-button size="small" type="warning" class="ml-2! h-7! theme-bg-color theme-border-color" @click="handleBuyAgain(order.id)">再买一单</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="empty-state">
|
||||
<div class="empty-icon">
|
||||
<van-icon name="orders-o" size="48" />
|
||||
</div>
|
||||
<div>暂无订单</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { showToast } from 'vant'
|
||||
|
||||
const searchValue = ref('')
|
||||
|
||||
// 响应式数据
|
||||
const activeTab = ref(0)
|
||||
const showActionMenu = ref(false)
|
||||
const orders = ref([
|
||||
{
|
||||
id: 1,
|
||||
storeName: '天猫 得力官方旗舰店',
|
||||
status: '交易成功',
|
||||
productName: '得力纳米胶双面胶高粘度防粘防尘始发地水电费水电费',
|
||||
spec: '[基础款长1米] 粘厚1mm宽24mm(1卷装)',
|
||||
num: 1,
|
||||
price: 4.89,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
storeName: '天猫 得力官方旗舰店',
|
||||
status: '交易成功',
|
||||
productName: '得力纳米胶双面胶高粘度防粘防尘始发地水电费水电费',
|
||||
spec: '[基础款长1米] 粘厚1mm宽24mm(1卷装)',
|
||||
num: 2,
|
||||
price: 4.89,
|
||||
},
|
||||
])
|
||||
|
||||
const tabs = reactive([
|
||||
{ name: '全部', value: 0 },
|
||||
{ name: '待付款', value: 1 },
|
||||
{ name: '待发货', value: 2 },
|
||||
{ name: '已发货', value: 3 },
|
||||
{ name: '退款', value: 4 },
|
||||
])
|
||||
|
||||
const onSearch = () => {}
|
||||
const onCancel = () => {}
|
||||
|
||||
const usePopover = () => {
|
||||
const showPopover = ref(false)
|
||||
const actions = [
|
||||
{ text: '取消订单', value: 'cancel' },
|
||||
{ text: '删除订单', value: 'delete' },
|
||||
]
|
||||
const onSelect = () => {}
|
||||
return {
|
||||
showPopover,
|
||||
actions,
|
||||
onSelect,
|
||||
}
|
||||
}
|
||||
const { showPopover, actions, onSelect } = usePopover()
|
||||
|
||||
// 方法
|
||||
const handleBuyAgain = (orderId) => {
|
||||
router.push({ name: 'commodity-detail', query: { id: orderId } })
|
||||
}
|
||||
|
||||
const handleAddToCart = (orderId) => {}
|
||||
const router = useRouter()
|
||||
const goDetail = (id: number) => {
|
||||
router.push({ path: '/order/detail', query: { id } })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.order-page {
|
||||
min-height: 100vh;
|
||||
:deep(.van-tabs) {
|
||||
&.van-tabs--line .van-tabs__wrap {
|
||||
height: 0.3rem;
|
||||
}
|
||||
}
|
||||
.order-card {
|
||||
& + .order-card {
|
||||
margin-top: 0.12rem;
|
||||
}
|
||||
}
|
||||
.product-name {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: var(--text-color-light);
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 16px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
.order-page__popover {
|
||||
:deep(.van-popover__content) {
|
||||
.van-popover__action {
|
||||
width: 0.8rem;
|
||||
height: 0.3rem;
|
||||
line-height: 0.3rem;
|
||||
}
|
||||
.van-popover__action-text {
|
||||
font-size: 0.12rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
64
src/views/review/center.vue
Normal file
64
src/views/review/center.vue
Normal file
@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div id="review-center" class="bg-[#FFF3CD] min-h-screen flex flex-col">
|
||||
<header class="flex items-center p-5">
|
||||
<img class="w-10 h-10 rounded-full bg-black" src="" alt="" style="border: 2px solid #fff" />
|
||||
<p class="ml-2">用户名</p>
|
||||
</header>
|
||||
<ul class="flex items-center justify-center mx-3 rounded-[.08rem] bg-white">
|
||||
<li v-for="item in nums" :key="item.name" class="flex-1 text-center py-4">
|
||||
<p class="text-lg font-bold">{{ item.num }}</p>
|
||||
<p class="mt-1 text-[#d1ac35]">{{ item.name }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
<main class="flex-1 rounded-[.1rem] overflow-scroll bg-white mt-3">
|
||||
<van-tabs v-model:active="tabActive" sticky>
|
||||
<van-tab title="待评价" name="0"></van-tab>
|
||||
<van-tab title="已评价" name="1"></van-tab>
|
||||
</van-tabs>
|
||||
<ul>
|
||||
<li v-for="item in reviews" :key="item.id" class="flex items-center p-2 relative">
|
||||
<img class="w-16 h-16" src="" alt="" />
|
||||
<div class="ml-2 h-16 flex flex-col justify-between">
|
||||
<p class="">{{ item.name }}</p>
|
||||
<div class="flex items-center">
|
||||
<p class="text-xs text-[#666]">一键评分</p>
|
||||
<van-rate v-model="item.rate" allow-half size=".12rem" />
|
||||
</div>
|
||||
</div>
|
||||
<van-button size="small" class="absolute! bottom-2 right-2 w-[.54rem]! h-[.26rem]! theme-color theme-disabled-color font-bold" color="#F4E1E8" @click="onGoReview(item.id)"
|
||||
>去评价</van-button
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const tabActive = ref('0')
|
||||
const reviews = ref([
|
||||
{ id: 1, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂', rate: 0 },
|
||||
{ id: 2, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂', rate: 0 },
|
||||
{ id: 3, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂', rate: 0 },
|
||||
{ id: 1, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂', rate: 0 },
|
||||
{ id: 2, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂', rate: 0 },
|
||||
{ id: 3, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂', rate: 0 },
|
||||
{ id: 1, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂', rate: 0 },
|
||||
{ id: 2, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂', rate: 0 },
|
||||
{ id: 3, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂', rate: 0 },
|
||||
])
|
||||
const nums = ref([
|
||||
{ name: '全部', num: 0 },
|
||||
{ name: '已评价', num: 0 },
|
||||
{ name: '待评价', num: 0 },
|
||||
])
|
||||
const router = useRouter()
|
||||
const onGoReview = (id: number) => {
|
||||
router.push({ name: 'review/write', query: { id } })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
#review-center {
|
||||
}
|
||||
</style>
|
||||
46
src/views/review/write.vue
Normal file
46
src/views/review/write.vue
Normal file
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div id="review-write" class="bg-[#f5f5f5] min-h-screen">
|
||||
<h3 class="pl-3 py-3 text-[#666]">您的评价将帮助其他用户</h3>
|
||||
<van-cell-group>
|
||||
<van-cell v-for="item in stars" :title="item.name" :key="item.name">
|
||||
<template #value>
|
||||
<div class="flex items-center justify-end">
|
||||
<p class="text-xs">{{ item.starMap }}</p>
|
||||
<van-rate class="ml-2" v-model="item.value" allow-half size=".16rem" @change="onChangeStar(item, item.value)" />
|
||||
</div>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-field class="mt-2" left-icon="edit" v-model="message" rows="3" autosize label="" type="textarea" maxlength="200" placeholder="请输入文字" show-word-limit />
|
||||
<div class="bg-white pl-3">
|
||||
<van-uploader v-model="fileList" multiple />
|
||||
</div>
|
||||
<footer class="mx-3 mt-3">
|
||||
<van-button type="primary" size="large" class="h-10! text-sm! theme-bg-color theme-border-color">发布</van-button>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const stars = reactive([
|
||||
{ name: '商品评价', value: 0, starMap: '' },
|
||||
{ name: '快递包装', value: 0, starMap: '' },
|
||||
{ name: '发货速度', value: 0, starMap: '' },
|
||||
{ name: '售后服务', value: 0, starMap: '' },
|
||||
])
|
||||
|
||||
const onChangeStar = (item: any, v: any) => {
|
||||
if (v >= 4.5) item.starMap = '非常好'
|
||||
else if (v >= 3) item.starMap = '挺好'
|
||||
else if (v >= 2) item.starMap = '一般'
|
||||
else item.starMap = '差'
|
||||
}
|
||||
|
||||
const message = ref('')
|
||||
const fileList = ref([])
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
#review-write {
|
||||
}
|
||||
</style>
|
||||
84
src/views/search-container/index.vue
Normal file
84
src/views/search-container/index.vue
Normal file
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<div id="search-container" class="h-screen bg-[#f2f2f2] flex flex-col">
|
||||
<header class="search-header flex items-center p-2">
|
||||
<van-search class="flex-1 p-0!" background="#f2f2f2" v-model="searchValue" placeholder="请输入搜索关键词" />
|
||||
<van-icon name="shopping-cart-o" size=".2rem" class="ml-2" />
|
||||
</header>
|
||||
<van-tabs v-model:active="searchSort" sticky :color="appStore.themeColor">
|
||||
<van-tab title="综合" name="0"></van-tab>
|
||||
<van-tab title="销量" name="1"></van-tab>
|
||||
<van-tab title="价格" name="2"></van-tab>
|
||||
</van-tabs>
|
||||
<ul class="search-condition bg-white pt-2 flex-1 overflow-y-scroll">
|
||||
<li v-for="item in searchList" :key="item.id" class="flex item-center p-2 relative" @click="onGoDetail(item.id)">
|
||||
<img src="" alt="" class="w-24 h-24" />
|
||||
<div class="ml-2">
|
||||
<h4 class="text-[.13rem]">{{ item.name }}</h4>
|
||||
<p class="text-[#888] mt-1">新鲜优质 | 酸甜多汁 | 足斤足两</p>
|
||||
<p class="mt-1">
|
||||
<van-tag plain type="primary" color="#ec4d3c">标签1</van-tag>
|
||||
<van-tag plain type="primary" color="#ec4d3c">标签2</van-tag>
|
||||
<van-tag plain type="primary" color="#ec4d3c">标签3</van-tag>
|
||||
</p>
|
||||
<p class="mt-3">
|
||||
<span class="text-[#e71e1e] font-bold">¥<b class="font-bold text-base ml-0.5">0</b>.01</span>
|
||||
</p>
|
||||
</div>
|
||||
<van-icon name="add" :color="appStore.themeColor" size=".2rem" class="absolute! right-3 bottom-6 h-5" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAppStore } from '@/stores/app.ts'
|
||||
const searchValue = ref('')
|
||||
const searchSort = ref('0')
|
||||
const searchList = ref([
|
||||
{ id: 1, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂' },
|
||||
{ id: 2, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂' },
|
||||
{ id: 3, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂' },
|
||||
{ id: 1, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂' },
|
||||
{ id: 2, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂' },
|
||||
{ id: 3, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂' },
|
||||
{ id: 1, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂' },
|
||||
{ id: 2, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂' },
|
||||
{ id: 3, name: '新疆大柚子水电费水电费水电费手动阀是是否神鼎飞丹砂' },
|
||||
])
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
||||
const router = useRouter()
|
||||
const onGoDetail = (id: number) => {
|
||||
router.push({ name: 'commodity-detail', query: { id } })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
#search-container {
|
||||
.search-header {
|
||||
:deep(.van-search) {
|
||||
.van-search__content {
|
||||
border-radius: 0.16rem;
|
||||
background: #fff;
|
||||
.van-field__body {
|
||||
padding-right: 0.06rem;
|
||||
}
|
||||
.van-cell {
|
||||
height: 0.3rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.van-tabs) {
|
||||
.van-tabs__wrap {
|
||||
height: 0.32rem;
|
||||
}
|
||||
}
|
||||
:deep(.van-tag) {
|
||||
font-size: 0.1rem;
|
||||
margin-right: 0.04rem;
|
||||
border-color: #ddd !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -4,6 +4,8 @@ import UnoCSS from 'unocss/vite'
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import { VantResolver } from '@vant/auto-import-resolver'
|
||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
|
||||
// https://vite.dev/config/
|
||||
@ -11,18 +13,30 @@ export default defineConfig({
|
||||
plugins: [
|
||||
UnoCSS(),
|
||||
vue(),
|
||||
vueDevTools(),
|
||||
// vueDevTools(),
|
||||
AutoImport({
|
||||
imports: [
|
||||
'vue',
|
||||
'vue-router',
|
||||
],
|
||||
dts: 'src/auto-import.d.ts'
|
||||
resolvers: [VantResolver()],
|
||||
imports: ['vue', 'vue-router'],
|
||||
dts: 'src/auto-import.d.ts',
|
||||
}),
|
||||
Components({
|
||||
resolvers: [VantResolver()],
|
||||
}),
|
||||
],
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: 3000,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||
},
|
||||
},
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: `@use "@/assets/variables.scss" as *;`,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
60
yarn.lock
60
yarn.lock
@ -1133,6 +1133,16 @@
|
||||
tinyglobby "^0.2.14"
|
||||
unplugin-utils "^0.2.4"
|
||||
|
||||
"@vant/area-data@^2.1.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmmirror.com/@vant/area-data/-/area-data-2.1.0.tgz#77dc6b3ddde18dc25ee8bfd9431b2c67f37233cd"
|
||||
integrity sha512-wx9PrUX7wSUJiFcz8UrcvZfTjV6sTc+7SHcbjGQQzEcv5y+EwOo5uV4ZKdfrR5Hzcw4MA08LQdvXPSEb4nWbug==
|
||||
|
||||
"@vant/auto-import-resolver@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.npmmirror.com/@vant/auto-import-resolver/-/auto-import-resolver-1.3.0.tgz#d9ab270edb641e9ab5d7c5841c2d721bd52c4133"
|
||||
integrity sha512-lJyWtCyFizR4bHZvMiNMF3w+WTFTUWAvka1eqTnPK9ticUcKTCOx6qEmHcm8JPb3g1t3GaD2W3MnHkBp/nHamw==
|
||||
|
||||
"@vant/popperjs@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz#e0eff017124b5b2352ef3b36a6df06277f4400f2"
|
||||
@ -1682,6 +1692,13 @@ debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0, debug@^4.4
|
||||
dependencies:
|
||||
ms "^2.1.3"
|
||||
|
||||
debug@^4.4.3:
|
||||
version "4.4.3"
|
||||
resolved "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
|
||||
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
|
||||
dependencies:
|
||||
ms "^2.1.3"
|
||||
|
||||
deep-is@^0.1.3:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||
@ -2386,7 +2403,7 @@ levn@^0.4.1:
|
||||
prelude-ls "^1.2.1"
|
||||
type-check "~0.4.0"
|
||||
|
||||
local-pkg@^1.1.1:
|
||||
local-pkg@^1.1.1, local-pkg@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmmirror.com/local-pkg/-/local-pkg-1.1.2.tgz#c03d208787126445303f8161619dc701afa4abb5"
|
||||
integrity sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==
|
||||
@ -2435,6 +2452,13 @@ magic-string@^0.30.17, magic-string@^0.30.4:
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.5.5"
|
||||
|
||||
magic-string@^0.30.19:
|
||||
version "0.30.19"
|
||||
resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.19.tgz#cebe9f104e565602e5d2098c5f2e79a77cc86da9"
|
||||
integrity sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.5.5"
|
||||
|
||||
math-intrinsics@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
|
||||
@ -2494,7 +2518,7 @@ mitt@^3.0.1:
|
||||
resolved "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1"
|
||||
integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==
|
||||
|
||||
mlly@^1.7.4:
|
||||
mlly@^1.7.4, mlly@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.npmmirror.com/mlly/-/mlly-1.8.0.tgz#e074612b938af8eba1eaf43299cbc89cb72d824e"
|
||||
integrity sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==
|
||||
@ -3026,6 +3050,14 @@ tinyglobby@^0.2.14:
|
||||
fdir "^6.4.4"
|
||||
picomatch "^4.0.2"
|
||||
|
||||
tinyglobby@^0.2.15:
|
||||
version "0.2.15"
|
||||
resolved "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2"
|
||||
integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==
|
||||
dependencies:
|
||||
fdir "^6.5.0"
|
||||
picomatch "^4.0.3"
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
@ -3163,6 +3195,30 @@ unplugin-utils@^0.3.0:
|
||||
pathe "^2.0.3"
|
||||
picomatch "^4.0.3"
|
||||
|
||||
unplugin-vue-components@^29.1.0:
|
||||
version "29.1.0"
|
||||
resolved "https://registry.npmmirror.com/unplugin-vue-components/-/unplugin-vue-components-29.1.0.tgz#6064dfd43ebfc2d54fc04d6c391d30c9f66d3360"
|
||||
integrity sha512-z/9ACPXth199s9aCTCdKZAhe5QGOpvzJYP+Hkd0GN1/PpAmsu+W3UlRY3BJAewPqQxh5xi56+Og6mfiCV1Jzpg==
|
||||
dependencies:
|
||||
chokidar "^3.6.0"
|
||||
debug "^4.4.3"
|
||||
local-pkg "^1.1.2"
|
||||
magic-string "^0.30.19"
|
||||
mlly "^1.8.0"
|
||||
tinyglobby "^0.2.15"
|
||||
unplugin "^2.3.10"
|
||||
unplugin-utils "^0.3.0"
|
||||
|
||||
unplugin@^2.3.10:
|
||||
version "2.3.10"
|
||||
resolved "https://registry.npmmirror.com/unplugin/-/unplugin-2.3.10.tgz#15e75fec9384743335be7e54e5c88b5c187a3e94"
|
||||
integrity sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==
|
||||
dependencies:
|
||||
"@jridgewell/remapping" "^2.3.5"
|
||||
acorn "^8.15.0"
|
||||
picomatch "^4.0.3"
|
||||
webpack-virtual-modules "^0.6.2"
|
||||
|
||||
unplugin@^2.3.5:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.npmmirror.com/unplugin/-/unplugin-2.3.8.tgz#617198a50ec3467f28d03e4096167339747405e6"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user