HarmonyOS 鸿蒙Next中如何使用Search组件实现搜索功能?如何保存搜索历史?
HarmonyOS 鸿蒙Next中如何使用Search组件实现搜索功能?如何保存搜索历史? 我需要实现一个搜索页面,Search 组件如何使用?如何保存和显示搜索历史?
3 回复
实现思路:
- 使用 Search 组件,通过 onSubmit 处理搜索提交:
Search({ value: this.keyword, placeholder: '搜索...' })
.onSubmit((value: string) => {
this.doSearch(value);
})
.onChange((value: string) => {
this.keyword = value;
})
- 使用 Preferences 保存搜索历史:
async saveToHistory(keyword: string) {
const history = this.searchHistory.filter(h => h !== keyword);
history.unshift(keyword);
this.searchHistory = history.slice(0, 10);
await storageUtil.putObject('searchHistory', this.searchHistory);
}
- 对数据进行关键词过滤:
this.searchResults = this.allData.filter(item =>
item.title.includes(keyword) || item.desc.includes(keyword)
);
- 完整示例代码:
@Entry
@Component
struct SearchPage {
@State keyword: string = '';
@State searchHistory: string[] = [];
@State searchResults: DataItem[] = [];
@State isSearching: boolean = false;
private allData: DataItem[] = [
{ id: '1', title: '苹果手机', desc: 'iPhone 15 Pro' },
{ id: '2', title: '华为手机', desc: 'Mate 60 Pro' },
{ id: '3', title: '小米手机', desc: 'Xiaomi 14' }
];
async aboutToAppear() {
this.searchHistory = await storageUtil.getObject<string[]>('searchHistory', []);
}
async doSearch(keyword: string) {
if (!keyword.trim()) return;
this.isSearching = true;
this.keyword = keyword;
await this.saveToHistory(keyword);
// 过滤数据
this.searchResults = this.allData.filter(item =>
item.title.includes(keyword) || item.desc.includes(keyword)
);
this.isSearching = false;
}
async saveToHistory(keyword: string) {
const history = this.searchHistory.filter(h => h !== keyword);
history.unshift(keyword);
this.searchHistory = history.slice(0, 10);
await storageUtil.putObject('searchHistory', this.searchHistory);
}
async clearHistory() {
this.searchHistory = [];
await storageUtil.delete('searchHistory');
}
build() {
Column() {
// 搜索框
Search({ value: this.keyword, placeholder: '搜索...' })
.width('100%')
.height(40)
.onChange((value: string) => {
this.keyword = value;
if (!value) this.searchResults = [];
})
.onSubmit((value: string) => this.doSearch(value))
// 搜索历史
if (this.searchHistory.length > 0 && !this.keyword) {
Column() {
Row() {
Text('搜索历史').fontSize(14).fontColor('#666')
Blank()
Text('清空').fontSize(12).fontColor('#999')
.onClick(() => this.clearHistory())
}
.width('100%')
.margin({ bottom: 8 })
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(this.searchHistory, (item: string) => {
Text(item)
.fontSize(12)
.padding({ left: 12, right: 12, top: 6, bottom: 6 })
.backgroundColor('#F0F0F0')
.borderRadius(16)
.margin(4)
.onClick(() => this.doSearch(item))
})
}
}
.padding(16)
}
// 搜索结果
if (this.isSearching) {
LoadingProgress().width(40).margin({ top: 40 })
} else if (this.searchResults.length > 0) {
List({ space: 8 }) {
ForEach(this.searchResults, (item: DataItem) => {
ListItem() {
Column() {
Text(item.title).fontSize(16)
Text(item.desc).fontSize(12).fontColor('#666')
}
.alignItems(HorizontalAlign.Start)
.padding(12)
}
})
}
.padding(16)
} else if (this.keyword) {
Text('暂无搜索结果').fontColor('#999').margin({ top: 40 })
}
}
.width('100%')
.height('100%')
}
}
interface DataItem {
id: string;
title: string;
desc: string;
}
更多关于HarmonyOS 鸿蒙Next中如何使用Search组件实现搜索功能?如何保存搜索历史?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,使用Search组件实现搜索功能:在ArkUI中引入Search组件,通过onSubmit事件处理搜索提交逻辑,使用onChange监听输入内容变化。
保存搜索历史:通过Preferences或RDB持久化存储搜索记录。在onSubmit事件中,将搜索关键词保存至本地数据库,并在需要时查询展示历史列表。
在HarmonyOS Next中,使用Search组件实现搜索功能并保存历史记录,可以按以下步骤操作:
1. 使用Search组件
Search是ArkUI的基础组件,用于创建搜索框。基本用法如下:
@Entry
@Component
struct SearchExample {
@State searchText: string = ''
build() {
Column() {
Search({
placeholder: '请输入关键词',
controller: this.searchController
})
.onChange((value: string) => {
this.searchText = value
})
.onSubmit((value: string) => {
// 处理搜索提交
this.performSearch(value)
})
.width('100%')
}
}
performSearch(keyword: string) {
// 执行搜索逻辑
console.log(`搜索关键词: ${keyword}`)
}
}
2. 保存搜索历史
建议使用轻量级存储(Preferences)保存搜索历史:
import preferences from '@ohos.data.preferences'
class SearchHistoryManager {
private static readonly KEY_HISTORY = 'search_history'
private static readonly MAX_HISTORY = 10
// 保存搜索记录
static async saveSearchKeyword(keyword: string): Promise<void> {
try {
const prefs = await preferences.getPreferences(this.getContext(), 'search_history')
let history = await prefs.get(this.KEY_HISTORY, '[]')
let historyArray = JSON.parse(history)
// 去重并限制数量
historyArray = historyArray.filter((item: string) => item !== keyword)
historyArray.unshift(keyword)
historyArray = historyArray.slice(0, this.MAX_HISTORY)
await prefs.put(this.KEY_HISTORY, JSON.stringify(historyArray))
await prefs.flush()
} catch (error) {
console.error('保存搜索历史失败:', error)
}
}
// 获取搜索历史
static async getSearchHistory(): Promise<string[]> {
try {
const prefs = await preferences.getPreferences(this.getContext(), 'search_history')
const history = await prefs.get(this.KEY_HISTORY, '[]')
return JSON.parse(history)
} catch (error) {
console.error('获取搜索历史失败:', error)
return []
}
}
// 清空搜索历史
static async clearSearchHistory(): Promise<void> {
try {
const prefs = await preferences.getPreferences(this.getContext(), 'search_history')
await prefs.delete(this.KEY_HISTORY)
await prefs.flush()
} catch (error) {
console.error('清空搜索历史失败:', error)
}
}
}
3. 显示搜索历史
在Search组件下方显示历史记录列表:
@Component
struct SearchHistoryList {
@State historyList: string[] = []
build() {
Column() {
if (this.historyList.length > 0) {
List() {
ForEach(this.historyList, (item: string) => {
ListItem() {
Text(item)
.fontSize(16)
.padding(10)
}
.onClick(() => {
// 点击历史记录重新搜索
this.onHistoryItemClick(item)
})
})
}
} else {
Text('暂无搜索历史')
.fontSize(14)
.fontColor(Color.Gray)
}
}
}
// 加载历史记录
async aboutToAppear() {
this.historyList = await SearchHistoryManager.getSearchHistory()
}
}
4. 完整集成示例
@Entry
@Component
struct SearchPage {
@State searchText: string = ''
@State searchHistory: string[] = []
private searchController: SearchController = new SearchController()
build() {
Column() {
// 搜索框
Search({
placeholder: '搜索...',
controller: this.searchController
})
.onChange((value: string) => {
this.searchText = value
})
.onSubmit(async (value: string) => {
if (value.trim()) {
await SearchHistoryManager.saveSearchKeyword(value)
await this.loadSearchHistory()
this.performSearch(value)
}
})
// 历史记录
SearchHistoryList({ historyList: this.searchHistory })
}
}
async loadSearchHistory() {
this.searchHistory = await SearchHistoryManager.getSearchHistory()
}
async aboutToAppear() {
await this.loadSearchHistory()
}
}
关键点说明:
- Search组件事件:
onChange监听输入变化,onSubmit处理搜索提交 - 数据存储:使用Preferences持久化存储,适合保存少量历史数据
- 历史记录管理:限制记录数量,避免重复,新的记录放在前面
- 性能考虑:历史记录数量建议控制在10-20条以内
这样实现后,用户每次搜索时会自动保存记录,并在下次打开搜索页面时显示历史记录。点击历史记录可以快速重新搜索。

