import { query } from '@/modules/query'; import { QueryMark, Mark } from '@/query/query-mark/query-mark'; import { useEffect, useRef, useState, useCallback } from 'react'; import { Tooltip } from '@/components/a/tooltip'; export const queryMark = new QueryMark({ query: query, markType: 'md' }); import Fuse from 'fuse.js'; import { debounce } from 'lodash-es'; import { SquareArrowOutUpRight } from 'lucide-react'; export const App = () => { const [list, setList] = useState([]); const [searchTerm, setSearchTerm] = useState(''); const [searchResults, setSearchResults] = useState([]); const fuseRef = useRef>(null); // 实际执行搜索的函数 const performSearch = (term: string) => { if (!term.trim()) { setSearchResults([]); return; } if (fuseRef.current) { const results = fuseRef.current.search(term); setSearchResults(results.map((result) => result.item)); } }; // 使用 useRef 和 useCallback 创建防抖搜索函数,确保它在组件生命周期中只创建一次 const debouncedSearchRef = useRef( debounce((term: string) => { performSearch(term); }, 1000), // 300毫秒的防抖延迟 ); useEffect(() => { init(); // 组件卸载时取消待执行的防抖函数 return () => { debouncedSearchRef.current.cancel(); }; }, []); const init = async () => { const res = await queryMark.getMarkList(); if (res.code === 200) { const list = res.data?.list || []; setList(list!); const fuse = new Fuse(list, { keys: ['title', 'description', 'tags', 'summary'], }); fuseRef.current = fuse; const result = fuse.search('苏生不惑的博客'); console.log(result); } }; const handleSearch = (term: string) => { setSearchTerm(term); // 立即更新输入框的值 debouncedSearchRef.current(term); // 使用防抖函数进行搜索 }; const onOpen = (item: Mark) => { const link = item.link; window.open(link); }; // 确定要显示的列表:有搜索内容时显示搜索结果,否则显示全部 const displayList = searchTerm.trim() ? searchResults : list; return (
handleSearch(e.target.value)} placeholder='搜索书签...' className='w-full p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-300' />
{displayList.length === 0 && searchTerm.trim() ? (
没有找到匹配的结果
) : ( displayList.map((item) => { return (

{item.title || '-'} onOpen(item)} />

{item.summary}

{item.tags.map((tag, index) => ( {tag} ))}
); }) )}
); };