diff --git a/src/components/Search.tsx b/src/components/Search.tsx index 77fc16b..747b83b 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -3,7 +3,8 @@ import { SearchIcon } from 'assets/svg'; import React, { ChangeEvent, useEffect, useState } from 'react'; import { http, truncateString } from 'utils'; -import { debounce } from 'lodash-es'; // 导入 debounce 方法 +import { debounce } from 'lodash-es'; +import { useNavigate } from 'react-router-dom'; // 导入 debounce 方法 export type SearchInputProps = { placeholder?: string; // 输入框的占位符文本 @@ -68,6 +69,7 @@ const SearchInput: React.FC = ({ className = '', style = {}, }) => { + const navigate = useNavigate(); const [suggestions, setSuggestions] = useState>([]); const [books, setBooks] = useState>([]); const [authors, setAuthors] = useState>([]); @@ -102,7 +104,6 @@ const SearchInput: React.FC = ({ }; useEffect(() => { - console.log(inputValue, 'inputValue'); const debouncedFetchSearch = debounce(() => { if (inputValue) { fetchSearchResults(inputValue); @@ -137,11 +138,23 @@ const SearchInput: React.FC = ({ placeholder={currentPlaceholder || placeholder} onChange={handleInputChange} // 使用防抖后的函数 onFocus={() => setShowSuggestions(true)} - onBlur={() => setShowSuggestions(false)} + onBlur={() => + setTimeout(() => { + setShowSuggestions(false); + }, 500) + } value={inputValue} style={{ width: '100%' }} // 输入框宽度100% /> - +
{ + e.preventDefault(); + console.log(1111); + }} + > + +
{showSuggestions && ( = ({ suggestions={suggestions} books={books} authors={authors} - setInputValue={(newValue: string) => setInputValue(newValue)} + setInputValue={(newValue: string) => { + setInputValue(newValue); + newValue && navigate(`search?keyword=${decodeURIComponent(newValue)}`); + setShowSuggestions(false); + }} /> )} diff --git a/src/utils/string.ts b/src/utils/string.ts index 09c6257..3b16531 100644 --- a/src/utils/string.ts +++ b/src/utils/string.ts @@ -11,7 +11,7 @@ export const truncateString = ( maxLength: number = 12, trailing: string = '...' ): string => { - if (str.length > maxLength) { + if (str?.length > maxLength) { return str.substring(0, maxLength - trailing.length) + trailing; } else { return str; diff --git a/src/views/SearchView.tsx b/src/views/SearchView.tsx index 776797c..062704d 100644 --- a/src/views/SearchView.tsx +++ b/src/views/SearchView.tsx @@ -1,8 +1,9 @@ -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { http } from '../utils/request'; import { uuid } from 'zhuba-tools'; import { Author } from 'assets/svg'; import { COVER_BASE_URL } from 'common/const'; +import { useLocation } from 'react-router-dom'; export interface SearchBookData { datas?: Datas; @@ -86,20 +87,27 @@ export interface RecDataList { } const SearchPage = () => { + const location = useLocation(); + const queryParams = new URLSearchParams(location.search); + const initialKeyword = queryParams.get('keyword') || ''; // 从路由参数获取初始值 const [searchResults, setSearchResults] = useState([]); const [loading, setLoading] = useState(false); + const [inputValue, setInputValue] = useState(initialKeyword); // 新增状态管理输入框值 - const handleSearch = async (e: React.FormEvent) => { - e.preventDefault(); - const formData = new FormData(e.currentTarget); - const searchTerm = formData.get('search') as string; + useEffect(() => { + setInputValue(initialKeyword); // 初始加载时更新输入框值 + }, [initialKeyword]); - if (!searchTerm.trim()) return; + useEffect(() => { + if (initialKeyword) { + fetchData(initialKeyword); // 值变化时请求数据 + } + }, [initialKeyword]); - setLoading(true); + const fetchData = async (keyword: string) => { try { const response = await http.get( - `/search?keyword=${encodeURIComponent(searchTerm)}` + `/search?keyword=${encodeURIComponent(keyword)}` ); console.log(' [ response ]-32-「views/SearchView.tsx」 ', response); setSearchResults(response.datas?.list || []); @@ -111,41 +119,58 @@ const SearchPage = () => { } }; + const handleSearch = async (e?: React.FormEvent) => { + e && e?.preventDefault(); + if (inputValue.trim()) { + setLoading(true); + fetchData(inputValue); // 点击搜索按钮时请求数据 + } + }; + return ( -
+
setInputValue(e.target.value)} + onKeyDown={(e) => { + if (e.key === 'Enter') { + handleSearch(); + } + }} /> -
- {loading ? ( -

正在搜索...

- ) : searchResults && searchResults?.length > 0 ? ( +

正在搜索...

+ ) : searchResults && searchResults.length > 0 ? (
{searchResults.map((result) => (
{result.name}

-

- {result.authorName} | {result.catePName} | {result.totalWord}字 +

+ | + {result.catePName} | {result.totalWord}字

{ href={`/directory?id=${result.bookId}`} className="text-blue-600 hover:underline mr-4 cursor-pointer" > - 查看详情 + 目录 - 最新章节:{result.chapterName} + 最新:{result.chapterName}

-

{result.authorName}

+