158 lines
4.0 KiB
Vue
158 lines
4.0 KiB
Vue
<template>
|
||
<div class="search-result-view">
|
||
<header class="top-bar">
|
||
<button class="back-btn" @click="goBack"><</button>
|
||
<div class="search-input-wrapper">
|
||
<span class="search-icon">🔍</span>
|
||
<input type="text" v-model="searchQuery" @keyup.enter="performSearch" />
|
||
</div>
|
||
</header>
|
||
|
||
<div class="tabs">
|
||
<button :class="{ active: activeTab === 'all' }" @click="activeTab = 'all'">全部</button>
|
||
<button :class="{ active: activeTab === 'product' }" @click="activeTab = 'product'">产品</button>
|
||
<button :class="{ active: activeTab === 'article' }" @click="activeTab = 'article'">文章</button>
|
||
<button :class="{ active: activeTab === 'ingredient' }" @click="activeTab = 'ingredient'">成分</button>
|
||
</div>
|
||
|
||
<main class="results-list">
|
||
<!-- Product Results -->
|
||
<div v-if="activeTab === 'all' || activeTab === 'product'" class="result-item" @click="goToResult('product1')">
|
||
<h4>[某品牌纯牛奶]</h4>
|
||
<p>安全评级: <span class="score-a">A</span> | 营养评级: <span class="score-high">高</span></p>
|
||
</div>
|
||
<div v-if="activeTab === 'all' || activeTab === 'product'" class="result-item" @click="goToResult('product2')">
|
||
<h4>[某品牌儿童牛奶]</h4>
|
||
<p>安全评级: <span class="score-c">C</span> | 营养评级: <span class="score-mid">中</span></p>
|
||
</div>
|
||
|
||
<!-- Article Results -->
|
||
<div v-if="activeTab === 'all' || activeTab === 'article'" class="result-item">
|
||
<h4>牛奶过敏的宝宝应该怎么办?</h4>
|
||
<p class="article-summary">本文将详细介绍牛奶过敏的症状、原因以及应对方法...</p>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, onMounted } from 'vue';
|
||
import { useRoute, useRouter } from 'vue-router';
|
||
|
||
const route = useRoute();
|
||
const router = useRouter();
|
||
const searchQuery = ref('');
|
||
const activeTab = ref('all');
|
||
|
||
onMounted(() => {
|
||
searchQuery.value = (route.query.q as string) || '';
|
||
});
|
||
|
||
const goBack = () => {
|
||
router.back();
|
||
};
|
||
|
||
const performSearch = () => {
|
||
// In a real app, this would re-trigger the search
|
||
console.log('Searching for:', searchQuery.value);
|
||
};
|
||
|
||
const goToResult = (id: string) => {
|
||
router.push({ name: 'result', params: { id } });
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
.search-result-view {
|
||
padding-top: 110px; /* Space for top-bar and tabs */
|
||
}
|
||
.top-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 10px 15px;
|
||
background-color: #fff;
|
||
border-bottom: 1px solid #e5e7eb;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
max-width: 428px;
|
||
margin: 0 auto;
|
||
z-index: 10;
|
||
}
|
||
.back-btn {
|
||
background: none; border: none; font-size: 20px; cursor: pointer; padding-right: 10px;
|
||
}
|
||
.search-input-wrapper {
|
||
flex-grow: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
background-color: #f3f4f6;
|
||
border-radius: 18px;
|
||
padding: 8px 12px;
|
||
}
|
||
.search-icon {
|
||
margin-right: 8px;
|
||
}
|
||
.search-input-wrapper input {
|
||
border: none;
|
||
outline: none;
|
||
background: transparent;
|
||
width: 100%;
|
||
}
|
||
|
||
.tabs {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
padding: 10px 0;
|
||
background-color: #fff;
|
||
border-bottom: 1px solid #e5e7eb;
|
||
position: fixed;
|
||
top: 57px; /* Position below top-bar */
|
||
left: 0;
|
||
right: 0;
|
||
max-width: 428px;
|
||
margin: 0 auto;
|
||
z-index: 9;
|
||
}
|
||
.tabs button {
|
||
background: none;
|
||
border: none;
|
||
font-size: 16px;
|
||
color: #6b7280;
|
||
cursor: pointer;
|
||
padding-bottom: 5px;
|
||
border-bottom: 2px solid transparent;
|
||
}
|
||
.tabs button.active {
|
||
color: #22c55e;
|
||
border-bottom-color: #22c55e;
|
||
}
|
||
|
||
.results-list {
|
||
padding: 0 20px;
|
||
}
|
||
.result-item {
|
||
padding: 15px 0;
|
||
border-bottom: 1px solid #e5e7eb;
|
||
cursor: pointer;
|
||
}
|
||
.result-item h4 {
|
||
font-size: 16px;
|
||
margin-bottom: 5px;
|
||
}
|
||
.result-item p {
|
||
font-size: 14px;
|
||
color: #6b7280;
|
||
}
|
||
.article-summary {
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
}
|
||
.score-a { color: #22c55e; font-weight: bold; }
|
||
.score-c { color: orange; font-weight: bold; }
|
||
.score-high { color: #22c55e; }
|
||
.score-mid { color: orange; }
|
||
</style> |