0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Vue.js2.6.x以上で実装するテンプレートとアトミックデザインの手法

Posted at

概要

JSフレームワークであるVue.jsでもReactでも、アトミックデザインを採用して実装する案件にアサインすることが多くなってきました。
そこでフロントエンドでの範囲に限られますが、バックエンドから取得したデータを出力するまでの手法として、各テンプレートの構成や処理内容について紐解いていこうと思います。

バージョン環境

vue@2.6.14

ソース構成

App.vue
├ views
  └ page.tpl //大元の画面
├ components
  ├ Heading.tpl //見出しを出力
  ├ Table.tpl //テーブル全体を出力
  └ tableList.tpl //テーブルのリストを出力
└ assets/css
  ├ style.scss
  └ page.scss

画面に出力される大枠のテンプレートは page.tpl です。
これとヘッダー、フッターなどを組み合わせてページ全体を構成する形になるため、アトミックデザインの「Organisms」にあたります。

その中の構成コンポーネントとしてテーブルを出力する Table.tpl 、その中のリストを出力する tableList などが存在します。
中身のボリュームはものによって変わるので、アトミックデザインの「Atoms」や「Molecules」にあたります。

また、スタイライズについては共通のものを使用し、 style.scssで全体管理をしつつ各画面ごとにスタイルシートを適用する形のイメージです。
(今回のテンプレートの場合は page.scss

画面のベース構成

まず大元となる page.tpl を見ていきます。

src/views/page.tpl
<template>
  <!-- テンプレートの中身を記述 -->
  <Title type="h2">
    見出し
  </Title>
  <Table
    :items="items.listItems"
  />
</template>

<script>

// テンプレートで呼び出すコンポーネントを指定
import Table from '@/components/Table';
import Title from '@/components/Title';

export default {

  data() {
    return {
      //初期値、データ型を設定する
      items: {
        listItems: [],
      }
    };
  },

  components: {
    // テンプレート内で呼び出すコンポーネントを指定
    Table
  },

  created() {
    // テンプレートが呼び出されたタイミングで実行するファンクション
    this.getListItems();
  },

  computed: {
    // 子コンポーネントに返り値を渡す際のファンクション
  },

  methods: {
    // テンプレート内で実行するファンクションの内容を定義
    getListItems() {
      this.items.listItems = [APIで取得したデータ];
    },
    
  }
};
</script>
src/components/Title.tpl
<template>
  <h2 v-if="type == 'h2'">
    <slot></slot>
  </h2>
  <h3 v-else-if="type == 'h3'">
    <slot></slot>
  </h3>
  <h4 v-else-if="type == 'h4'">
    <slot></slot>
  </h4>
</template>

<script>
  props: {
    // 親から受け取るプロパティの型定義
    type: {
      type: String,
      required: false
    }
  }
</script>

pageでは2つのコンポーネントを呼び出します。
見出しを出力する Title 、テーブルを出力する Table です。

Titleコンポーネントについては記述したテキストを元にh2〜h4の見出しを出力します。
どのタグを出すかは、親テンプレートで指定したプロパティ type を参照する形になっています。
ミニマムなコンポーネントに対して親側で要素を設計する場合は、子供側で slot を記述することで構成にあった出力をすることができます。

Tableについては :items プロパティを設定していますが、これはcreatedのタイミングでmethodsの getListItems によりAPIデータが取得され、dataに入ったものを参照しているという流れになります。

なおこの次にここで取得したデータをtableListで一覧表示することになるのですが、tableListはpageと直接的な連携を行うわけではないのでここではimportなどの記述が必要ありません。
Tableを介してtableListがデータを取得する流れができていればいいというわけです。

テーブル部分の構成

src/components/Table.tpl
<template>
  <table>
    <tr>
      <th>項目1</th>
      <th>項目2</th>
      <th>項目3</th>
      <th>項目4</th>
    </tr>
    <tableList
      v-for="item in items"
      :key="item.id"
      :item="item"
    />
  </table>
</template>

<script>
import tableList from '@/components/tableList';

export default {
  props: {
    items: {
      type: Array,
      required: true
    }
  },

  components: {
    tableList
  }
};
</script>
src/components/tableList.tpl
<template>
  <table>
    <tr>
      <th>{item.data1}</th>
      <th>{item.data2}</th>
      <th>{item.data3}</th>
      <th>{item.data4}</th>
    </tr>
  </table>
</template>

<script>

export default {
  props: {
    item: {
      type: Object,
      required: true
    }
  }
  
};
</script>

まずTableでは、pageで取得されたデータリスト「listItems」をitemsという配列で継承しています。
このitemsはtableListへの継承データとなり、tableListをimportした状態でv-forでループ出力させる構造になっています。

表示順は:keyプロパティでの指定が可能で、今回はAPIデータに含まれるitem.idを指定しています。

次にtableList側ではそのデータをpropsで受け取り、4つある項目にそれぞれの値を出力している形になります。
ここのdata1data2といった値は、データの大元であるAPIデータ側の構成に準拠した名前となります。

参考文献

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?