139 lines
2.7 KiB
Vue
139 lines
2.7 KiB
Vue
<template>
|
|
<div class="search-filter-bar">
|
|
<div class="search-input-wrapper">
|
|
<el-input
|
|
v-model="searchKeyword"
|
|
placeholder="请输入关键词搜索项目"
|
|
clearable
|
|
size="small"
|
|
class="search-input"
|
|
@keyup.enter.native="handleSearch"
|
|
@clear="handleSearch"
|
|
/>
|
|
<el-button type="primary" size="small" @click="handleSearch">搜索</el-button>
|
|
</div>
|
|
<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>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'SearchBar',
|
|
props: {
|
|
showSearch: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
tabCounts: {
|
|
type: Object,
|
|
default: () => ({
|
|
all: 0,
|
|
'0': 0,
|
|
'1': 0,
|
|
'2': 0
|
|
})
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
searchKeyword: '',
|
|
activeTab: 'all',
|
|
tabs: [
|
|
{ label: '全部项目', value: 'all', count: 0 },
|
|
{ label: '进行中', value: '0', count: 0 },
|
|
{ label: '已完成', value: '1', count: 0 },
|
|
{ label: '已归档', value: '2', 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()
|
|
},
|
|
/** 标签页切换 */
|
|
handleTabChange(tabValue) {
|
|
this.activeTab = tabValue
|
|
this.emitQuery()
|
|
},
|
|
/** 发送查询 */
|
|
emitQuery() {
|
|
this.$emit('query', {
|
|
projectName: this.searchKeyword || null,
|
|
status: this.activeTab === 'all' ? null : this.activeTab
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.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-input-wrapper {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.search-input {
|
|
width: 240px;
|
|
// Let Element UI's size="small" control the height naturally
|
|
}
|
|
|
|
.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;
|
|
}
|
|
|
|
&.active {
|
|
color: #3B82F6;
|
|
background: #EFF6FF;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
</style>
|