@tencentcloud/sdk-mcp 1.3.4 → 1.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/package.json +1 -1
  2. package/resource/doc/chatuikit/android/features/theme.md +363 -0
  3. package/resource/doc/chatuikit/android/workflow.md +0 -0
  4. package/resource/doc/chatuikit/{android/client_api_android.md → faq/android_sdk/client-api.md} +0 -1
  5. package/resource/doc/chatuikit/faq/{native_sdk/faq.md → common/product.md} +8 -0
  6. package/resource/doc/chatuikit/faq/flutter_sdk/faq.md +54 -0
  7. package/resource/doc/chatuikit/faq/web_sdk/faq.md +1 -1
  8. package/resource/doc/chatuikit/flutter/features/theme.md +379 -0
  9. package/resource/doc/chatuikit/flutter/workflow.md +816 -0
  10. package/resource/doc/chatuikit/iOS/features/theme.md +416 -0
  11. package/resource/doc/chatuikit/iOS/workflow.md +0 -0
  12. package/resource/doc/chatuikit/react/components/chat-setting.md +124 -0
  13. package/resource/doc/chatuikit/react/components/contact-list.md +1331 -0
  14. package/resource/doc/chatuikit/react/components/search.md +885 -0
  15. package/resource/doc/chatuikit/vue/components/chat-setting.md +88 -0
  16. package/resource/doc/chatuikit/vue/components/contact-list.md +679 -0
  17. package/resource/doc/chatuikit/vue/components/search.md +1384 -0
  18. package/resource/doc/livekit/live/android/workflow.md +137 -4
  19. package/resource/doc/livekit/live/flutter/live-audience-list.md +337 -0
  20. package/resource/doc/livekit/live/flutter/live-audio-effect.md +739 -0
  21. package/resource/doc/livekit/live/flutter/live-barrage.md +578 -0
  22. package/resource/doc/livekit/live/flutter/live-base-beauty.md +484 -0
  23. package/resource/doc/livekit/live/flutter/live-co-guest-interaction.md +606 -0
  24. package/resource/doc/livekit/live/flutter/live-gift.md +812 -0
  25. package/resource/doc/livekit/live/flutter/live-host-interaction.md +1113 -0
  26. package/resource/doc/livekit/live/flutter/live-integration.md +1029 -0
  27. package/resource/doc/livekit/live/flutter/live-live-list.md +861 -0
  28. package/resource/doc/livekit/live/ios/live-audience-list.md +335 -0
  29. package/resource/doc/livekit/live/ios/live-audio-effect.md +373 -0
  30. package/resource/doc/livekit/live/ios/live-barrage.md +529 -0
  31. package/resource/doc/livekit/live/ios/live-base-beauty.md +237 -0
  32. package/resource/doc/livekit/live/ios/live-co-guest-interaction.md +483 -0
  33. package/resource/doc/livekit/live/ios/live-gift.md +785 -0
  34. package/resource/doc/livekit/live/ios/live-host-interaction.md +743 -0
  35. package/resource/doc/livekit/live/ios/live-integration.md +822 -0
  36. package/resource/doc/livekit/live/ios/live-live-list.md +535 -0
  37. package/resource/doc/livekit/live/ios/workflow.md +352 -0
  38. package/resource/doc/rtcengine/faq/web/web.md +2 -2
  39. package/resource/doc/rtcengine/web/how_to_integrated_web_sdk.md +2 -2
  40. package/resource/doc/rtcengine/web/plugin/20-advanced-customized-capture-rendering.md +84 -0
  41. package/resource/doc/rtcengine/web/plugin/21-advanced-auto-play-policy.md +86 -0
  42. package/resource/doc/rtcengine/web/plugin/22-advanced-audio-mixer.md +220 -0
  43. package/resource/doc/rtcengine/web/plugin/23-advanced-support-detection.md +217 -0
  44. package/resource/doc/rtcengine/web/plugin/24-advanced-network-quality.md +137 -0
  45. package/resource/doc/rtcengine/web/plugin/25-advanced-device-change.md +97 -0
  46. package/resource/doc/rtcengine/web/plugin/26-advanced-publish-cdn-stream.md +453 -0
  47. package/resource/doc/rtcengine/web/plugin/27-advanced-small-stream.md +180 -0
  48. package/resource/doc/rtcengine/web/plugin/28-advanced-beauty.md +349 -0
  49. package/resource/doc/rtcengine/web/plugin/29-advanced-water-mark.md +149 -0
  50. package/resource/doc/rtcengine/web/plugin/30-advanced-cross-room-link.md +96 -0
  51. package/resource/doc/rtcengine/web/plugin/31-advanced-plugins-overview.md +405 -0
  52. package/resource/doc/rtcengine/web/plugin/34-advanced-proxy.md +244 -0
  53. package/resource/doc/rtcengine/web/plugin/35-advanced-ai-denoiser.md +84 -0
  54. package/resource/doc/rtcengine/web/plugin/36-advanced-virtual-background.md +202 -0
  55. package/resource/doc/rtcengine/web/plugin/37-advanced-voice-changer.md +98 -0
  56. package/resource/doc/rtcengine/web/plugin/38-advanced-basic-beauty.md +95 -0
  57. package/resource/doc/rtcengine/web/plugin/39-advanced-video-decoder.md +33 -0
  58. package/resource/doc/rtcengine/web/plugin/40-advanced-video-mixer.md +380 -0
  59. package/resource/doc/rtcengine/web/plugin/41-advanced-small-stream-auto-switcher.md +91 -0
  60. package/resource/doc/rtcengine/web/plugin/42-advanced-realtime-transcriber.md +314 -0
  61. package/resource/doc/rtcengine/web/plugin/43-advanced-face-detection.md +180 -0
  62. package/tools/chat/get-native-chat-feature-detail.js +30 -0
  63. package/tools/chat/get-native-chat-feature-detail.js.map +1 -0
  64. package/tools/chat/get-native-chat-integration.js +30 -12
  65. package/tools/chat/get-native-chat-integration.js.map +1 -1
  66. package/tools/common/get-faq.js +2 -4
  67. package/tools/common/get-faq.js.map +1 -1
  68. package/tools/definitions/get_native_chat_feature_detail_def.js +32 -0
  69. package/tools/definitions/get_native_chat_feature_detail_def.js.map +1 -0
  70. package/tools/definitions/get_native_chat_uikit_integration_def.js +18 -6
  71. package/tools/definitions/get_native_chat_uikit_integration_def.js.map +1 -1
  72. package/tools/definitions/{get_native_live_extra_features_def.js → get_native_live_uikit_extra_features_def.js} +3 -3
  73. package/tools/definitions/get_native_live_uikit_extra_features_def.js.map +1 -0
  74. package/tools/definitions/{get_native_live_interaction_def.js → get_native_live_uikit_interaction_def.js} +3 -3
  75. package/tools/definitions/get_native_live_uikit_interaction_def.js.map +1 -0
  76. package/tools/definitions/get_web_chat_uikit_component_detail_def.js +46 -7
  77. package/tools/definitions/get_web_chat_uikit_component_detail_def.js.map +1 -1
  78. package/tools/index.js +6 -4
  79. package/tools/index.js.map +1 -1
  80. package/tools/live/{get_native_live_extra_features.js → get_native_live_uikit_extra_features.js} +4 -4
  81. package/tools/live/get_native_live_uikit_extra_features.js.map +1 -0
  82. package/tools/live/{get_native_live_interaction.js → get_native_live_uikit_interaction.js} +4 -4
  83. package/tools/live/get_native_live_uikit_interaction.js.map +1 -0
  84. package/tools/rtcengine/get-trtc-web-sdk-faq.js +1 -1
  85. package/tools/rtcengine/get-trtc-web-sdk-plugin.js +45 -0
  86. package/tools/rtcengine/get-trtc-web-sdk-plugin.js.map +1 -0
  87. package/utils/handle-component-name.js +0 -16
  88. package/utils/handle-component-name.js.map +1 -1
  89. package/utils/report-cls-client.js +1 -1
  90. package/utils/report-es-client.js +1 -1
  91. package/resource/doc/chatuikit/android/integrate_tuichat_only_android.md +0 -382
  92. package/resource/doc/chatuikit/android/ui_api_android.md +0 -418
  93. package/resource/doc/chatuikit/iOS/integrate_tuichat_only_iOS.md +0 -993
  94. package/resource/doc/chatuikit/iOS/ui_api_iOS.md +0 -526
  95. package/tools/definitions/get_native_live_extra_features_def.js.map +0 -1
  96. package/tools/definitions/get_native_live_interaction_def.js.map +0 -1
  97. package/tools/live/get_native_live_extra_features.js.map +0 -1
  98. package/tools/live/get_native_live_interaction.js.map +0 -1
  99. /package/resource/doc/chatuikit/android/{integrate_tuikit_android.md → integration.md} +0 -0
  100. /package/resource/doc/chatuikit/{flutter/client_api_Flutter.md → faq/flutter_sdk/client-api.md} +0 -0
  101. /package/resource/doc/chatuikit/{iOS/client_api_iOS.md → faq/ios_sdk/client-api.md} +0 -0
  102. /package/resource/doc/chatuikit/flutter/{integrate_tuikit_Flutter.md → integration.md} +0 -0
  103. /package/resource/doc/chatuikit/iOS/{integrate_tuikit_iOS.md → integration.md} +0 -0
  104. /package/resource/doc/chatuikit/react/components/{chatheader.md → chat-header.md} +0 -0
  105. /package/resource/doc/chatuikit/vue/components/{chatheader.md → chat-header.md} +0 -0
