Vue.js 中递归组件之间的通信

在 [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社区中非常常见的模式:将函数转移为属性,这使我们能够轻松处理复发组件上的点击操作,同时保持其性能和易于推理。

保持冷静

Published At
Categories with 技术
Tagged with
comments powered by Disqus