feat: 添加分页组件和地址选择组件,优化样式和类型定义
refactor: 重构路由配置,移除订单页面路由 style: 统一使用CSS变量替换硬编码颜色值 docs: 添加前端数据需求分析文档 fix: 修复登录页面记住我功能,更新用户信息页面链接 perf: 优化搜索组件动画效果和响应式设计 chore: 更新TypeScript类型定义,添加订单和地址相关类型
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div id="header">
|
||||
<div id="header" v-if="booleanHeader">
|
||||
<div id="header-profile">
|
||||
<div id="header-profile-left">
|
||||
<!-- 用户信息悬浮菜单 -->
|
||||
@@ -15,6 +15,19 @@
|
||||
</div>
|
||||
<span class="user-arrow">▼</span>
|
||||
</div>
|
||||
<template #overlay>
|
||||
<div class="user-info-menu">
|
||||
<div class="user-info-menu-item">
|
||||
<a href="javascript:;">1st menu item</a>
|
||||
</div>
|
||||
<div class="user-info-menu-item">
|
||||
<a href="javascript:;">2nd menu item</a>
|
||||
</div>
|
||||
<div class="user-info-menu-item">
|
||||
<a href="javascript:;">3rd menu item</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<div id="header-profile-right">
|
||||
@@ -93,9 +106,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Button, Col, Row, Space, Dropdown, Avatar, Menu, Divider, Tag } from 'ant-design-vue';
|
||||
import Input from 'ant-design-vue/es/input';
|
||||
const router = useRouter()
|
||||
// 定义搜索框绑定的变量
|
||||
const searchValue = ref('')
|
||||
@@ -105,19 +119,23 @@ const showHistory = ref(false)
|
||||
const isClearingHistory = ref(false)
|
||||
// 控制搜索框是否显示
|
||||
const booleanSearch = ref(true)
|
||||
// 路由事件
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (to.name === 'search' && to.query.keyword) {
|
||||
searchValue.value = to.query.keyword as string
|
||||
// 控制Header是否显示
|
||||
const booleanHeader = ref(true)
|
||||
// 监听路由变化 当路由变化时 更新搜索框的显示状态
|
||||
watch(() => router.currentRoute.value.name, (newName) => {
|
||||
// 如果是搜索页面 则更新查询参数
|
||||
if (newName === 'search') {
|
||||
searchValue.value = router.currentRoute.value.query.keyword as string
|
||||
}
|
||||
console.log(to.name)
|
||||
// 如果在商品页面 隐藏搜索框
|
||||
if (to.name === 'productDetail' || to.name === 'chat') {
|
||||
booleanSearch.value = false
|
||||
} else {
|
||||
// 如果是商品页面 则显示搜索框
|
||||
if (newName === 'productDetail' || newName === 'chat') {
|
||||
booleanSearch.value = true
|
||||
}
|
||||
next()
|
||||
// 如果在登录页面 则隐藏搜索框
|
||||
if (newName === 'login') {
|
||||
booleanHeader.value = false
|
||||
}
|
||||
console.log(newName)
|
||||
})
|
||||
// 定义搜索框的搜索事件
|
||||
const onSearch = (value: string) => {
|
||||
@@ -186,7 +204,7 @@ const setSearchType = (type: string, event: MouseEvent) => {
|
||||
const currentActiveItem = document.querySelector('.search-type-item.active')
|
||||
// 保存点击的元素引用
|
||||
const clickedTarget = event.currentTarget as HTMLElement
|
||||
|
||||
|
||||
// 为当前活跃的元素添加消失动画
|
||||
if (currentActiveItem && currentActiveItem !== clickedTarget) {
|
||||
if (currentSearchType.value === '宝贝' && type === '店铺') {
|
||||
@@ -270,9 +288,7 @@ const rightMenu = [
|
||||
<style scoped>
|
||||
#header {
|
||||
width: 100%;
|
||||
background-color: var(--card-bg);
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
/* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); */
|
||||
position: relative;
|
||||
z-index: 1000;
|
||||
}
|
||||
@@ -310,8 +326,6 @@ const rightMenu = [
|
||||
border-radius: var(--border-radius-3xl);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-transform);
|
||||
background-color: var(--card-bg);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.user-info-container:hover {
|
||||
@@ -399,6 +413,35 @@ const rightMenu = [
|
||||
transform: rotate(180deg) scale(1.1);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
/* 用户信息菜单样式 */
|
||||
.user-info-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: var(--spacing-md);
|
||||
border-radius: var(--border-radius-lg);
|
||||
box-shadow: var(--shadow-lg);
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
transition: all var(--transition-transform);
|
||||
background-color: var(--card-bg);
|
||||
}
|
||||
|
||||
.user-info-menu-item {
|
||||
padding: var(--spacing-sm) var(--spacing-md);
|
||||
border-radius: var(--border-radius-2xl);
|
||||
transition: all var(--transition-transform);
|
||||
}
|
||||
|
||||
.user-info-menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
|
||||
.user-info-menu-item:hover {
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* 右侧功能菜单样式 */
|
||||
.header-more-btn {
|
||||
@@ -715,6 +758,7 @@ const rightMenu = [
|
||||
.search-type-item.animate-left-out::after {
|
||||
animation: slideOutLeft 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* 搜索类型选择器从左往右动画 */
|
||||
@keyframes slideInRight {
|
||||
from {
|
||||
@@ -727,6 +771,7 @@ const rightMenu = [
|
||||
left: -10%;
|
||||
}
|
||||
}
|
||||
|
||||
/* 搜索类型选择器从右往左动画 */
|
||||
@keyframes slideInLeft {
|
||||
from {
|
||||
@@ -750,20 +795,20 @@ const rightMenu = [
|
||||
|
||||
to {
|
||||
width: 0;
|
||||
left: 100%;
|
||||
left: 200%;
|
||||
}
|
||||
}
|
||||
|
||||
/* 从右往左消失动画 */
|
||||
@keyframes slideOutLeft {
|
||||
from {
|
||||
width: 10%;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
right: -10%;
|
||||
}
|
||||
|
||||
to {
|
||||
width: 0%;
|
||||
right: 100%;
|
||||
right: -200%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user