ホームページ  >  記事  >  ウェブフロントエンド  >  Vue を使用して組織構造ツリー コンポーネントを作成する方法

Vue を使用して組織構造ツリー コンポーネントを作成する方法

亚连
亚连オリジナル
2018-06-22 14:42:544660ブラウズ

最近、会社は Vue 開発に基づいたプロジェクトに取り組んでいます。そのプロジェクトでは、インターネットで長い間検索しましたが、適切なコンポーネントが見つかりませんでした。 Vue に基づいた組織構造ツリー コンポーネントを共有します。友人である必要がありますので、参照してください

会社のビジネス ニーズにより、組織構造 (会社の) を表示するツリー コンポーネントを開発する必要があります。プロジェクトは Vue に基づいています)。 GitHub で長い間検索した結果、そのようなコンポーネントはあまりなく、ビジネス ニーズを満たすコンポーネントもなかったので、独自のホイールを作成することにしました。

分析

  • ツリーなので、各ノードは同じコンポーネントである必要があります

  • ノードはノードの下にネストされているため、ノードコンポーネントは再帰コンポーネントである必要があります

、 質問は 。再帰的なコンポーネントを記述するにはどうすればよいですか?

再帰コンポーネント

Vue の公式ドキュメントには次のように書かれています:

コンポーネントはテンプレート内で自身を再帰的に呼び出すことができます。ただし、これは名前オプションがある場合にのみ実行できます

次に、ツリー ノードの再帰コンポーネントを作成しましょう:

<template>
 <p class="org-tree-node">
 <p class="org-tree-node-label">{{data.label}}</p>
  <p class="org-tree-node-children" v-if="data.children">
  <org-tree-node v-for="node in data.children" :data="node" :key="data.id"></org-tree-node>
 </p>
 </p>
</template>
<script>
 export default {
 name: &#39;OrgTreeNode&#39;,
 props: {
  data: Object
 }
 }
</script>
<style>
 /* ... */
</style>

次に、このコンポーネントをレンダリングすると、効果は次のようになります

この時点で、単純な構成構造 ツリーコンポーネントが完成しました。

しかし、事態はまだ終わっていません。 。 。

要件: ノードのラベルはカスタマイズをサポートし、ツリーは水平表示をサポートする必要があります。

そのため、再帰コンポーネントに次の変更を加えました:

<template>
 <p class="org-tree-node">
 <p class="org-tree-node-label">
  <slot>{{data.label}}</slot>
 </p> 
 <p class="org-tree-node-children" v-if="data.children">
  <org-tree-node v-for="node in data.children" :data="node" :key="data.id"></org-tree-node>
 </p>
 </p>
</template>
<script>
 export default {
 name: &#39;OrgTreeNode&#39;,
 props: {
  data: Object
 }
 }
</script>
<style>
 /* ... */
</style>

ラベルのカスタマイズをサポートするためにスロットスロットを使用しましたが、問題が再び発生しました: カスタマイズできるのは第 1 レベルのノードラベルと、ネストされた子ノードのみであることがわかりました。スロットスロットを効果的に渡すことができません。長い間オンラインで検索しても結果がなかったので、公式ドキュメントを見ました。機能的なコンポーネントが見つかりました。以前に element-ui のツリー コンポーネントを使用したことがあったので、element-ui のツリー コンポーネントと同じように renderContent 関数を渡すことを思いつき、呼び出し元が自分でノード ラベルをレンダリングできるため、ノードのカスタマイズの目的を達成できます。 !

機能コンポーネント

次に、ツリーノードテンプレートコンポーネントを機能コンポーネントに変換します。 Node.js の書き方:

まず render 関数を実装します

export const render = (h, context) => {
 const {props} = context
 return renderNode(h, props.data, context)
}

renderNode 関数を実装します

export const renderNode = (h, data, context) => {
 const {props} = context
 const childNodes = []
 childNodes.push(renderLabel(h, data, context))
 if (props.data.children && props.data.children.length) {
 childNodes.push(renderChildren(h, props.data.children, context))
 }
 return h(&#39;p&#39;, {
 domProps: {
 className: &#39;org-tree-node&#39;
 }
 }, childNodes)
}

renderLabel 関数を実装します。ノード ラベルのカスタマイズの鍵は次のとおりです:

export const renderLabel = (h, data, context) => {
 const {props} = context
 const renderContent = props.renderContent
 const childNodes = []
 // 节点label定制,由调用者传入的renderContent实现
 if (typeof renderContent === &#39;function&#39;) {
 let vnode = renderContent(h, props.data)
 vnode && childNodes.push(vnode)
 } else {
 childNodes.push(props.data.label)
 }
 return h(&#39;p&#39;, {
 domProps: {
 className: &#39;org-tree-node-label&#39;
 }
 }, childNodes)
}

renderChildren 関数を実装します。ここで、renderNode が再帰的に呼び出され、再帰コンポーネントが実装されます

export const renderChildren = (h, list, context) => {
 if (Array.isArray(list) && list.length) {
 const children = list.map(item => {
 return renderNode(h, item, context)
 })
 return h(&#39;p&#39;, {
 domProps: {
 className: &#39;org-tree-node-children&#39;
 }
 }, children)
 }
 return &#39;&#39;
}

これで、render 関数が完成しました。 次に、render 関数を使用して機能コンポーネントを定義します。ツリーコンポーネントで宣言します:

<template>
 <!-- ... -->
</template>
<script>
 import render from &#39;./node.js&#39;
 export default {
 name: &#39;OrgTree&#39;,
 components: {
  OrgTreeNode: {
  render,
  // 定义函数式组件
  functional: true
  }
 }
 }
</script>

この時点で、機能コンポーネントの変換は完了です。水平表示については、スタイル コントロールを使用するだけです。

CSS スタイル

スタイルは、less を使用してプリコンパイルされます。ノード間の線は、:before と :after 擬似要素の境界線を使用して描画されます

機能拡張

  • ノードラベルのスタイルカスタマイズをサポートするために labelClassName 属性を追加しました

  • 以前に使用されていた labelWidth 属性を追加しましたノードラベルの幅を制限します

  • props 属性を追加しました。複雑なデータ構造をサポートするために、element-ui のツリーコンポーネントの props 属性を参照します

  • 子の展開と拡張をサポートするために、collapseable 属性を追加しましたノードの折りたたみ (展開と折りたたみの操作は呼び出し側で実装する必要があります)

  • 最初はフレックス レイアウトが使用されていましたが、IE9 と互換性がある必要があり、後に表示に変更されました: テーブル レイアウト

最終的な効果:

デフォルト

水平

問題の概要

各ノードのステータスを保存するツリーストアを定義できるため、ツリーノードの展開状態と折りたたみ状態を確認できます。内部的にメンテナンスできます

上記は私が皆さんのためにまとめたものです。将来的に皆さんのお役に立てれば幸いです。

関連記事:

WeChatアプレットに画像アップロードなどの一連の機能を実装する方法

JavaScriptのnull値とfalse値について

Webpackでの自動構築について(詳細チュートリアル)

JavaScriptでバグが発生しました

以上がVue を使用して組織構造ツリー コンポーネントを作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。