// pages/wiki/index.js import { MOCK_WIKI } from '../../utils/mockData'; Page({ data: { // Data Source (effectively the backend result) filteredSourceList: [], // Display Data (rendered list) displayedList: [], // Filter State searchQuery: '', activeCategory: '全部', // Pagination State page: 1, pageSize: 5, isLoading: false, hasMore: true, // Modal State showIdentifyModal: false }, onLoad() { // Initial Load this.filterList(); }, onShow() { if (typeof this.getTabBar === 'function' && this.getTabBar()) { this.getTabBar().setData({ selected: 3 }); } }, // Search Input Handler onSearchInput(e) { this.setData({ searchQuery: e.detail.value }, () => { this.filterList(); }); }, // Category Filter Handler setCategory(e) { this.setData({ activeCategory: e.currentTarget.dataset.cat }, () => { this.filterList(); }); }, /** * Simulates "Backend" Search & Filtering * Resets pagination and prepares the filtered data source. */ filterList() { const { searchQuery, activeCategory } = this.data; let result = MOCK_WIKI; // Filter by Search Query if (searchQuery) { const q = searchQuery.toLowerCase(); result = result.filter(item => item.name.toLowerCase().includes(q) || item.scientificName.toLowerCase().includes(q) ); } // Filter by Category if (activeCategory !== '全部') { result = result.filter(item => item.category.includes(activeCategory)); } this.setData({ filteredSourceList: result, displayedList: [], page: 1, hasMore: true }, () => { this.loadMoreData(); }); }, /** * Simulates "Backend" Pagination * Appends the next page of data from filteredSourceList to displayedList. * key-value data path update is used for performance optimization. */ loadMoreData() { const { isLoading, hasMore, page, pageSize, filteredSourceList, displayedList } = this.data; if (isLoading || !hasMore) return; this.setData({ isLoading: true }); // Simulate Network Delay setTimeout(() => { const startIndex = (page - 1) * pageSize; const endIndex = startIndex + pageSize; const newItems = filteredSourceList.slice(startIndex, endIndex); const isLastPage = endIndex >= filteredSourceList.length; if (newItems.length > 0) { // Performance Optimization: Use data path to append items // Instead of setData({ displayedList: [...old, ...new] }) const updateData = {}; const currentLen = displayedList.length; newItems.forEach((item, index) => { updateData[`displayedList[${currentLen + index}]`] = item; }); updateData['page'] = page + 1; updateData['hasMore'] = !isLastPage; updateData['isLoading'] = false; this.setData(updateData); } else { this.setData({ hasMore: false, isLoading: false }); } }, 500); }, // Infinite Scroll Handler onReachBottom() { this.loadMoreData(); }, goToDetail(e) { const item = e.currentTarget.dataset.item; wx.navigateTo({ url: `/pages/wiki/detail/index?id=${item.id}` }); }, openIdentifyModal() { this.setData({ showIdentifyModal: true }); }, onPopupVisibleChange(e) { this.setData({ showIdentifyModal: e.detail.visible }); }, closeIdentifyModal() { this.setData({ showIdentifyModal: false }); } })