Open AymanElarian opened 4 years ago
@AymanElarian most likely it is a matter of activeDevices
binding, if you want to achieve good performance in vue for such binding on lists, then do the Mobx
trick with limited reactivity by wrapping the reactive value in a function.
Something like this I do with composition-api
.
In the list component create "reactive data non-reactive getter" for each item: props: {getValue: (item) => searchResultItem(item, selectedSetIds)}
In the component of a list item: render() {const v = props.getValue(props.item); return <el-checkbox {... v} />}
Then, when updating the checkbox, the entire collection will not be updated, but only 1 element.
When linked to activeDevices
, 1 checkbox will cause all checkboxes to be updated due to reactivity.
I don’t know how to do this without composition-api
, but I think you will find a solution.
I hope I understood your problem correctly, I do not use this library yet, but the situation seemed familiar to me, good luck.
function searchResultItem(
item: any,
selectedSetIds: SelectionMediator<number, string>
) {
const propsSearchResultItem = reactive<SearchResultItemState["props"]>({
...mapItemToSearchResult(item),
checked: selectedSetIds.has(item.id)
});
function handle(isSelected: boolean) {
propsSearchResultItem.checked = isSelected;
}
selectedSetIds.on(item.id, handle);
return {
value: {
props: propsSearchResultItem,
on: {
change: (checked: boolean) => {
selectedSetIds.change(item.id);
}
}
}
};
}
import { IsSelectedTuple, itemTogglerFor } from "@/utils/itemTogglerFor";
import { reactive, watch } from "@vue/composition-api";
export type HandlerMap<TId> = Map<TId, (isSelected: boolean) => void>;
export class SelectionMediator<
TAdditiveId,
TId,
TPosibleId = TAdditiveId | TId
> {
protected readonly _selected: Set<TId>;
protected readonly _handlers: HandlerMap<TId> = new Map();
get selected(): ReadonlySet<TId> {
return this._selected;
}
get handlers(): Readonly<HandlerMap<TId>> {
return this._handlers;
}
protected readonly toggle: (x: TPosibleId) => IsSelectedTuple<TId> = (
x: TPosibleId
) => itemTogglerFor<Set<TId>, TId>(this._selected)(this._constraint(x));
constructor(private readonly _constraint: (x: TPosibleId) => TId) {
this._selected = new Set<TId>([]);
}
public change(id: TPosibleId): IsSelectedTuple<TId> {
return this.handle(this.toggle(id));
}
public has(id: TPosibleId): boolean {
return this.selected.has(this._constraint(id));
}
public select(ids: TPosibleId[]): Array<IsSelectedTuple<TId>> {
return ids.map(this.toggle).map(this.handle);
}
private handle = ([id, isSelected]: IsSelectedTuple<TId>): IsSelectedTuple<
TId
> => {
const handler = this.handlers.get(id);
handler && handler(isSelected);
return [id, isSelected];
};
public on(id: TPosibleId, onChange: (isSelected: boolean) => void) {
const item = this._constraint(id);
this.handlers.set(item, onChange);
}
}
p.s. For 200 items on the screen, checkboxes have visible switching delays of about 0.8 seconds. With this method, a delay of 0.5 seconds starts at 2000 elements, and this(0.5) is a delay due to the browser, and not due to not optimal reactivity.
hello I have an problem , my list is more than 10 k if I scroll without active checkbox grid scroll fast , but if all checkbox is active , it became very laggy this code inside the template