概述
SearchStore 提供了基于云端搜索的搜索能力。如果自定义组件能力不能支持您的业务,可以使用 SearchStore 实现您的需求。
属性
属性名 | 类型 | 说明 |
userList | UserProfile[] | 用户搜索结果列表。 |
userTotalCount | number | 用户搜索结果总数。 |
hasMoreUsers | boolean | 用户搜索结果是否还有下一页。 |
groupList | GroupSearchInfo[] | 群组搜索结果列表。 |
groupTotalCount | number | 群组搜索结果总数。 |
hasMoreGroups | boolean | 群组搜索结果是否还有下一页。 |
groupMemberList | Record<string, GroupMember[]> | 群成员搜索结果,按 groupID 分组。 |
groupMemberTotalCount | number | 群成员搜索结果总数。 |
hasMoreGroupMembers | boolean | 群成员搜索结果是否还有下一页。 |
messageResults | MessageSearchResultItem[] | 消息搜索结果列表。每项按会话聚合,包含会话 ID、会话展示信息、命中消息数量和消息列表。 |
messageResultTotalCount | number | 消息搜索结果总数。 |
hasMoreMessageResults | boolean | 消息搜索结果是否还有下一页。 |
方法
方法名 | 类型 | 说明 |
search | (keywordList: string[], option?: SearchOption) => Promise<void> | 发起搜索。默认会同时搜索用户、群组、群成员和消息;可通过 option.searchScope 限制搜索范围。调用时会重置当前结果和分页游标。 |
searchMore | (searchType: SearchType) => Promise<void> | 加载指定搜索类型的下一页结果。searchType 可为 User、Group、GroupMember、Message。 |
destroy | () => void | 销毁当前 SearchStore 实例,清理订阅和状态。通常由 React/Vue3 封装层自动管理。 |
SearchOption
字段名 | 类型 | 说明 |
keywordListMatchMode | KeywordListMatchMode | 多关键词匹配模式:Or 或 And。默认 Or。 |
searchScope | SearchType[] | 搜索范围。默认包含用户、群组、群成员、消息四类。 |
pageSize | number | 每页数量,默认 20。 |
userFilter | UserSearchFilter | 用户搜索过滤条件。 |
messageFilter | MessageSearchFilter | 消息搜索过滤条件。 |
groupMemberFilter | GroupMemberSearchFilter | 群成员搜索过滤条件。 |
使用示例
<script setup lang="ts">import { ref } from 'vue';import {SearchType,SearchStore,} from '@tencentcloud/chat-uikit-vue3';const {hasMoreUsers,search,searchMore,userList,userTotalCount,} = SearchStore.create();const keyword = ref('');const hasSearched = ref(false);const isLoading = ref(false);async function handleSearch() {const nextKeyword = keyword.value.trim();if (!nextKeyword) {return;}isLoading.value = true;hasSearched.value = true;try {await search([nextKeyword], {pageSize: 20,searchScope: [SearchType.User],});} finally {isLoading.value = false;}}async function handleLoadMore() {isLoading.value = true;try {await searchMore(SearchType.User);} finally {isLoading.value = false;}}function getAvatarText(value: string) {return value.slice(0, 1).toUpperCase();}</script><template><div class="search-store-basic-demo"><div class="search-store-basic-demo__header"><h2>Search Store Basic</h2><p>Very simple user search powered by SearchStore.</p></div><div class="search-store-basic-demo__toolbar"><inputv-model="keyword"type="text"placeholder="Enter user keyword"@keyup.enter="handleSearch"/><buttontype="button":disabled="isLoading || !keyword.trim()"@click="handleSearch">{{ isLoading ? 'Searching...' : 'Search' }}</button></div><div class="search-store-basic-demo__panel"><h3>Users ({{ userTotalCount }})</h3><ul v-if="userList.length > 0" class="search-store-basic-demo__list"><liv-for="user in userList":key="user.userID"class="search-store-basic-demo__item"><span class="search-store-basic-demo__avatar">{{ getAvatarText(user.nickname || user.userID) }}</span><span><strong>{{ user.nickname || user.userID }}</strong><small>{{ user.userID }}</small></span></li></ul><div v-else class="search-store-basic-demo__empty">{{ hasSearched ? 'No users found.' : 'Enter a keyword and search.' }}</div></div><buttonv-if="hasMoreUsers"class="search-store-basic-demo__more"type="button":disabled="isLoading"@click="handleLoadMore">Load More</button></div></template><style scoped>.search-store-basic-demo {display: flex;height: 100%;flex-direction: column;gap: 16px;padding: 24px;overflow: hidden;}.search-store-basic-demo__header h2 {margin: 0 0 8px;color: #111827;font-size: 22px;}.search-store-basic-demo__header p {margin: 0;color: #6b7280;font-size: 14px;}.search-store-basic-demo__toolbar {display: flex;gap: 8px;}.search-store-basic-demo__toolbar input {width: 260px;padding: 8px 10px;border: 1px solid #d7dce5;border-radius: 8px;}.search-store-basic-demo__toolbar button,.search-store-basic-demo__more {padding: 8px 12px;border: 1px solid #667eea;border-radius: 8px;background: #667eea;color: #fff;cursor: pointer;}.search-store-basic-demo__toolbar button:disabled,.search-store-basic-demo__more:disabled {opacity: 0.6;cursor: not-allowed;}.search-store-basic-demo__panel {display: flex;width: min(560px, 100%);min-height: 0;flex: 1;flex-direction: column;overflow: hidden;border: 1px solid #edf0f5;border-radius: 12px;background: #fff;}.search-store-basic-demo__panel h3 {margin: 0;padding: 14px 16px;border-bottom: 1px solid #edf0f5;color: #111827;font-size: 15px;}.search-store-basic-demo__list {display: flex;flex-direction: column;gap: 8px;margin: 0;padding: 12px;overflow: auto;list-style: none;}.search-store-basic-demo__item {display: flex;align-items: center;gap: 10px;padding: 10px;border-radius: 10px;background: #f9fafb;}.search-store-basic-demo__avatar {display: inline-flex;width: 32px;height: 32px;align-items: center;justify-content: center;border-radius: 50%;background: #eef2ff;color: #4f46e5;font-size: 13px;font-weight: 700;}.search-store-basic-demo__item strong,.search-store-basic-demo__item small {display: block;}.search-store-basic-demo__item strong {color: #111827;font-size: 14px;}.search-store-basic-demo__item small {margin-top: 2px;color: #6b7280;font-size: 12px;}.search-store-basic-demo__empty {padding: 24px;color: #6b7280;text-align: center;}.search-store-basic-demo__more {width: fit-content;}</style>