Vue.jsの再帰コンポーネントの投稿では、再帰ツリーコンポーネントを構築する方法を見てきましたが、ツリー全体でアクションを伝達する必要はありませんでした。 この投稿でその問題に取り組みましょう。

コミュニケーションとはどういう意味ですか?

前の記事のNodeTreeがクリックされたときに確認し、それを外部コンポーネント( Tree コンポーネントを使用しているコンポーネント)に伝達するとします。

Vue.jsでは、カスタムイベントを使用して上向きの通信が行われます。 しかし、Vue.js1.xまたはAngular1.xから、複数のレベルにまたがるイベントを持つことは悪い習慣であり、推論するのが難しいコードベースになることを学びました。 そのため、Vue.js 2以降、カスタムイベントは1つの子から親へのレベルでのみ許可されます。

それを知って、次のようなツリーを想像してください。

+ Folder 1
  + Folder 2
    + Folder 3
      + Folder 4
        + Folder 5

クリックイベントを Folder 5 カスタムイベントを使用すると、イベントを5回発行する必要があります。

木がいくつあるかは事前にわからないので、木には無限の深さがあると言えます。 そのため、カスタムイベントを使用すると、実行不可能で非効率的で複雑になります。

小道具を使用した再帰的コミュニケーションの解決

はVue.jsで小道具として関数を使用できることを忘れないでください。 Reactとは異なり、Vue.jsには子から親への通信用のカスタムイベントがあるため、これは一般的なパターンではありません。 しかし、このような場合には、それは本当に便利です。

各レベルでイベントを発行するのとは異なり、関数への同じ参照を渡すだけでよいため、これははるかに単純でパフォーマンスが高くなります。

追加しましょう handleClick NodeTree.vue コンポーネントのプロパティを作成し、クリックイベントに使用します。

NodeTree.vue
<template>
  <li class="node-tree">
    <span class="label" @click="handleClick(node)">{{ node.label }}</span>

    <ul v-if="node.children && node.children.length">
      <node
        v-for="child in node.children"
        :node="child"
        :handle-click="handleClick">
      </node>
    </ul>
  </li>
</template>

<script>
export default {
  name: "node",
  props: {
    node: Object,
    handleClick: Function
  }
};
</script>

タイプを次のように設定する方法に注目してください Function ラベルに使用します @click イベントを実行し、それを子ノードに再度渡します :handle-click="handleClick".

アウターコミュニケーション

Tree.vue コンポーネントから、その関数をルートノードに渡す必要があります。

さらに、外部( Tree を使用するコンポーネント)からのクリックを処理する方法を提供する必要があります。これには、1つ上のレベルであるため、実際にカスタムイベントを使用できます。

Tree.vue
<template>
  <div class="tree">
    <ul class="tree-list">
      <node-tree :node="treeData" :handle-click="handleClick"></node-tree>
    </ul>
  </div>
</template>

<script>
import NodeTree from "./NodeTree";

export default {
  props: {
    treeData: Object
  },
  methods: {
    handleClick (node) {
      this.$emit('node-click', node);
    }
  }
  components: {
    NodeTree
  }
};
</script>

ご覧のとおり、 handleClick Treeコンポーネントにローカルなメソッド。これは、に渡されます。 node-tree. このメソッドは、データのノードを使用してイベントを発行します。 $emit Vueインスタンスメソッド。

これにより、 App.vue またはその他の外部コンポーネントからのクリックを処理しながら、次を使用して優れたAPI構文を維持できます。 @node-click テンプレート上:

App.vue
<template>
  <div>
    <tree :tree-data="tree" @node-click="logClick"></tree>
  </div>
</template>

<script>
import Tree from "./Tree";

export default {
  data: () => ({
    // ...
  }),
  methods: {
    logClick(node) {
      console.log("Clicked: ", node);
    }
  },
  components: {
    Tree
  }
};
</script>

まとめ

ご覧のとおり、「無限レベル」の通信の問題を修正するために、Reactコミュニティで非常に一般的なパターン、つまり関数をプロパティとして渡すパターンを利用しました。 これにより、再帰コンポーネントのパフォーマンスと推論を容易に保ちながら、再帰コンポーネントのクリックアクションを簡単に処理できるようになりました。

涼しくしてください🦄