background
These days, I need to make requirements. One table is tree-shaped data. The data in the inner layer is loaded lazily, but the UI page data is not updated in real time after the modification of the inner layer data, so I feel that the user experience is not particularly good.
The tree table is implemented using ElementUI
Requirements describe
- Table data is tree data (analogous to folders), and the inner data is lazily loaded
- You can add, delete and rename folders
- If the inner data is not empty, the expansion mark needs to be displayed. Click the expansion mark to load the inner data
Problem description
-
Page inner data cannot be updated in real time when changing the inner data name. After submitting the changes, only the outermost data is obtained by re-requesting the table data. The data in the inner layer is only loaded during expansion due to lazy loading, so it is not updated.
-
There is an attribute isLeaf in the outer data to indicate whether there is inner data. When the third layer data is deleted, the isLeaf property of the second layer data is not updated in time and will continue to display the expanded icon, making people think that there is inner layer data. This problem does not occur after layer 2 data is deleted. Because after deleting, rerequesting the table data also gets the outermost data.
The difference between these two problems is whether the inner data is related to the outer data. In essence, the table data is only retrieved from the outermost layer of data, and the data in the inner layer is not updated. How to solve this problem? Three ideas.
Methods described
1. Forcibly refresh components
The easiest way to do this is to refresh the page, but the page flickers. You can refresh the component. After manipulating the table data, refresh the entire table component so that the expanded data is closed, and then re-request the inner data during the later expansion to implement view-level updates.
Here’s how to refresh a component. See the correct way to force a component to re-render in Vue
Here, the key value of the component is updated to refresh the component
You only need to bind the key value to the component first
<template :key="componentKey"></template>
Copy the code
Then update the component’s key when the data is updated
this.componentKey = this.componentKey === 0 ? 1 : 0;
Copy the code
After the key value of a component is updated, the component is refreshed.
Advantages: No need to increase storage space, simple implementation.
Disadvantages: Components need to be refreshed, and the cost of component refresh should be considered. After refreshing, the inner data will be closed and the user experience will be slightly worse.
2. Use the built-in load function
In the built-in load function, store {tree, treeNode, resolve} in data with map, marked with keyID. In this way, objects and methods that render the inner data for each data can be saved locally for later invocation.
// Used to save lazy loading required built-in objects and methods for rendering child nodes
funcCache: new Map(),
Copy the code
this.maps.set(tree.keyid, { tree, treeNode, resolve });
Copy the code
Fetching objects and methods to operate when the inner data needs to be refreshed
const { tree, treeNode, resolve } = this.funcCache.get(parentId);
Copy the code
Advantages: Real-time data refresh, good user experience.
Disadvantages: A large number of objects need to be stored. The number of data is N and the number of objects to be stored is approximately O(N), which may waste storage space.
When dealing with the second problem mentioned above, because operations on the inner data can cause changes to the outer data, it is not enough to refresh the inner data only, but also to refresh the outer data, possibly going back to the affected outermost data, which makes the logic more complicated.
Ask the big boys for help
I don’t know if they have any optimization suggestions or other solutions to share.
If you have this kind of demand “silver bullet” also welcome to share!