LoginSignup
1
1

More than 3 years have passed since last update.

TreeViewコンポーネント(Vuetify)の「Async items」機能について

Last updated at Posted at 2020-06-15

背景

Vuetifyの公式サイトを見ていて、treeviewコンポーネントに「Async items」という機能があるのを見つけたので試してみた。
https://vuetifyjs.com/ja/components/treeview/

簡単に説明すると、ツリーのノードを開いた瞬間に子要素のデータを取得しに行く機能。
まぁ、ツリーのコンポーネントなら普通は持ってるよねって感じの機能ですが、使ってみると色々見えてきたりするので。。。

あと、今回はローカルファイルからのデータ読み込みをやるので、ついでに、VS CodeのLive Serverを試してみようと思う(実はこっちが本当の目的だったりする)。

ツリーコンポーネントへの「Async items」の適用

以前作成したWebComponents用ツリーコンポーネントのサンプルは、コード内にデータをべた書きしていたので、これを他からデータを取得してくるように変えてみる。

準備

以前作成したWebComponents用ツリーコンポーネントのコードを落としてくる。

> git clone https://github.com/yusuke-ka/sample-vce-vuetify.git

インストール。

> cd sample-vce-vuetify
> yarn install

元のコードは下のようになっていて、データ(items)は固定になっている。

tree.vue
<template>
  <div id="app">
    <v-app id="inspire">
      <v-treeview selectable :items="items"></v-treeview>
    </v-app>
  </div>
</template>

<script>
...
export default {
  el: "#app",
  vuetify: new Vuetify({
    icons: {
      iconfont: "md",
    },
  }),
  data: () => ({
    items: [
      {
        id: 1,
        name: "Applications :",
        children: [
          { id: 2, name: "Calendar : app" },
          { id: 3, name: "Chrome : app" },
          { id: 4, name: "Webstorm : app" },
        ],
      },
      ....
    ],
  }),
};
</script>

yarn buildでビルドすると、ツリーコンポーネントがWebComponents化されてbundle.jsが生成されて、他から呼び出せるようになる。

プロジェクト直下に下記のようなindex.htmlを置くと、ローカルでの動作確認ができる。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Custom Element By Vue + Vuetify</title>
    <script src="dist/bundle.js"></script>
  </head>
  <body>
    <vce-tree></vce-tree>
  </body>
</html>

こんな感じ↓

image.png

これを、ノードを開くタイミングで子要素を取得してくるように変更してみる。

コード修正

まず、template部分に:load-childrenを追加。メソッド(算出プロパティ)名は「fetchData」にしておく。
また、メソッド名が紛らわしいので、「:items="items"」は「:items="itemList"」に変更しておく。

tree.vue
<template>
  <div id="app">
    <v-app id="inspire">
      <v-treeview
        selectable
        :items="itemList"
        :load-children="fetchData"
      ></v-treeview>
    </v-app>
  </div>
</template>

script部分は、dataitemsは空にしておき、computeditemList()を定義する。
さらに、methodsfetchData()を定義。ここでデータを取得する。
普通はバックエンドのサーバーからデータを取得するんだけど、今回はローカルファイルを指定。
あと、外部からデータを取得しているのを分かりやすくするために、最初にpauseを定義して、意図的に待ち時間を入れている。

tree.vue
<script>
...

const pause = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

export default {
  ...
  data: () => ({
    items: [],
  }),
  computed: {
    itemList() {
      return [
        {
          name: "ItemList",
          children: this.items,
        },
      ];
    },
  },
  methods: {
    async fetchData(item) {
      await pause(1000); // 意図的に待ち時間を発生させる
      return fetch("./data.json")
        .then((res) => res.json())
        .then((json) => item.children.push(...json))
        .catch((err) => console.warn(err));
    },
  },
};
</script>

ローカルに置いたデータファイル(data.json)はこちら。

data.json
[
  {
    "id": 1,
    "name": "ChildA :",
    "children": [
      {
        "id": 4,
        "name": "ChildA-1 :"
      }
    ]
  },
  {
    "id": 2,
    "name": "ChildB :",
    "children": []
  },
  {
    "id": 3,
    "name": "ChildC :"
  }
]

vuetifytreeviewでは、「children」を空にしてやると、そのノードを開いた際に「:load-children」に定義したメソッドが実行されるらしいので、上のデータでは「ChildB」だけその状態にしている。

動作確認

このままビルドして、index.htmlを再表示してみる。

image.png

ローカルファイルを読み込んでいるので、最近のブラウザだとCORSのエラーが発生する。

ということで、予定通りVS CodeにLive Serverを入れて対応する。

Live Serverの導入

VS CodeのExtensions(MARKETPLACE)で、「Live Server」で検索

image.png

Live ServerのExtensionが表示されるので、「Install」ボタンからインストールする。

導入完了。

実行も簡単。
index.htmlをVS Code上で開いた状態で、右下にある「Go Live」を押す。

image.png

自動的にブラウザが立ち上がり、index.htmlが表示される。

動作確認(再)

初期表示では、「itemList()」の実行結果として、ルートノードが表示される。

ノードを開くと、fetchData(item)が実行されて、「data.json」に書いたデータが表示される。

tree.gif

続いて取得したデータの子要素を開いてみる。

tree.gif

ChildAの子要素「ChildA-1」は「data.json」に定義されているので、最初のデータ取得で一緒に取得され、即座に展開される。

ChildBの子要素は「data.json」には空で定義されているので、展開しようとした際にfetchData(item)が実行されて再度取得される。
(※本来は引数のitemで指定したノードの子要素を取りに行くべきだが、今回はitemを無視して「data.json」を読むので最初と全く同じデータが展開される。)

ChildCは「data.json」で「children」を指定していないので、そもそもノードが展開できない。

ということで、treeviewコンポーネントで動的に子要素を取得するように変更できました。

さいごに

ローカルで色々書いていると、CORSのエラーにはよく遭遇する。
今までは、わざわざS3でホスティングして確認していたので結構面倒だったが、Live Serverを使うことでだいぶ楽になることが分かった。

treeviewコンポーネントへの「Async items」導入については、「順次ロードさせるためにはchildrenを空にして返してやる必要がある」ってのが分かったことが収穫かな。(※まぁ公式サイトに書いてあるんですが。)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1