Files
ys-app/src/components/customSearch.vue
2025-08-27 13:49:03 +08:00

306 lines
7.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<!-- 搜索框 -->
<view class="search search-sao">
<!-- @confirm="handleSearch" @cancel="handleCancel"-->
<uni-search-bar class="custom-search"
radius="28"
placeholder="请输入搜索条件"
clearButton="auto"
bgColor="#6FA2F8" textColor="#ffffff"
v-model="searchText"
cancelButton="none"
focus
/>
<text class="search-btn" @click="handleSearch">查询</text>
</view>
<view class="white-bg">
<!-- 类型列表 -->
<view class="search-section" v-if="searchTypeList.length>0">
<view class="section-header">
<text class="section-title">{{ searchType.typeName }}</text>
</view>
<view class="tag-container">
<view class="search-tag notice-tag" :class="{'notice-check':!searchCheckObj.id}" @click="handleNoticeClick({})">全部</view>
<view class="search-tag notice-tag" :class="{'notice-check':item.id==searchCheckObj.id}"
v-for="(item, index) in searchTypeList"
:key="'notice-' + index"
@click="handleNoticeClick(item)"
>
{{ item.name }}
</view>
</view>
</view>
<!-- 历史记录 v-if="historyList.length>0" -->
<view class="search-section">
<view class="section-header">
<text class="section-title">历史搜索</text>
<uni-icons type="trash" size="18" color="#999" @click="clearHistory"></uni-icons>
</view>
<view class="tag-container">
<view class="search-tag" v-for="(item, index) in historyList" :key="'history-' + index"
@click="handleHistoryClick(item)">
{{ item }}
</view>
</view>
</view>
<!-- 搜索结果 -->
<!-- <view class="search-result" v-if="searchResult.length > 0">
<view class="result-item"
v-for="(item, index) in searchResult"
:key="'result-' + index"
@click="handleResultClick(item)"
>
{{ item.name }}
</view>
</view> -->
</view>
</view>
</template>
<script setup>
import { ref,watch } from 'vue'
const props = defineProps({
searchKeywords:{//搜索文本
type:String
},
searchType:{//哪种类型显示对象 typeId:1-首页2-业务首页3-消息 之后可以自动添加
type:Object
},
searchTypeList:{//类型列表
type:Array,
default:[]
},
checkTypeObj:{//选中的类型对象
type:Object
},
})
const searchText = ref('');// 搜索文本
const searchCheckObj = ref({});//选中的类型对象
const showCancel = ref(false)// 是否显示取消按钮
const historyList = ref([])// 历史记录列表
const searchResult = ref([])// 搜索结果
// 搜索文本内容
watch(() => props.searchKeywords, (newVal, oldVal) => {
searchText.value = newVal
},{
deep:true, // 深度监听
immediate:true // 立即执行
});
// 选中类型对象
watch(() => props.checkTypeObj, (newVal, oldVal) => {
searchCheckObj.value = newVal
},{
deep:true, // 深度监听
immediate:true // 立即执行
});
// 调用父组件的方法
const emit = defineEmits(['confirm']);
// 加载历史记录
const loadHistory = () => {
let typeId = props.searchType?props.searchType.typeId:undefined
const history = uni.getStorageSync('searchHistory'+typeId) || []
historyList.value = history
}
loadHistory();
// 处理搜索
const handleSearch = () => {
let txtContent = searchText.value?searchText.value.trim():undefined
if (txtContent) {
// uni.showToast({
// title: '请输入搜索内容',
// icon: 'none'
// })
// return
// 添加到历史记录
addToHistory(txtContent)
}
// 模拟搜索请求
// searchResult.value = [
// { id: 1, name: `${searchText.value} 结果1` },
// { id: 2, name: `${searchText.value} 结果2` },
// { id: 3, name: `${searchText.value} 结果3` }
// ]
// 传给父组件
emit('confirm',searchCheckObj,searchText);
}
// 处理输入
const handleInput = () => {
showCancel.value = searchText.value.length > 0
}
// 清除搜索
const clearSearch = () => {
searchText.value = ''
showCancel.value = false
searchResult.value = []
}
// 添加到历史记录
const addToHistory = (keyword) => {
const index = historyList.value.indexOf(keyword)
if (index !== -1) {
historyList.value.splice(index, 1)
}
historyList.value.unshift(keyword)
// 限制历史记录数量
if (historyList.value.length > 10) {
historyList.value = historyList.value.slice(0, 10)
}
let typeId = props.searchType.typeId
uni.setStorageSync('searchHistory'+typeId, historyList.value)
}
// 清除历史记录
const clearHistory = () => {
uni.showModal({
title: '提示',
content: '确定要清空历史记录吗?',
success: (res) => {
if (res.confirm) {
historyList.value = []
let typeId = props.searchType.typeId;
uni.removeStorageSync('searchHistory'+typeId)
}
}
})
}
// 点击历史记录
const handleHistoryClick = (item) => {
searchText.value = item
handleSearch()
}
// 点击消息类型
const handleNoticeClick = (item) => {
// searchText.value = item
searchCheckObj.value = item;
handleSearch()
}
// 点击搜索结果
const handleResultClick = (item) => {
uni.showToast({
title: `点击了 ${item.name}`,
icon: 'none'
})
// 实际项目中这里可以跳转到详情页
// uni.navigateTo({ url: `/pages/detail/detail?id=${item.id}` })
}
</script>
<style scoped>
.search-sao {
display: flex;
}
.search-sao .custom-search {
/* width:615rpx; */
width: 590rpx;
padding: 0 20rpx;
margin-bottom:15rpx;
}
.search-sao :deep(.custom-search.uni-searchbar) {
padding-bottom: 15rpx !important;
}
.search-sao .search-btn {
margin: 15rpx 30rpx 10rpx 0;
color: #fff;
font-size: 28rpx;
font-weight: bold;
text-align: center;
}
.white-bg {
width: 750rpx;
padding: 40rpx 0;
margin-bottom: 0;
border-radius: 8px 8px 0 0;
/* #ifdef APP-PLUS */
height: calc(100vh - 168px);
/* #endif */
/* #ifndef APP-PLUS */
height: calc(100vh - 150px);
/* #endif */
}
.search-section {
margin-bottom: 40rpx;
padding:0 45rpx;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.section-title {
font-size: 28rpx;
color: #333;
font-weight: bold;
}
.tag-container {
display: flex;
flex-wrap: wrap;
}
.search-tag {
background-color: #fff;
border:1px solid #E8E8E8;
border-radius: 10rpx;
padding: 10rpx 15rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
font-size: 28rpx;
}
.search-tag.notice-tag{
padding: 10rpx 45rpx;
}
.notice-tag:nth-child(3n){
margin-right: 0;
}
.notice-check{
background-color: #05A3F4;
color:#fff;
border-color:#05A3F4;
}
.search-result {
margin-top: 20rpx;
padding:0 20rpx;
}
.result-item {
padding: 20rpx 0;
border-bottom: 1rpx solid #eee;
font-size: 28rpx;
color: #333;
}
</style>