@@ -0,0 +1,1384 @@
1
+ ## 概述
2
+
3
+ Search 是一个功能完整的搜索解决方案,包含了搜索框、搜索结果展示、高级搜索等功能的完整组件集合。适用于即时通讯、在线会议、在线教育等场景的用户、群组、消息搜索。
4
+
5
+ > **说明:**
6
+ >
7
+
8
+ > 此功能属于增值服务,需要您购买云端搜索插件,请点击 [购买](https://cloud.tencent.com/document/product/269/120945)。
9
+ >
10
+
11
+
12
+ ![](https://write-document-release-1258344699.cos.ap-guangzhou.tencentcos.cn/100027116646/a31b2bd2870911f0bd05525400454e06.png)
13
+
14
+
15
+ ## 搜索模式
16
+ <table>
17
+ <tr>
18
+ <td rowspan="1" colSpan="1" >**迷你模式 (MINI)**</td>
19
+
20
+ <td rowspan="1" colSpan="1" >**标准模式 (STANDARD)**</td>
21
+
22
+ <td rowspan="1" colSpan="1" >**嵌入式模式 (EMBEDDED)**</td>
23
+ </tr>
24
+
25
+ <tr>
26
+ <td rowspan="1" colSpan="1" >适用于侧边栏或小容器<br>显示有限结果数量<br>支持展开查看更多</td>
27
+
28
+ <td rowspan="1" colSpan="1" >适用于全屏搜索界面<br>完整功能展示<br>支持高级搜索</td>
29
+
30
+ <td rowspan="1" colSpan="1" >适用于聊天界面<br>专注消息搜索<br>优化的布局</td>
31
+ </tr>
32
+ </table>
33
+
34
+
35
+ ## Props
36
+ <table>
37
+ <tr>
38
+ <td rowspan="1" colSpan="1" >属性名</td>
39
+
40
+ <td rowspan="1" colSpan="1" >类型</td>
41
+
42
+ <td rowspan="1" colSpan="1" >默认值</td>
43
+
44
+ <td rowspan="1" colSpan="1" >说明</td>
45
+ </tr>
46
+
47
+ <tr>
48
+ <td rowspan="1" colSpan="1" >variant</td>
49
+
50
+ <td rowspan="1" colSpan="1" >VariantType</td>
51
+
52
+ <td rowspan="1" colSpan="1" >VariantType.MINI</td>
53
+
54
+ <td rowspan="1" colSpan="1" >搜索模式:mini(迷你)、standard(标准)、embedded(嵌入式)</td>
55
+ </tr>
56
+
57
+ <tr>
58
+ <td rowspan="1" colSpan="1" >SearchBar</td>
59
+
60
+ <td rowspan="1" colSpan="1" >Component<SearchBarProps></td>
61
+
62
+ <td rowspan="1" colSpan="1" >DefaultSearchBar</td>
63
+
64
+ <td rowspan="1" colSpan="1" >自定义搜索框组件</td>
65
+ </tr>
66
+
67
+ <tr>
68
+ <td rowspan="1" colSpan="1" >SearchResults</td>
69
+
70
+ <td rowspan="1" colSpan="1" >Component<SearchResultsProps></td>
71
+
72
+ <td rowspan="1" colSpan="1" >DefaultSearchResults</td>
73
+
74
+ <td rowspan="1" colSpan="1" >自定义搜索结果组件</td>
75
+ </tr>
76
+
77
+ <tr>
78
+ <td rowspan="1" colSpan="1" >SearchAdvanced</td>
79
+
80
+ <td rowspan="1" colSpan="1" >Component<SearchAdvancedProps></td>
81
+
82
+ <td rowspan="1" colSpan="1" >DefaultSearchAdvanced</td>
83
+
84
+ <td rowspan="1" colSpan="1" >自定义高级搜索组件</td>
85
+ </tr>
86
+
87
+ <tr>
88
+ <td rowspan="1" colSpan="1" >SearchResultsPresearch</td>
89
+
90
+ <td rowspan="1" colSpan="1" >Component</td>
91
+
92
+ <td rowspan="1" colSpan="1" >-</td>
93
+
94
+ <td rowspan="1" colSpan="1" >搜索前占位符组件</td>
95
+ </tr>
96
+
97
+ <tr>
98
+ <td rowspan="1" colSpan="1" >SearchResultsLoading</td>
99
+
100
+ <td rowspan="1" colSpan="1" >Component</td>
101
+
102
+ <td rowspan="1" colSpan="1" >-</td>
103
+
104
+ <td rowspan="1" colSpan="1" >加载中占位符组件</td>
105
+ </tr>
106
+
107
+ <tr>
108
+ <td rowspan="1" colSpan="1" >SearchResultsEmpty</td>
109
+
110
+ <td rowspan="1" colSpan="1" >Component</td>
111
+
112
+ <td rowspan="1" colSpan="1" >-</td>
113
+
114
+ <td rowspan="1" colSpan="1" >空结果占位符组件</td>
115
+ </tr>
116
+
117
+ <tr>
118
+ <td rowspan="1" colSpan="1" >SearchResultItem</td>
119
+
120
+ <td rowspan="1" colSpan="1" >Component<ResultItemProps></td>
121
+
122
+ <td rowspan="1" colSpan="1" >-</td>
123
+
124
+ <td rowspan="1" colSpan="1" >自定义搜索结果项组件</td>
125
+ </tr>
126
+
127
+ <tr>
128
+ <td rowspan="1" colSpan="1" >debounceTime</td>
129
+
130
+ <td rowspan="1" colSpan="1" >number</td>
131
+
132
+ <td rowspan="1" colSpan="1" >300</td>
133
+
134
+ <td rowspan="1" colSpan="1" >搜索防抖时间(毫秒)</td>
135
+ </tr>
136
+
137
+ <tr>
138
+ <td rowspan="1" colSpan="1" >autoFocus</td>
139
+
140
+ <td rowspan="1" colSpan="1" >boolean</td>
141
+
142
+ <td rowspan="1" colSpan="1" >false</td>
143
+
144
+ <td rowspan="1" colSpan="1" >是否自动聚焦搜索框</td>
145
+ </tr>
146
+
147
+ <tr>
148
+ <td rowspan="1" colSpan="1" >className</td>
149
+
150
+ <td rowspan="1" colSpan="1" >string</td>
151
+
152
+ <td rowspan="1" colSpan="1" >-</td>
153
+
154
+ <td rowspan="1" colSpan="1" >自定义样式类名</td>
155
+ </tr>
156
+
157
+ <tr>
158
+ <td rowspan="1" colSpan="1" >style</td>
159
+
160
+ <td rowspan="1" colSpan="1" >CSSProperties</td>
161
+
162
+ <td rowspan="1" colSpan="1" >-</td>
163
+
164
+ <td rowspan="1" colSpan="1" >自定义样式</td>
165
+ </tr>
166
+
167
+ <tr>
168
+ <td rowspan="1" colSpan="1" >onKeywordChange</td>
169
+
170
+ <td rowspan="1" colSpan="1" >(keyword: string) => void</td>
171
+
172
+ <td rowspan="1" colSpan="1" >-</td>
173
+
174
+ <td rowspan="1" colSpan="1" >搜索关键词变化回调</td>
175
+ </tr>
176
+
177
+ <tr>
178
+ <td rowspan="1" colSpan="1" >onSearchComplete</td>
179
+
180
+ <td rowspan="1" colSpan="1" >(results: Map<SearchType, SearchResult>) => void</td>
181
+
182
+ <td rowspan="1" colSpan="1" >-</td>
183
+
184
+ <td rowspan="1" colSpan="1" >搜索完成回调</td>
185
+ </tr>
186
+
187
+ <tr>
188
+ <td rowspan="1" colSpan="1" >onResultItemClick</td>
189
+
190
+ <td rowspan="1" colSpan="1" >(data: SearchResultItem, type: SearchType) => void</td>
191
+
192
+ <td rowspan="1" colSpan="1" >-</td>
193
+
194
+ <td rowspan="1" colSpan="1" >搜索结果点击回调</td>
195
+ </tr>
196
+
197
+ <tr>
198
+ <td rowspan="1" colSpan="1" >onError</td>
199
+
200
+ <td rowspan="1" colSpan="1" >(error: Error) => void</td>
201
+
202
+ <td rowspan="1" colSpan="1" >-</td>
203
+
204
+ <td rowspan="1" colSpan="1" >搜索错误回调</td>
205
+ </tr>
206
+ </table>
207
+
208
+
209
+ ## 基础用法
210
+ ``` typescript
211
+ <template>
212
+ <div class="app">
213
+ <Search
214
+ :variant="VariantType.STANDARD"
215
+ @result-item-click="handleResultClick"
216
+ @keyword-change="handleKeywordChange"
217
+ @error="handleError"
218
+ />
219
+ </div>
220
+ </template>
221
+
222
+ <script setup lang="ts">
223
+ import { Search, VariantType } from '@tencentcloud/chat-uikit-vue3';
224
+ import type { SearchResultItemType, SearchType } from '@tencentcloud/chat-uikit-vue3';
225
+
226
+ const handleResultClick = (data: SearchResultItemType, type: SearchType) => {
227
+ console.log('搜索结果点击:', data, type);
228
+ };
229
+
230
+ const handleKeywordChange = (keyword: string) => {
231
+ console.log('搜索关键词变化:', keyword);
232
+ };
233
+
234
+ const handleError = (error: Error) => {
235
+ console.error('搜索错误:', error);
236
+ };
237
+ </script>
238
+ ```
239
+
240
+ ## 自定义
241
+
242
+ `Search` 组件提供了多个可替换的子组件,允许用户自定义 `SearchBar`, `SearchResults`, `SearchAdvanced`, `SearchResultItem`, `SearchResultsPresearch`, `SearchResultsLoading`, `SearchResultsEmpty` 等。同时,用户还可以利用默认子组件进行二次开发定制。
243
+
244
+
245
+
246
+ 【自定义 SearchBar】
247
+
248
+ **Props**
249
+ <table>
250
+ <tr>
251
+ <td rowspan="1" colSpan="1" >属性名</td>
252
+
253
+ <td rowspan="1" colSpan="1" >类型</td>
254
+
255
+ <td rowspan="1" colSpan="1" >默认值</td>
256
+
257
+ <td rowspan="1" colSpan="1" >说明</td>
258
+ </tr>
259
+
260
+ <tr>
261
+ <td rowspan="1" colSpan="1" >value</td>
262
+
263
+ <td rowspan="1" colSpan="1" >string</td>
264
+
265
+ <td rowspan="1" colSpan="1" >-</td>
266
+
267
+ <td rowspan="1" colSpan="1" >搜索框值</td>
268
+ </tr>
269
+
270
+ <tr>
271
+ <td rowspan="1" colSpan="1" >onChange</td>
272
+
273
+ <td rowspan="1" colSpan="1" >(e: Event) => void</td>
274
+
275
+ <td rowspan="1" colSpan="1" >-</td>
276
+
277
+ <td rowspan="1" colSpan="1" >输入变化回调</td>
278
+ </tr>
279
+
280
+ <tr>
281
+ <td rowspan="1" colSpan="1" >onKeyDown</td>
282
+
283
+ <td rowspan="1" colSpan="1" >(e: KeyboardEvent) => void</td>
284
+
285
+ <td rowspan="1" colSpan="1" >-</td>
286
+
287
+ <td rowspan="1" colSpan="1" >键盘事件回调</td>
288
+ </tr>
289
+
290
+ <tr>
291
+ <td rowspan="1" colSpan="1" >onClear</td>
292
+
293
+ <td rowspan="1" colSpan="1" >() => void</td>
294
+
295
+ <td rowspan="1" colSpan="1" >-</td>
296
+
297
+ <td rowspan="1" colSpan="1" >清除回调</td>
298
+ </tr>
299
+
300
+ <tr>
301
+ <td rowspan="1" colSpan="1" >placeholder</td>
302
+
303
+ <td rowspan="1" colSpan="1" >string</td>
304
+
305
+ <td rowspan="1" colSpan="1" >-</td>
306
+
307
+ <td rowspan="1" colSpan="1" >占位符文本</td>
308
+ </tr>
309
+
310
+ <tr>
311
+ <td rowspan="1" colSpan="1" >SearchIcon</td>
312
+
313
+ <td rowspan="1" colSpan="1" >Component</td>
314
+
315
+ <td rowspan="1" colSpan="1" >-</td>
316
+
317
+ <td rowspan="1" colSpan="1" >自定义搜索图标</td>
318
+ </tr>
319
+
320
+ <tr>
321
+ <td rowspan="1" colSpan="1" >ClearIcon</td>
322
+
323
+ <td rowspan="1" colSpan="1" >Component</td>
324
+
325
+ <td rowspan="1" colSpan="1" >-</td>
326
+
327
+ <td rowspan="1" colSpan="1" >自定义清除图标</td>
328
+ </tr>
329
+
330
+ <tr>
331
+ <td rowspan="1" colSpan="1" >className</td>
332
+
333
+ <td rowspan="1" colSpan="1" >string</td>
334
+
335
+ <td rowspan="1" colSpan="1" >-</td>
336
+
337
+ <td rowspan="1" colSpan="1" >自定义样式类名</td>
338
+ </tr>
339
+
340
+ <tr>
341
+ <td rowspan="1" colSpan="1" >style</td>
342
+
343
+ <td rowspan="1" colSpan="1" >CSSProperties</td>
344
+
345
+ <td rowspan="1" colSpan="1" >-</td>
346
+
347
+ <td rowspan="1" colSpan="1" >自定义样式</td>
348
+ </tr>
349
+
350
+ <tr>
351
+ <td rowspan="1" colSpan="1" >onFocus</td>
352
+
353
+ <td rowspan="1" colSpan="1" >(e: FocusEvent) => void</td>
354
+
355
+ <td rowspan="1" colSpan="1" >-</td>
356
+
357
+ <td rowspan="1" colSpan="1" >获得焦点回调</td>
358
+ </tr>
359
+
360
+ <tr>
361
+ <td rowspan="1" colSpan="1" >onBlur</td>
362
+
363
+ <td rowspan="1" colSpan="1" >(e: FocusEvent) => void</td>
364
+
365
+ <td rowspan="1" colSpan="1" >-</td>
366
+
367
+ <td rowspan="1" colSpan="1" >失去焦点回调</td>
368
+ </tr>
369
+
370
+ <tr>
371
+ <td rowspan="1" colSpan="1" >autoFocus</td>
372
+
373
+ <td rowspan="1" colSpan="1" >boolean</td>
374
+
375
+ <td rowspan="1" colSpan="1" >false</td>
376
+
377
+ <td rowspan="1" colSpan="1" >是否自动聚焦</td>
378
+ </tr>
379
+
380
+ <tr>
381
+ <td rowspan="1" colSpan="1" >variant</td>
382
+
383
+ <td rowspan="1" colSpan="1" >VariantType</td>
384
+
385
+ <td rowspan="1" colSpan="1" >-</td>
386
+
387
+ <td rowspan="1" colSpan="1" >搜索模式</td>
388
+ </tr>
389
+ </table>
390
+
391
+
392
+ **示例**
393
+ ``` typescript
394
+ <template>
395
+ <div class="custom-search-bar">
396
+ <div class="search-bar-header">
397
+ <span class="search-icon">🔍</span>
398
+ <span class="search-title">智能搜索</span>
399
+ </div>
400
+ <div class="search-input-wrapper">
401
+ <input
402
+ type="text"
403
+ :value="value"
404
+ :placeholder="placeholder || '输入关键词开始搜索...'"
405
+ @input="handleChange"
406
+ class="enhanced-search-input"
407
+ />
408
+ <button
409
+ v-if="value"
410
+ @click="handleClear"
411
+ class="enhanced-clear-btn"
412
+ >
413
+ ✕
414
+ </button>
415
+ </div>
416
+ </div>
417
+ </template>
418
+
419
+ <script setup lang="ts">
420
+ interface SearchBarProps {
421
+ value?: string;
422
+ onChange?: (event: Event) => void;
423
+ onClear?: () => void;
424
+ placeholder?: string;
425
+ variant?: string;
426
+ }
427
+
428
+ const props = defineProps<SearchBarProps>();
429
+
430
+ const emit = defineEmits<{
431
+ change: [event: Event];
432
+ clear: [];
433
+ }>();
434
+
435
+ const handleChange = (event: Event) => {
436
+ if (props.onChange) {
437
+ props.onChange(event);
438
+ }
439
+ emit('change', event);
440
+ };
441
+
442
+ const handleClear = () => {
443
+ if (props.onClear) {
444
+ props.onClear();
445
+ }
446
+ emit('clear');
447
+ };
448
+ </script>
449
+
450
+ <style scoped>
451
+ .custom-search-bar {
452
+ display: flex;
453
+ flex-direction: column;
454
+ gap: 8px;
455
+ }
456
+
457
+ .search-bar-header {
458
+ display: flex;
459
+ align-items: center;
460
+ gap: 8px;
461
+ }
462
+
463
+ .search-icon {
464
+ font-size: 16px;
465
+ }
466
+
467
+ .search-title {
468
+ font-weight: 500;
469
+ color: #333;
470
+ }
471
+
472
+ .search-input-wrapper {
473
+ position: relative;
474
+ display: flex;
475
+ align-items: center;
476
+ }
477
+
478
+ .enhanced-search-input {
479
+ width: 100%;
480
+ padding: 8px 12px;
481
+ border: 1px solid #ddd;
482
+ border-radius: 4px;
483
+ font-size: 14px;
484
+ outline: none;
485
+ }
486
+
487
+ .enhanced-search-input:focus {
488
+ border-color: #007bff;
489
+ }
490
+
491
+ .enhanced-clear-btn {
492
+ position: absolute;
493
+ right: 8px;
494
+ background: none;
495
+ border: none;
496
+ cursor: pointer;
497
+ color: #999;
498
+ font-size: 16px;
499
+ }
500
+
501
+ .enhanced-clear-btn:hover {
502
+ color: #666;
503
+ }
504
+ </style>
505
+
506
+ ```
507
+ ``` typescript
508
+ <template>
509
+ <Search :SearchBar="CustomSearchBar" />
510
+ </template>
511
+
512
+ <script setup lang="ts">
513
+ import { Search } from '@tencentcloud/chat-uikit-vue3';
514
+ import CustomSearchBar from './CustomSearchBar.vue';
515
+ </script>
516
+
517
+ ```
518
+
519
+ 【自定义 SearchResults】
520
+
521
+ **Props**
522
+ <table>
523
+ <tr>
524
+ <td rowspan="1" colSpan="1" >属性名</td>
525
+
526
+ <td rowspan="1" colSpan="1" >类型</td>
527
+
528
+ <td rowspan="1" colSpan="1" >默认值</td>
529
+
530
+ <td rowspan="1" colSpan="1" >说明</td>
531
+ </tr>
532
+
533
+ <tr>
534
+ <td rowspan="1" colSpan="1" >results</td>
535
+
536
+ <td rowspan="1" colSpan="1" >Map<SearchType, SearchResult></td>
537
+
538
+ <td rowspan="1" colSpan="1" >-</td>
539
+
540
+ <td rowspan="1" colSpan="1" >搜索结果数据</td>
541
+ </tr>
542
+
543
+ <tr>
544
+ <td rowspan="1" colSpan="1" >isLoading</td>
545
+
546
+ <td rowspan="1" colSpan="1" >boolean</td>
547
+
548
+ <td rowspan="1" colSpan="1" >-</td>
549
+
550
+ <td rowspan="1" colSpan="1" >是否正在加载</td>
551
+ </tr>
552
+
553
+ <tr>
554
+ <td rowspan="1" colSpan="1" >error</td>
555
+
556
+ <td rowspan="1" colSpan="1" >Error \| null</td>
557
+
558
+ <td rowspan="1" colSpan="1" >-</td>
559
+
560
+ <td rowspan="1" colSpan="1" >错误信息</td>
561
+ </tr>
562
+
563
+ <tr>
564
+ <td rowspan="1" colSpan="1" >keyword</td>
565
+
566
+ <td rowspan="1" colSpan="1" >string</td>
567
+
568
+ <td rowspan="1" colSpan="1" >-</td>
569
+
570
+ <td rowspan="1" colSpan="1" >搜索关键词</td>
571
+ </tr>
572
+
573
+ <tr>
574
+ <td rowspan="1" colSpan="1" >typeLabels</td>
575
+
576
+ <td rowspan="1" colSpan="1" >Record<SearchType, string></td>
577
+
578
+ <td rowspan="1" colSpan="1" >-</td>
579
+
580
+ <td rowspan="1" colSpan="1" >搜索类型标签</td>
581
+ </tr>
582
+
583
+ <tr>
584
+ <td rowspan="1" colSpan="1" >onLoadMore</td>
585
+
586
+ <td rowspan="1" colSpan="1" >(type: SearchType) => void</td>
587
+
588
+ <td rowspan="1" colSpan="1" >-</td>
589
+
590
+ <td rowspan="1" colSpan="1" >加载更多回调</td>
591
+ </tr>
592
+
593
+ <tr>
594
+ <td rowspan="1" colSpan="1" >onResultItemClick</td>
595
+
596
+ <td rowspan="1" colSpan="1" >(data: SearchResultItemType, type: SearchType) => void</td>
597
+
598
+ <td rowspan="1" colSpan="1" >-</td>
599
+
600
+ <td rowspan="1" colSpan="1" >结果项点击回调</td>
601
+ </tr>
602
+
603
+ <tr>
604
+ <td rowspan="1" colSpan="1" >SearchResultsLoading</td>
605
+
606
+ <td rowspan="1" colSpan="1" >Component</td>
607
+
608
+ <td rowspan="1" colSpan="1" >Loading</td>
609
+
610
+ <td rowspan="1" colSpan="1" >自定义加载组件</td>
611
+ </tr>
612
+
613
+ <tr>
614
+ <td rowspan="1" colSpan="1" >SearchResultsPresearch</td>
615
+
616
+ <td rowspan="1" colSpan="1" >Component</td>
617
+
618
+ <td rowspan="1" colSpan="1" >-</td>
619
+
620
+ <td rowspan="1" colSpan="1" >搜索前占位符组件</td>
621
+ </tr>
622
+
623
+ <tr>
624
+ <td rowspan="1" colSpan="1" >SearchResultsEmpty</td>
625
+
626
+ <td rowspan="1" colSpan="1" >Component</td>
627
+
628
+ <td rowspan="1" colSpan="1" >EmptyResult</td>
629
+
630
+ <td rowspan="1" colSpan="1" >空结果占位符组件</td>
631
+ </tr>
632
+
633
+ <tr>
634
+ <td rowspan="1" colSpan="1" >SearchResultItem</td>
635
+
636
+ <td rowspan="1" colSpan="1" >Component<ResultItemProps></td>
637
+
638
+ <td rowspan="1" colSpan="1" >DefaultSearchResultsItem</td>
639
+
640
+ <td rowspan="1" colSpan="1" >自定义结果项组件</td>
641
+ </tr>
642
+
643
+ <tr>
644
+ <td rowspan="1" colSpan="1" >variant</td>
645
+
646
+ <td rowspan="1" colSpan="1" >VariantType</td>
647
+
648
+ <td rowspan="1" colSpan="1" >VariantType.STANDARD</td>
649
+
650
+ <td rowspan="1" colSpan="1" >显示模式</td>
651
+ </tr>
652
+
653
+ <tr>
654
+ <td rowspan="1" colSpan="1" >searchType</td>
655
+
656
+ <td rowspan="1" colSpan="1" >SearchType \| 'all'</td>
657
+
658
+ <td rowspan="1" colSpan="1" >'all'</td>
659
+
660
+ <td rowspan="1" colSpan="1" >当前搜索类型</td>
661
+ </tr>
662
+ </table>
663
+
664
+
665
+ **示例**
666
+ ``` typescript
667
+ <template>
668
+ <div class="custom-search-results">
669
+ <div class="search-results-header">
670
+ <span class="results-icon">📋</span>
671
+ <span class="results-title">搜索结果</span>
672
+ </div>
673
+ <div class="search-results-content">
674
+ <div v-if="!results || results.size === 0" class="no-results">
675
+ 暂无搜索结果
676
+ </div>
677
+ <div v-else class="results-list">
678
+ <div
679
+ v-for="(item, key) in results.keys()"
680
+ :key="key"
681
+ class="result-item"
682
+ >
683
+ <div class="result-group">
684
+ <div class="result-title">
685
+ {{ item }}
686
+ </div>
687
+ <ul v-if="item === SearchType.MESSAGE" class="result-description">
688
+ <li
689
+ v-for="(data, index) in results.get(item)?.resultList"
690
+ :key="index"
691
+ @click="handleResultClick(data)"
692
+ >
693
+ {{ (data as SearchCloudMessagesResultItem).conversation?.getShowName() }}
694
+ </li>
695
+ </ul>
696
+ <ul v-if="item === SearchType.USER" class="result-description">
697
+ <li
698
+ v-for="(data, index) in results.get(item)?.resultList"
699
+ :key="index"
700
+ @click="handleResultClick(data)"
701
+ >
702
+ {{ (data as SearchCloudUsersResultItem).profile.nick
703
+ || (data as SearchCloudUsersResultItem).profile.userID }}
704
+ </li>
705
+ </ul>
706
+ <ul v-if="item === SearchType.GROUP" class="result-description">
707
+ <li
708
+ v-for="(data, index) in results.get(item)?.resultList"
709
+ :key="index"
710
+ @click="handleResultClick(data)"
711
+ >
712
+ {{ (data as SearchCloudGroupsResultItem).groupInfo.name
713
+ || (data as SearchCloudGroupsResultItem).groupInfo.groupID }}
714
+ </li>
715
+ </ul>
716
+ </div>
717
+ </div>
718
+ </div>
719
+ </div>
720
+ </div>
721
+ </template>
722
+
723
+ <script setup lang="ts">
724
+ import { SearchType } from '@tencentcloud/chat-uikit-vue3';
725
+ import type {
726
+ SearchCloudGroupsResultItem,
727
+ SearchCloudMessagesResultItem,
728
+ SearchCloudUsersResultItem,
729
+ SearchResult,
730
+ SearchResultItemType,
731
+ } from '@tencentcloud/chat-uikit-vue3';
732
+
733
+ interface SearchResultsProps {
734
+ results?: Map<SearchType, SearchResult<any>>;
735
+ loading?: boolean;
736
+ keyword?: string;
737
+ searchType?: SearchType;
738
+ }
739
+
740
+ const props = defineProps<SearchResultsProps>();
741
+
742
+ const emit = defineEmits<{
743
+ 'result-item-click': [data: SearchResultItemType, type: any];
744
+ }>();
745
+
746
+ const handleResultClick = (item: SearchResultItemType) => {
747
+ emit('result-item-click', item, props.searchType || 'ALL');
748
+ };
749
+ </script>
750
+
751
+ <style scoped>
752
+ .custom-search-results {
753
+ display: flex;
754
+ flex-direction: column;
755
+ gap: 8px;
756
+ }
757
+
758
+ .search-results-header {
759
+ display: flex;
760
+ align-items: center;
761
+ gap: 8px;
762
+ }
763
+
764
+ .results-icon {
765
+ font-size: 16px;
766
+ }
767
+
768
+ .results-title {
769
+ font-weight: 500;
770
+ color: #333;
771
+ }
772
+
773
+ .search-results-content {
774
+ max-height: 400px;
775
+ overflow-y: auto;
776
+ }
777
+
778
+ .no-results {
779
+ padding: 20px;
780
+ text-align: center;
781
+ color: #999;
782
+ font-size: 14px;
783
+ }
784
+
785
+ .results-list {
786
+ display: flex;
787
+ flex-direction: column;
788
+ gap: 4px;
789
+ }
790
+
791
+ .result-item {
792
+ padding: 12px;
793
+ border: 1px solid #eee;
794
+ border-radius: 4px;
795
+ cursor: pointer;
796
+ transition: background-color 0.2s;
797
+ }
798
+
799
+ .result-item:hover {
800
+ background-color: #f5f5f5;
801
+ }
802
+
803
+ .result-content {
804
+ display: flex;
805
+ flex-direction: column;
806
+ gap: 4px;
807
+ }
808
+
809
+ .result-title {
810
+ font-weight: 500;
811
+ color: #333;
812
+ font-size: 14px;
813
+ }
814
+
815
+ .result-description {
816
+ color: #666;
817
+ font-size: 12px;
818
+ line-height: 1.4;
819
+ }
820
+ </style>
821
+
822
+ ```
823
+ ``` typescript
824
+ <template>
825
+ <Search :SearchResults="CustomSearchResults" />
826
+ </template>
827
+
828
+ <script setup lang="ts">
829
+ import { Search } from '@tencentcloud/chat-uikit-vue3';
830
+ import CustomSearchResults from './CustomSearchResults.vue';
831
+ </script>
832
+ ```
833
+
834
+ 【自定义 SearchAdvanced】
835
+
836
+ **Props**
837
+ <table>
838
+ <tr>
839
+ <td rowspan="1" colSpan="1" >属性名</td>
840
+
841
+ <td rowspan="1" colSpan="1" >类型</td>
842
+
843
+ <td rowspan="1" colSpan="1" >默认值</td>
844
+
845
+ <td rowspan="1" colSpan="1" >说明</td>
846
+ </tr>
847
+
848
+ <tr>
849
+ <td rowspan="1" colSpan="1" >variant</td>
850
+
851
+ <td rowspan="1" colSpan="1" >VariantType</td>
852
+
853
+ <td rowspan="1" colSpan="1" >-</td>
854
+
855
+ <td rowspan="1" colSpan="1" >显示模式</td>
856
+ </tr>
857
+
858
+ <tr>
859
+ <td rowspan="1" colSpan="1" >searchType</td>
860
+
861
+ <td rowspan="1" colSpan="1" >SearchTabType</td>
862
+
863
+ <td rowspan="1" colSpan="1" >-</td>
864
+
865
+ <td rowspan="1" colSpan="1" >当前搜索类型</td>
866
+ </tr>
867
+
868
+ <tr>
869
+ <td rowspan="1" colSpan="1" >advancedParams</td>
870
+
871
+ <td rowspan="1" colSpan="1" >Map<SearchType, SearchParamsMap[SearchType]></td>
872
+
873
+ <td rowspan="1" colSpan="1" >-</td>
874
+
875
+ <td rowspan="1" colSpan="1" >高级搜索参数</td>
876
+ </tr>
877
+
878
+ <tr>
879
+ <td rowspan="1" colSpan="1" >onAdvancedParamsChange</td>
880
+
881
+ <td rowspan="1" colSpan="1" >(type: SearchType, params: SearchParamsMap[SearchType]) => void</td>
882
+
883
+ <td rowspan="1" colSpan="1" >-</td>
884
+
885
+ <td rowspan="1" colSpan="1" >参数变化回调</td>
886
+ </tr>
887
+ </table>
888
+
889
+
890
+ **示例**
891
+ ``` typescript
892
+ <template>
893
+ <div class="custom-search-advanced">
894
+ <div class="search-advanced-header">
895
+ <span class="advanced-icon">⚙️</span>
896
+ <span class="advanced-title">高级搜索</span>
897
+ </div>
898
+ <div class="search-advanced-content">
899
+ <div class="search-type-section">
900
+ <div class="section-title">
901
+ 搜索类型
902
+ </div>
903
+ <div class="search-type-options">
904
+ <label
905
+ v-for="type in searchTypes"
906
+ :key="type.value"
907
+ class="type-option"
908
+ >
909
+ <input
910
+ type="radio"
911
+ :value="type.value"
912
+ :checked="searchType === type.value"
913
+ @change="handleSearchTypeChange(type.value as SearchType)"
914
+ >
915
+ <span class="type-label">{{ type.label }}</span>
916
+ </label>
917
+ </div>
918
+ </div>
919
+ </div>
920
+ </div>
921
+ </template>
922
+
923
+ <script setup lang="ts">
924
+ import { ref } from 'vue';
925
+ import { SearchType, useSearchState } from '@tencentcloud/chat-uikit-vue3';
926
+ import type { VariantType } from '@tencentcloud/chat-uikit-vue3';
927
+
928
+ interface CustomSearchAdvancedProps {
929
+ variant?: VariantType;
930
+ searchType?: SearchType;
931
+ }
932
+
933
+ const props = defineProps<CustomSearchAdvancedProps>();
934
+ const { setSelectedType } = useSearchState();
935
+
936
+ const emit = defineEmits<{
937
+ 'search-type-change': [type: SearchType | 'all'];
938
+ }>();
939
+
940
+ const searchTypes = [
941
+ { value: 'all', label: '全部' },
942
+ { value: SearchType.MESSAGE, label: '消息' },
943
+ { value: SearchType.USER, label: '用户' },
944
+ { value: SearchType.GROUP, label: '群组' },
945
+ ];
946
+
947
+ const searchType = ref<SearchType | 'all'>(props.searchType || 'all');
948
+
949
+ const handleSearchTypeChange = (type: SearchType) => {
950
+ searchType.value = type;
951
+ setSelectedType(type);
952
+ emit('search-type-change', type);
953
+ };
954
+ </script>
955
+
956
+ <style scoped>
957
+ .custom-search-advanced {
958
+ display: flex;
959
+ flex-direction: column;
960
+ gap: 16px;
961
+ padding: 16px;
962
+ border: 1px solid #eee;
963
+ border-radius: 8px;
964
+ background-color: #fff;
965
+ }
966
+
967
+ .search-advanced-header {
968
+ display: flex;
969
+ align-items: center;
970
+ gap: 8px;
971
+ padding-bottom: 12px;
972
+ border-bottom: 1px solid #f0f0f0;
973
+ }
974
+
975
+ .advanced-icon {
976
+ font-size: 16px;
977
+ }
978
+
979
+ .advanced-title {
980
+ font-weight: 500;
981
+ color: #333;
982
+ font-size: 16px;
983
+ }
984
+
985
+ .search-advanced-content {
986
+ display: flex;
987
+ flex-direction: column;
988
+ gap: 16px;
989
+ }
990
+
991
+ .section-title {
992
+ font-weight: 500;
993
+ color: #333;
994
+ font-size: 14px;
995
+ margin-bottom: 8px;
996
+ }
997
+
998
+ .search-type-options {
999
+ display: flex;
1000
+ flex-wrap: wrap;
1001
+ gap: 12px;
1002
+ }
1003
+
1004
+ .type-option {
1005
+ display: flex;
1006
+ align-items: center;
1007
+ gap: 6px;
1008
+ cursor: pointer;
1009
+ }
1010
+
1011
+ .type-option input[type="radio"] {
1012
+ margin: 0;
1013
+ }
1014
+
1015
+ .type-label {
1016
+ font-size: 14px;
1017
+ color: #666;
1018
+ }
1019
+ </style>
1020
+
1021
+ ```
1022
+ ``` typescript
1023
+ <template>
1024
+ <Search :SearchAdvanced="CustomSearchAdvanced" />
1025
+ </template>
1026
+
1027
+ <script setup lang="ts">
1028
+ import { Search } from '@tencentcloud/chat-uikit-vue3';
1029
+ import CustomSearchAdvanced from './CustomSearchAdvanced.vue';
1030
+ </script>
1031
+ ```
1032
+
1033
+ 【自定义 SearchResultItem】
1034
+
1035
+ **Props**
1036
+ <table>
1037
+ <tr>
1038
+ <td rowspan="1" colSpan="1" >属性名</td>
1039
+
1040
+ <td rowspan="1" colSpan="1" >类型</td>
1041
+
1042
+ <td rowspan="1" colSpan="1" >默认值</td>
1043
+
1044
+ <td rowspan="1" colSpan="1" >说明</td>
1045
+ </tr>
1046
+
1047
+ <tr>
1048
+ <td rowspan="1" colSpan="1" >data</td>
1049
+
1050
+ <td rowspan="1" colSpan="1" >SearchResultItem</td>
1051
+
1052
+ <td rowspan="1" colSpan="1" >-</td>
1053
+
1054
+ <td rowspan="1" colSpan="1" >搜索结果数据</td>
1055
+ </tr>
1056
+
1057
+ <tr>
1058
+ <td rowspan="1" colSpan="1" >type</td>
1059
+
1060
+ <td rowspan="1" colSpan="1" >SearchType</td>
1061
+
1062
+ <td rowspan="1" colSpan="1" >-</td>
1063
+
1064
+ <td rowspan="1" colSpan="1" >搜索结果类型</td>
1065
+ </tr>
1066
+
1067
+ <tr>
1068
+ <td rowspan="1" colSpan="1" >keyword</td>
1069
+
1070
+ <td rowspan="1" colSpan="1" >string</td>
1071
+
1072
+ <td rowspan="1" colSpan="1" >-</td>
1073
+
1074
+ <td rowspan="1" colSpan="1" >搜索关键词</td>
1075
+ </tr>
1076
+
1077
+ <tr>
1078
+ <td rowspan="1" colSpan="1" >onClick</td>
1079
+
1080
+ <td rowspan="1" colSpan="1" >(data: SearchResultItem, type: SearchType) => void</td>
1081
+
1082
+ <td rowspan="1" colSpan="1" >-</td>
1083
+
1084
+ <td rowspan="1" colSpan="1" >点击回调</td>
1085
+ </tr>
1086
+
1087
+ <tr>
1088
+ <td rowspan="1" colSpan="1" >className</td>
1089
+
1090
+ <td rowspan="1" colSpan="1" >string</td>
1091
+
1092
+ <td rowspan="1" colSpan="1" >-</td>
1093
+
1094
+ <td rowspan="1" colSpan="1" >自定义样式类名</td>
1095
+ </tr>
1096
+ </table>
1097
+
1098
+
1099
+ **示例**
1100
+ ``` java
1101
+ <template>
1102
+ <div class="custom-search-item">
1103
+ <div
1104
+ v-if="type === SearchType.USER"
1105
+ class="user-item"
1106
+ @click="handleClick"
1107
+ >
1108
+ <div class="user-avatar">
1109
+ <img :src="data.profile.avatar" :alt="data.profile.nick" />
1110
+ </div>
1111
+ <div class="user-info">
1112
+ <div class="user-name">{{ data.profile.nick }}</div>
1113
+ <div class="user-id">{{ data.profile.userID }}</div>
1114
+ </div>
1115
+ </div>
1116
+
1117
+ <div
1118
+ v-else-if="type === SearchType.GROUP"
1119
+ class="group-item"
1120
+ @click="handleClick"
1121
+ >
1122
+ <div class="group-avatar">👥</div>
1123
+ <div class="group-info">
1124
+ <div class="group-name">{{ data.groupInfo.name }}</div>
1125
+ <div class="group-id">{{ data.groupInfo.groupID }}</div>
1126
+ </div>
1127
+ </div>
1128
+
1129
+ <div
1130
+ v-else-if="type === SearchType.MESSAGE"
1131
+ class="message-item"
1132
+ @click="handleClick"
1133
+ >
1134
+ <div class="message-content">{{ data.conversation.getShowName() }}</div>
1135
+ <div class="message-num">{{ data.messageCount }}</div>
1136
+ </div>
1137
+ </div>
1138
+ </template>
1139
+
1140
+ <script setup lang="ts">
1141
+ import { SearchType } from '@tencentcloud/chat-uikit-vue3';
1142
+ import type { SearchResultItemType } from '@tencentcloud/chat-uikit-vue3';
1143
+
1144
+ interface CustomSearchItemProps {
1145
+ data: SearchResultItemType;
1146
+ type?: SearchType;
1147
+ onClick?: (data: SearchResultItemType, type: SearchType) => void;
1148
+ }
1149
+
1150
+ const props = defineProps<CustomSearchItemProps>();
1151
+
1152
+ console.warn('CustomSearchItem', props);
1153
+
1154
+ const handleClick = () => {
1155
+ if (props.onClick && props.type) {
1156
+ props.onClick(props.data, props.type);
1157
+ }
1158
+ };
1159
+
1160
+ const formatTime = (timestamp: number) => {
1161
+ return new Date(timestamp).toLocaleString();
1162
+ };
1163
+ </script>
1164
+
1165
+ <style scoped>
1166
+ .custom-search-item {
1167
+ cursor: pointer;
1168
+ padding: 12px;
1169
+ border-bottom: 1px solid #f0f0f0;
1170
+ transition: background-color 0.2s;
1171
+ }
1172
+
1173
+ .custom-search-item:hover {
1174
+ background-color: #f5f5f5;
1175
+ }
1176
+
1177
+ .user-item,
1178
+ .group-item,
1179
+ .message-item {
1180
+ display: flex;
1181
+ align-items: center;
1182
+ gap: 12px;
1183
+ }
1184
+
1185
+ .user-avatar img {
1186
+ width: 40px;
1187
+ height: 40px;
1188
+ border-radius: 50%;
1189
+ object-fit: cover;
1190
+ }
1191
+
1192
+ .group-avatar {
1193
+ width: 40px;
1194
+ height: 40px;
1195
+ border-radius: 8px;
1196
+ background-color: #e9ecef;
1197
+ display: flex;
1198
+ align-items: center;
1199
+ justify-content: center;
1200
+ font-size: 18px;
1201
+ }
1202
+
1203
+ .user-info,
1204
+ .group-info {
1205
+ flex: 1;
1206
+ }
1207
+
1208
+ .user-name,
1209
+ .group-name {
1210
+ font-weight: 500;
1211
+ color: #333;
1212
+ font-size: 14px;
1213
+ margin-bottom: 4px;
1214
+ }
1215
+
1216
+ .user-id,
1217
+ .group-id {
1218
+ color: #666;
1219
+ font-size: 12px;
1220
+ }
1221
+
1222
+ .message-content {
1223
+ flex: 1;
1224
+ color: #333;
1225
+ font-size: 14px;
1226
+ line-height: 1.4;
1227
+ }
1228
+
1229
+ .message-num {
1230
+ color: #666;
1231
+ font-size: 12px;
1232
+ white-space: nowrap;
1233
+ }
1234
+ </style>
1235
+ ```
1236
+ ``` typescript
1237
+ <template>
1238
+ <Search :SearchResultItem="CustomSearchItem" />
1239
+ </template>
1240
+
1241
+ <script setup lang="ts">
1242
+ import { Search } from '@tencentcloud/chat-uikit-vue3';
1243
+ import CustomSearchItem from './CustomSearchItem.vue';
1244
+ </script>
1245
+ ```
1246
+
1247
+ 【自定义占位符】
1248
+
1249
+ **Props**
1250
+ <table>
1251
+ <tr>
1252
+ <td rowspan="1" colSpan="1" >属性名</td>
1253
+
1254
+ <td rowspan="1" colSpan="1" >类型</td>
1255
+
1256
+ <td rowspan="1" colSpan="1" >默认值</td>
1257
+
1258
+ <td rowspan="1" colSpan="1" >说明</td>
1259
+ </tr>
1260
+
1261
+ <tr>
1262
+ <td rowspan="1" colSpan="1" >SearchResultsPresearch</td>
1263
+
1264
+ <td rowspan="1" colSpan="1" >Component</td>
1265
+
1266
+ <td rowspan="1" colSpan="1" >-</td>
1267
+
1268
+ <td rowspan="1" colSpan="1" >搜索前占位符组件</td>
1269
+ </tr>
1270
+
1271
+ <tr>
1272
+ <td rowspan="1" colSpan="1" >SearchResultsLoading</td>
1273
+
1274
+ <td rowspan="1" colSpan="1" >Component</td>
1275
+
1276
+ <td rowspan="1" colSpan="1" >-</td>
1277
+
1278
+ <td rowspan="1" colSpan="1" >加载中占位符组件</td>
1279
+ </tr>
1280
+
1281
+ <tr>
1282
+ <td rowspan="1" colSpan="1" >SearchResultsEmpty</td>
1283
+
1284
+ <td rowspan="1" colSpan="1" >Component</td>
1285
+
1286
+ <td rowspan="1" colSpan="1" >-</td>
1287
+
1288
+ <td rowspan="1" colSpan="1" >空结果占位符组件</td>
1289
+ </tr>
1290
+ </table>
1291
+
1292
+
1293
+ **示例**
1294
+ ``` typescript
1295
+ <template>
1296
+ <Search
1297
+ :search-results-presearch="PresearchComponent"
1298
+ :search-results-loading="LoadingComponent"
1299
+ :search-results-empty="EmptyComponent"
1300
+ />
1301
+ </template>
1302
+
1303
+ <script setup lang="ts">
1304
+ import { defineComponent, h } from 'vue';
1305
+ import { Search } from '@tencentcloud/chat-uikit-vue3';
1306
+
1307
+ const PresearchComponent = defineComponent({
1308
+ name: 'PresearchComponent',
1309
+ setup() {
1310
+ return () => h('div', { class: 'presearch-placeholder' }, [
1311
+ h('div', { class: 'placeholder-icon' }, '🔍'),
1312
+ h('div', { class: 'placeholder-text' }, '输入关键词开始搜索')
1313
+ ]);
1314
+ }
1315
+ });
1316
+
1317
+ const LoadingComponent = defineComponent({
1318
+ name: 'LoadingComponent',
1319
+ setup() {
1320
+ return () => h('div', { class: 'loading-placeholder' }, [
1321
+ h('div', { class: 'loading-spinner' }),
1322
+ h('div', { class: 'loading-text' }, '搜索中...')
1323
+ ]);
1324
+ }
1325
+ });
1326
+
1327
+ const EmptyComponent = defineComponent({
1328
+ name: 'EmptyComponent',
1329
+ setup() {
1330
+ return () => h('div', { class: 'empty-placeholder' }, [
1331
+ h('div', { class: 'empty-icon' }, '😔'),
1332
+ h('div', { class: 'empty-text' }, '未找到相关结果'),
1333
+ h('div', { class: 'empty-hint' }, '尝试使用其他关键词搜索')
1334
+ ]);
1335
+ }
1336
+ });
1337
+ </script>
1338
+
1339
+ <style scoped>
1340
+ .presearch-placeholder,
1341
+ .loading-placeholder,
1342
+ .empty-placeholder {
1343
+ display: flex;
1344
+ flex-direction: column;
1345
+ align-items: center;
1346
+ justify-content: center;
1347
+ padding: 60px 20px;
1348
+ color: #999;
1349
+ }
1350
+
1351
+ .placeholder-icon,
1352
+ .empty-icon {
1353
+ font-size: 48px;
1354
+ margin-bottom: 16px;
1355
+ }
1356
+
1357
+ .loading-spinner {
1358
+ width: 32px;
1359
+ height: 32px;
1360
+ border: 3px solid #f3f3f3;
1361
+ border-top: 3px solid #1890ff;
1362
+ border-radius: 50%;
1363
+ animation: spin 1s linear infinite;
1364
+ margin-bottom: 16px;
1365
+ }
1366
+
1367
+ @keyframes spin {
1368
+ 0% { transform: rotate(0deg); }
1369
+ 100% { transform: rotate(360deg); }
1370
+ }
1371
+
1372
+ .placeholder-text,
1373
+ .loading-text,
1374
+ .empty-text {
1375
+ font-size: 16px;
1376
+ margin-bottom: 8px;
1377
+ }
1378
+
1379
+ .empty-hint {
1380
+ font-size: 14px;
1381
+ color: #bbb;
1382
+ }
1383
+ </style>
1384
+ ```