add searchable
This commit is contained in:
@ -2,6 +2,7 @@
|
||||
import config from "../../config/index";
|
||||
import { JournalPage, JournalPageType } from "../../types/Journal";
|
||||
import Time from "../../utils/Time";
|
||||
import Toolkit from "../../utils/Toolkit";
|
||||
|
||||
export type JournalListItem = {
|
||||
id: number;
|
||||
@ -16,9 +17,15 @@ interface JournalListData {
|
||||
isFetching: boolean;
|
||||
isFinished: boolean;
|
||||
page: JournalPage;
|
||||
searchValue: string;
|
||||
}
|
||||
|
||||
Component({
|
||||
// 组件实例类型扩展
|
||||
interface ComponentInstance {
|
||||
debouncedSearch?: ((keyword: string) => void) & { cancel(): void };
|
||||
}
|
||||
|
||||
Component<JournalListData, {}, {}, ComponentInstance>({
|
||||
options: {
|
||||
styleIsolation: 'apply-shared'
|
||||
},
|
||||
@ -34,6 +41,14 @@ Component({
|
||||
selectedId: {
|
||||
type: Number,
|
||||
value: undefined
|
||||
},
|
||||
searchable: {
|
||||
type: Boolean,
|
||||
value: false // 是否显示搜索框
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
value: 'select' // 'select' 选择模式 或 'navigate' 跳转模式
|
||||
}
|
||||
},
|
||||
data: <JournalListData>{
|
||||
@ -44,27 +59,63 @@ Component({
|
||||
index: 0,
|
||||
size: 16,
|
||||
type: JournalPageType.PREVIEW
|
||||
},
|
||||
searchValue: ""
|
||||
},
|
||||
lifetimes: {
|
||||
ready() {
|
||||
// 创建防抖搜索函数
|
||||
this.debouncedSearch = Toolkit.debounce(
|
||||
(keyword: string) => {
|
||||
this.resetAndSearch(keyword);
|
||||
},
|
||||
false, // 不立即执行,等待输入停止
|
||||
400 // 400ms 延迟
|
||||
);
|
||||
// 组件加载时就获取数据
|
||||
this.fetch();
|
||||
},
|
||||
detached() {
|
||||
// 组件销毁时取消防抖
|
||||
if (this.debouncedSearch) {
|
||||
this.debouncedSearch.cancel();
|
||||
}
|
||||
}
|
||||
},
|
||||
observers: {
|
||||
'visible': function(visible: boolean) {
|
||||
// visible 从 false 变为 true 时,如果还没有数据则加载
|
||||
if (visible && this.data.list.length === 0) {
|
||||
this.fetch();
|
||||
}
|
||||
},
|
||||
'type': function() {
|
||||
this.resetPage();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
resetPage() {
|
||||
const likeExample = this.data.searchValue ? {
|
||||
idea: this.data.searchValue,
|
||||
location: this.data.searchValue
|
||||
} : undefined;
|
||||
|
||||
const equalsExample = this.properties.type ? {
|
||||
type: this.properties.type
|
||||
} : undefined;
|
||||
|
||||
this.setData({
|
||||
page: {
|
||||
index: 0,
|
||||
size: 16,
|
||||
type: JournalPageType.PREVIEW
|
||||
type: JournalPageType.PREVIEW,
|
||||
equalsExample,
|
||||
likeExample
|
||||
},
|
||||
list: [],
|
||||
isFinished: false
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
fetch() {
|
||||
if (this.data.isFetching || this.data.isFinished) {
|
||||
return;
|
||||
@ -88,7 +139,7 @@ Component({
|
||||
const firstThumb = journal.items.find((item: any) => item.attachType === "THUMB");
|
||||
return {
|
||||
id: journal.id,
|
||||
date: Time.toPassedDateTime(journal.createdAt),
|
||||
date: Time.toPassedDate(journal.createdAt),
|
||||
idea: journal.idea,
|
||||
location: journal.location,
|
||||
thumbUrl: firstThumb ? `${config.url}/attachment/read/${firstThumb.mongoId}` : undefined
|
||||
@ -108,9 +159,70 @@ Component({
|
||||
}
|
||||
});
|
||||
},
|
||||
onSearchChange(e: WechatMiniprogram.CustomEvent) {
|
||||
const value = e.detail.value.trim();
|
||||
this.setData({ searchValue: value });
|
||||
// 如果是清空操作,不使用防抖(clear 事件会处理)
|
||||
if (value === "" && this.debouncedSearch) {
|
||||
this.debouncedSearch.cancel();
|
||||
return;
|
||||
}
|
||||
// 使用防抖自动搜索
|
||||
if (this.debouncedSearch) {
|
||||
this.debouncedSearch(value);
|
||||
}
|
||||
},
|
||||
onSearchSubmit(e: WechatMiniprogram.CustomEvent) {
|
||||
const value = e.detail.value.trim();
|
||||
// 立即搜索,取消防抖
|
||||
if (this.debouncedSearch) {
|
||||
this.debouncedSearch.cancel();
|
||||
}
|
||||
this.resetAndSearch(value);
|
||||
},
|
||||
onSearchClear() {
|
||||
// 取消防抖,立即搜索
|
||||
if (this.debouncedSearch) {
|
||||
this.debouncedSearch.cancel();
|
||||
}
|
||||
this.resetAndSearch("");
|
||||
},
|
||||
resetAndSearch(keyword: string) {
|
||||
const likeExample = keyword ? {
|
||||
idea: keyword,
|
||||
location: keyword
|
||||
} : undefined;
|
||||
|
||||
const equalsExample = this.properties.type ? {
|
||||
type: this.properties.type
|
||||
} : undefined;
|
||||
|
||||
this.setData({
|
||||
searchValue: keyword,
|
||||
list: [],
|
||||
page: {
|
||||
index: 0,
|
||||
size: 16,
|
||||
type: JournalPageType.PREVIEW,
|
||||
equalsExample,
|
||||
likeExample
|
||||
},
|
||||
isFetching: false,
|
||||
isFinished: false
|
||||
}, () => {
|
||||
// 无论是否有搜索词,都重新获取列表
|
||||
this.fetch();
|
||||
});
|
||||
},
|
||||
onSelectItem(e: WechatMiniprogram.BaseEvent) {
|
||||
const { id } = e.currentTarget.dataset;
|
||||
this.triggerEvent('select', { id });
|
||||
if (this.properties.mode === 'navigate') {
|
||||
// 跳转模式:触发 navigate 事件
|
||||
this.triggerEvent('navigate', { id });
|
||||
} else {
|
||||
// 选择模式:触发 select 事件
|
||||
this.triggerEvent('select', { id });
|
||||
}
|
||||
},
|
||||
onScrollToLower() {
|
||||
this.fetch();
|
||||
|
||||
Reference in New Issue
Block a user