在 [Vue.js 中的回归组件]( / 社区 / 教程 / vuejs - 回归组件)的帖子中,我们看到如何构建回归树组件,但我们不必在树上传达任何行动。
沟通是什么意思
想象一下,你想检查前一篇文章中的 NodeTree 被点击时,并将其传达给外部组件(使用 Tree 组件的组件)。
在 Vue.js 中,上向通信使用 自定义事件发生。但我们从 Vue.js 1.x 或 Angular 1.x 了解到,跨多个层次的事件是一种不好的做法,这使得代码库难以推理。
知道这一点,想象一棵树如下:
1+ Folder 1
2 + Folder 2
3 + Folder 3
4 + Folder 4
5 + Folder 5
如果我们想使用自定义事件从文件夹5
中传达一个点击事件,我们将不得不发出一个事件最多5次。
我们可以说一棵树有无限的深度,因为我们不知道它有多少。
使用props解决复发式通信
请记住,我们可以在 Vue.js 中使用功能作为附件,这不是一个常见的模式,因为与 React 不同,Vue.js 具有自定义事件,用于儿童与父母之间的沟通。
与在每个级别播放事件不同,这是更简单和性能的,因为我们只需要传递相同的参考函数。
让我们将一个handleClick
属性添加到 NodeTree.vue 组件中,并将其用于点击事件:
1[label NodeTree.vue]
2<template>
3 <li class="node-tree">
4 <span class="label" @click="handleClick(node)">{{ node.label }}</span>
5
6 <ul v-if="node.children && node.children.length">
7 <node
8 v-for="child in node.children"
9 :node="child"
10 :handle-click="handleClick">
11 </node>
12 </ul>
13 </li>
14</template>
15
16<script>
17export default {
18 name: "node",
19 props: {
20 node: Object,
21 handleClick: Function
22 }
23};
24</script>
注意我们如何将它的类型设置为函数
,我们在标签@click
事件上使用它,并将其再次传递给儿童节点:handle-click="handleClick
。
外部通信
从 Tree.vue 组件,我们仍然需要将该函数传递到根节点。
此外,我们必须提供一种方法来处理来自外部的点击(使用Tree的组件),因此我们确实可以使用自定义事件,因为它只是一个级别:
1[label Tree.vue]
2<template>
3 <div class="tree">
4 <ul class="tree-list">
5 <node-tree :node="treeData" :handle-click="handleClick"></node-tree>
6 </ul>
7 </div>
8</template>
9
10<script>
11import NodeTree from "./NodeTree";
12
13export default {
14 props: {
15 treeData: Object
16 },
17 methods: {
18 handleClick (node) {
19 this.$emit('node-click', node);
20 }
21 }
22 components: {
23 NodeTree
24 }
25};
26</script>
正如你所看到的,我们在Tree组件中添加了本地的handleClick
方法,该方法被传送到node-tree
。
通过此,我们可以处理 App.vue 或任何其他外部组件的点击,同时通过在模板上使用 `@node-click' 来保持良好的 API 语法:
1[label App.vue]
2<template>
3 <div>
4 <tree :tree-data="tree" @node-click="logClick"></tree>
5 </div>
6</template>
7
8<script>
9import Tree from "./Tree";
10
11export default {
12 data: () => ({
13 // ...
14 }),
15 methods: {
16 logClick(node) {
17 console.log("Clicked: ", node);
18 }
19 },
20 components: {
21 Tree
22 }
23};
24</script>
包装上
正如你刚刚看到的那样,为了解决无限级别
的通信问题,我们使用了React社区中非常常见的模式:将函数转移为属性,这使我们能够轻松处理复发组件上的点击操作,同时保持其性能和易于推理。
保持冷静