我正在构建自己的Tree View组件,该组件允许选择树的元素(单选)。我正在使用一个递归调用自己的TreeNode子组件。到目前为止,一切都很好,树已经构建好了,我正要对选择(单击)元素做出反应。
我在以下两种方法之间犹豫不决:
selectedKey
道具(所选元素的ID),并在每次单击元素时发出'update:selectedKey'
事件。由于selectedKey
是TreeNode的支持,这会将事件(即所选ID)传播到树的根节点(由于事件在每个树节点中发出),然后传播回所有子节点。最后,每个树节点实例都通过计算属性来确定它是否为选定的树实例。这是TreeNode.vue示例代码(已大大简化):<template>
<div>
<div @click="selectNode">{{ node.label }}</div>
<TreeNode v-for="node of node.children" :key="node.key"
:node="node"
:selectedKey="selectedKey"
@update:selectedKey="$emit('update:selectedKey', $event)"/>
</div>
</template>
export default {
props: ['node', 'selectedKey'],
computed: {
isSelected () {
return this.node.key === this.selectedKey
}
},
methods: {
selectNode () {
this.$emit('update:selectedKey', this.node.key)
}
}
}
'nodeSelected'
事件。每当单击某个元素时,它都会发出该事件,并提供所选元素的ID作为有效负载,然后每个节点都会接收该事件并检查是否应选择该事件。这是示例代码:<template>
<div>
<div @click="selectNode">{{ node.label }}</div>
<TreeNode v-for="node of node.children" :key="node.key" :node="node"/>
</div>
</template>
export default {
props: ['node'],
data (): {
selectedKey: null
},
computed: {
isSelected () {
return this.node.key === this.selectedKey
}
},
created () {
this.$root.$on('nodeSelected', this.onNodeSelected)
},
beforeDestroy () {
this.$root.$off('nodeSelected', this.onNodeSelected)
},
methods: {
selectNode () {
this.$root.$emit('nodeSelected', this.node.key)
},
onNodeSelected (selectedKey) {
this.selectedKey = selectedKey
}
}
}
现在我的问题-以上哪种方法是首选方法-一种更紧密地遵循Vue最佳实践和准则,并能确保更好的性能和可伸缩性的方法?
我必须说,在测试过程中,我注意到第二种方法可能会更快地工作,即有迹象表明,鼠标单击和元素选择之间的延迟(我对选定元素应用了一些背景)小于第一种方法。我将其归因于以下事实:在第一种情况下,有一个事件必须一直传播到根节点,然后再返回到树的所有元素。我的树甚至不大-只有14个节点。但是我可能错了:)
第二种方法的第二个问题-如何将Tree组件(这是包含TreeNode组件的递归树的主要父组件)传递给所有子代,以便他们注册'nodeSelected'
事件而不是根Vue组件上?这将使整个Tree View组件更加封装和独立。
谢谢!