feat: 重写搜索栏组件,添加标签页筛选功能

This commit is contained in:
wkc
2026-02-27 14:05:05 +08:00
parent b03c9c4efe
commit 0554cb5df1

View File

@@ -1,62 +1,25 @@
<template>
<div class="search-bar-container">
<el-card class="search-card" shadow="hover">
<el-row :gutter="12" align="middle">
<el-col :span="8">
<el-input
v-model="searchKeyword"
placeholder="请输入项目名称"
prefix-icon="el-icon-search"
clearable
size="medium"
@keyup.enter.native="handleSearch"
/>
</el-col>
<el-col :span="5">
<el-select
v-model="selectedStatus"
placeholder="项目状态"
clearable
size="medium"
style="width: 100%"
@change="handleStatusChange"
>
<el-option
v-for="item in statusOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-col>
<el-col :span="4">
<el-button
type="primary"
icon="el-icon-search"
size="medium"
@click="handleSearch"
>搜索</el-button>
<el-button
icon="el-icon-refresh"
size="medium"
@click="handleReset"
>重置</el-button>
</el-col>
<el-col :span="7" style="text-align: right">
<el-button
type="primary"
icon="el-icon-plus"
size="medium"
@click="handleAdd"
>新建项目</el-button>
<el-button
icon="el-icon-folder-opened"
size="medium"
@click="handleImport"
>导入历史项目</el-button>
</el-col>
</el-row>
</el-card>
<div class="search-filter-bar">
<el-input
v-model="searchKeyword"
placeholder="请输入关键词搜索项目"
prefix-icon="el-icon-search"
clearable
size="small"
class="search-input"
@keyup.enter.native="handleSearch"
@clear="handleSearch"
/>
<div class="tab-filters">
<div
v-for="tab in tabs"
:key="tab.value"
:class="['tab-item', { active: activeTab === tab.value }]"
@click="handleTabChange(tab.value)"
>
{{ tab.label }}({{ tab.count }})
</div>
</div>
</div>
</template>
@@ -67,74 +30,101 @@ export default {
showSearch: {
type: Boolean,
default: true
},
tabCounts: {
type: Object,
default: () => ({
all: 0,
ongoing: 0,
completed: 0,
archived: 0
})
}
},
data() {
return {
searchKeyword: '',
selectedStatus: '',
statusOptions: [
{ label: '进行中', value: '0' },
{ label: '已完成', value: '1' },
{ label: '已归档', value: '2' }
activeTab: 'all',
tabs: [
{ label: '全部项目', value: 'all', count: 0 },
{ label: '进行中', value: 'ongoing', count: 0 },
{ label: '已完成', value: 'completed', count: 0 },
{ label: '已归档', value: 'archived', count: 0 }
]
}
},
watch: {
tabCounts: {
handler(newVal) {
this.tabs = this.tabs.map(tab => ({
...tab,
count: newVal[tab.value] || 0
}))
},
immediate: true,
deep: true
}
},
methods: {
/** 搜索 */
handleSearch() {
this.emitQuery()
},
/** 状态变化 */
handleStatusChange() {
this.emitQuery()
},
/** 重置 */
handleReset() {
this.searchKeyword = ''
this.selectedStatus = ''
/** 标签页切换 */
handleTabChange(tabValue) {
this.activeTab = tabValue
this.emitQuery()
},
/** 发送查询 */
emitQuery() {
this.$emit('query', {
projectName: this.searchKeyword || null,
status: this.selectedStatus || null
status: this.activeTab === 'all' ? null : this.activeTab
})
},
/** 新增 */
handleAdd() {
this.$emit('add')
},
/** 导入 */
handleImport() {
this.$emit('import')
}
}
}
</script>
<style lang="scss" scoped>
.search-bar-container {
margin-bottom: 12px;
.search-filter-bar {
display: flex;
align-items: center;
gap: 24px;
padding: 16px 20px;
background: #ffffff;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.search-card {
border-radius: 4px;
border: 1px solid #EBEEF5;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
.search-input {
width: 240px;
height: 40px;
}
:deep(.el-card__body) {
padding: 12px 16px;
.tab-filters {
display: flex;
align-items: center;
gap: 24px;
}
.tab-item {
font-size: 14px;
color: #6B7280;
cursor: pointer;
padding: 6px 12px;
border-radius: 6px;
transition: all 0.2s ease;
user-select: none;
&:hover {
color: #3B82F6;
}
}
:deep(.el-button--medium) {
padding: 10px 16px;
margin-left: 8px;
&:first-child {
margin-left: 0;
&.active {
color: #3B82F6;
background: #EFF6FF;
font-weight: 500;
}
}
</style>