[英]Vue - Storing a tree in Pinia
我要問的問題是關於 Pinia 的,但實際上可以推廣到任何基礎商店。
我有一個 Vue + Pinia 應用程序,我希望能夠在其中存儲一棵樹。 該樹由Node
類型的對象組成。 我需要一次只存儲一棵樹,我不關心根(我們可以想象它在那里,但我關心的是根的孩子,他們的孩子,等等)。
我想支持以下操作:
這是我想做的事情:
Node
數組。 我們稱它為topLevelNodes
nodeIdToChildren
,它將節點的 id 映射到作為其子節點的Node
數組我最初會獲取頂級節點,填充數組topLevelNodes
。
對於每個需要知道其子節點的節點,獲取它們並將它們作為鍵放入父 ID 下的nodeIdToChildren
中。
這種方法的一個優點是很容易添加、刪除和移動節點:只需觸摸映射中的相關條目。 最大的缺點是只找到一個節點的效率要低得多,不管它的 position。假設我想編輯 id 為xyz
的節點,不知道它是誰的孩子。
我可以創建一個吸氣劑,將映射 object 中的所有值與頂級節點數組中的值一起展平,但我不確定其效率。
有沒有更好的方法來做到這一點?
最有效的方法是將所有節點存儲在一個數組中,而在一個節點的子/父數組中,您只放置其他節點的 ID。
parents
,但它返回所有項目的 ids,這些項目當前在他們的 children 數組中包含當前項目的 id。 同樣,如果您存儲父母,則孩子將被計算。注意事項:
getItemDetails
))children
ID 數組中刪除它的 ID,將它的 ID 添加到新父母的children
中。孩子本身不受影響,除了值它的parents
計算的變化。如果你正在存儲parents
, - 並且計算了children
- 你需要改變孩子的parents
數組。當然,當你執行這個改變時,每個新舊父母的children
計算都會改變) . 您可以在此處查看工作演示。 對不起 styles,我只是從不同的沙盒中調整了一些東西。 但是你得到了<TreeView />
和<TableView />
的基本實現。 這個有 1k 個節點,但最多 5k 個節點應該沒有問題。 除此之外,您需要注意渲染的內容和時間。
這不是Vue/Pinia特有的,所以我只是寫了大概的思路,你可以選擇實現的方式。
您將把您的樹存放在一個平面 map 上。
const tree = new Map()
每個項目都是一個node
,鍵是nodeId
。 每個節點將包含以下屬性:
{
id: "the node id",
parentId: "id of the parent, null if it is the root node",
childIds: "array of the id of its child",
content: "content of the node, whatever you want"
}
讓我們通過您想要的每個運營商 go:
// difficulty: easy
const rootNode = {
id: "nodeId"
parentId: null,
childIds: [...],
content: "..."
}
tree.set(nodeId, rootNode)
// difficulty: easy
// add the child first
const childNode = {
id: "nodeId"
parentId: "parentId",
childIds: [...],
content: "..."
}
tree.set(nodeId, childNode)
// add the child id to the parent node
const parentNode = tree.get(parentId)
parentNode.childIds.push(childNode.id)
// set the parent back to your tree
tree.set(parentNode.id, parentNode)
// modify a node.
// difficulty: easy
const node = tree.get(nodeId)
// ... make the modification
// set it back to the tree
tree.set(nodeId, node)
// delete a node.
// difficulty: medium
// retrieve the node first
const node = tree.get(nodeId)
// delete it
tree.delete(nodeId)
// delete all of its children
// you need a recursive delete function here to go through all of the node child and child of child and so on
tree.childIds.forEach(recursiveDelete)
// don't forget to delete the nodeId from its parent node. It's easy
...
// moving around the tree is quite easy, you just need to follow the `parentId` and `childIds`
// changing a node's parent (same level)
// difficulty: easy
// you just need to change the parentId of the node. And modify the childIds of its old and new parent
// changing a node level, moving its children accordingly
// difficulty: easy
// same as changing a node parent above. Its children will move accordingly
// changing a node level to be a child of one of its children
// difficulty: hard
// get the node
const node = tree.get(nodeId)
// go through its children and update the parentId of each to the node.parentId (moving its children to be the direct child of its parent)
node.childIds.forEach((childId)=> updateParentId(childId, node.parentId))
// set the node parentId to the new one
node.parentId = newParentId
// set new childIds for the node if you want
node.childIds = [...]
// don't forget to set it back on the tree
tree.set(node.id, node)
// There is no problem at all. You just need to load from the root
優點和缺點
優點:
缺點
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.