---
title: 技術検証 - vue.jsを用いたフロントサイト構築
---
# 技術検証 - vue.jsを用いたフロントサイト構築
フロントサイトの==構築経験0の初学者==が、`vue.js`を用いて、レスポンシブルかつSPAなサイトを実際に構築した際の気付きについてまとめる。
---
## package.json 抜粋
```json=
"dependencies": {
"buefy": "^0.8.12",
"core-js": "^3.6.4",
"material-components-web": "^5.1.0",
"vue": "^2.6.11",
"vue-router": "^3.1.5",
"vuex": "^3.1.2"
}
```
## 検証期間
2020.3.4〜2020.3.23 (13営業日)
## 比較対象
Apache FreeMarker JAVAにて構築された某アパレル系サイト
---
## サイト全体の構成
### vue.js/vue-router/Bulma/Buefyによる構築
----
1. 画面切り替え
画面レベルでの切り替えを制御する`/views/*.vue`。`/router/index.js`。
部品化した`/conponent/*.vue`。というvue.jsの基本的な構造は初学者にも理解しやすかった。
```javascript=
Vue.use(VueRouter)
const routes = [{
path: '/',
component: Home,
children: [{
path: '',
component: PickUp,
},
{
path: '/NewArrival',
component: NewArrival,
}, {
path: '/Ranking',
component: Ranking,
}, {
path: '/ShopList',
component: ShopList,
}, {
path: '/Search',
component: Search,
},
]
}]
```
従来であれば、jQueryによるDOM操作を行うか、サーバアクセスを伴う画面遷移を行うこととなり、以下に陥る。
- jQuery:DOMツリーをゴリゴリいじるのでソースの可読性に難あり。
- 画面遷移:サーバサイドのコードを読まないと何に切り替わるのかわからない。
これだけでも`vue.js`を採用する価値はあると考えられる。
----
2. component配置
Bulmaによって提供されている手法にてcomponentを配置していく。
一般的に使われているような配置は大抵提供されているため、配置手法を把握さえできれば大抵の構造は作成できる。
逆を言うと、Bulmaでできる配置手法を全部押さえておかないと、せっかくのレスポンシブル100%のBulmaの恩恵が無理実装により実現されないといったことが起こりうる。
なるべく従来のcssの知識で構造を作成せず、Bulmaの提供するレイアウト(HTML/class設定)で構築するといった考え方の変更が必要と考える。
また、Bulmaの思想は、==以下の通りモバイルファースト==でありPCブラウザを主としていないため、PCブラウザを主眼においたサイト構築にはベストフィットする訳ではなさそうだ。
(正し、それを理由にBulmaを使わないとなる程ではない)
>Vertical by default#
Every element in Bulma is mobile-first and optimizes for vertical reading, so by default on mobile:
>columns are stacked vertically
the level component will show its children stacked vertically
the nav menu will be hidden
You can however enforce the horizontal layout for both columns or level by appending the is-mobile modifier.
あと、少々公式のDocumentationが情報不足であり、実装してみては「なんか違う?」と言う手戻りは多く発生した。
----
3. サイト全体のカラーについて
Bulma/Buefyのコンポーネントに対する色指定は、いわゆる`#FFFFFF`形式ではなく`is-black`等で行う。
プリセットされている`$colors`だけでは当然足りないので、`/App.vue`において以下のような指定を行う。
※`$twitter`以降が追加カラー。`$primary`は上書き。
```javascript=
// Set your colors
$primary: #8c67ef;
$primary-invert: findColorInvert($primary);
$twitter: #4099FF;
$twitter-invert: findColorInvert($twitter);
$pink: #FFC0C9;
$pink-invert: findColorInvert($pink);
$menugray: #F8F8F8;
$menugray-invert: findColorInvert($menugray);
// Setup $colors to use as bulma classes (e.g. 'is-twitter')
$colors: (
"white": ($white, $black),
"black": ($black, $white),
"light": ($light, $light-invert),
"dark": ($dark, $dark-invert),
"primary": ($primary, $primary-invert),
"info": ($info, $info-invert),
"success": ($success, $success-invert),
"warning": ($warning, $warning-invert),
"danger": ($danger, $danger-invert),
"twitter": ($twitter, $twitter-invert),
"pink": ($pink, $pink-invert),
"menugray":($menugray, $menugray-invert)
);
```
サイト全体のカラー制御をここで実施できるのは非常に利点にかんじられるが・・・、最大の問題点は==全ての提供されているUI-componentがこれに対応している訳ではない==・・・ということにある。
また、グラデーション(`background: linear-gradient(#fddfe9, #e6e9fa);`のような記述に対応できているかは未調査である。これが不可能となると個別でスタイル指定をすることとなり、せっかくのサイト全体でのカラー制御が崩れてしまうこととなる。
---
## vue.js制御構文
vue.jsの制御構文(v-for,v-if)は非常に簡潔である。
以下は、json配列をループで回し、テキストタイプのボタンもしくはアイコンどちらを表示するか`v-if`にて判断するコードである。
```htmlmixed=
<div class="tile" id="footer_company_info">
<div calss="tile" v-for="footerinfo in footerinfos" v-bind:key="footerinfo.no">
<b-button v-if="footerinfo.kind ==='link'" type="is-text" size="is-small">{{ footerinfo.label }}</b-button>
<b-icon v-if="footerinfo.kind === 'icon'" :icon="footerinfo.icon" size="is-small"></b-icon>
</div>
</div>
```
```javascript=
<script>
import { mapState } from "vuex";
export default {
computed: mapState({
footerinfos: state => state.FooterLink.footerinfoList
}),
created() {
this.$store.dispatch("FooterLink/getFooterInfo");
}
};
</script>
```
- footerinfos:json配列
- footerinfo:配列の1レコード
という説明だけで、ほぼ解説は不要なレベルのわかりやすさである。
HTMLタグ内で、objectにアクセスしたいときに属性名にコロン(:)を付加する記載についてのドキュメントが見当たらなかったことで、少々苦労した程度である。
また、動的に変わる必要のない「サイドメニュー」や「フッターのリンク」もjson形式のデータにしておいて、上記コードの形で実現すると、可読性が向上したことを付け加えておく。
---
## 各種UIコンポーネント
今回利用したBuefy-uiコンポーネントは以下である。
- `<b-button>`
- `<b-carousel>`
- `<b-autocomplete>`
- `<b-icon>`
- `<b-menu>`
- `<b-message>`
- `<b-navbar>`
---
### <b-button>
標準的なボタンから、角が丸いボタン、リンクの形状のボタン等デザインには困らなかった。
また(当たり前だが)vue-routerへの連携がわかりやすい。
### <b-carousel>、<b-carousel-list>
多少はプロパティによるデザイン変更は可能であるが、多様なニーズに答えられるほど完成されてはいない。
例を挙げると、デザイン的には`<b-carousel-list>`を使いたいが、こちらでは自動アニメーション遷移が設定できないことがあった。
既存サイトと同等の振る舞いをさせるには、ui-コンポーネントそのものに修正をかける(or別物として作る)必要がある。
### <b-autocomplete>
公式ドキュメントのコピーアンドペーストで、想定通りの物が完成できた。
非常に便利。
### <b-icon>
公式ドキュメントのコピーアンドペーストで、想定通りの物が完成できた。
非常に便利。
### <b-menu>
属性に設定する項目が多いため、これもメニュー項目自体はjsonに分離した方が可読性が高くなりそう。
特にデザインに拘らないのであれば、簡単にサイドメニューを作ることができる、またハンバーガーメニューにも自動対応している。
```htmlmixed=
<b-menu>
<b-menu-list label="さがす">
<b-menu-item
v-for="sitem in sidemenu"
v-bind:key="sitem.no"
:label="sitem.label"
tag="router-link"
:to="sitem.routerlink"
></b-menu-item>
</b-menu-list>
```
デザインを自由に作ろうとする際には、カスタムラベル等を使用すると予想されるのだが、公式ドキュメントが以下で終わってしまっているので、難儀しそうである。
> Menu list custom label
### <b-message>
こちらはデザインも豊富かつ、`is-$colors`によるスタイル指定も可能なため、使い勝手が良い。
ただz-indexによる優先度がかなり高く設定されてるからか、ドロップダウンメニューより上に表示されてしまう。
(z-index指定してうまく動くようにしてしまえばいいのだが・・・。なかなか気づかない。)
### <b-navbar>
デザインの自由度が低いように思える。
必ず以下の順番で構成される。
1. ロゴ
2. 左寄せメニュー群
3. 右寄せメニュー群
そのため、中央にサイトロゴをおきたいといった場合には適用しづらく、今回はロゴなし&無理やりCSSでロゴを重ねると言う形で実装を行った。ハンバーガーメニュー化できなくなるけれど、`class=level`で均等配置させる方が素直かもしれない。
---
## データ制御
java語での表現となるが、`/store/modules/*.js`に、データ構造とそのアクセサをカプセル化し、Buefy-uiコンポーネントにマッピングするだけで、特に難しい設定や、階層構造を考えることなくデータのやりとり・変更が行えた。
捉え方によってはデータをかたっぱしからglobalに使っていると捕らえられるが、可読性がよくメンテナンスも簡単であることのメリットの方が大きいように思える。
vuexすげーな。
今回はREST-API呼び出しによるデータ取得までは検証の範囲外とした(時間切れ)。
---
## ドキュメントについて
- HTML5
- CSS3
- vue.js
- vue-router
- vuex
- Bulma
- Buefy
と7つのドキュメントを理解しながら見比べ実装していくため、人によっては対応ができなくなる可能性が想定される。
とはいえ、一度誰かが作ってしまえば、過去のソースを参考に量産していくことは==可読性の高いvue.jsの思想を壊さないかぎり==問題なくできると考えられる。
---
## 総評
vue.jsを軸としたフロントサイトの構築そのものについては、非常に軽量かつ、今風なサイト構築がスピーディにでき、またフロントサイト構築自体の素人でもある程度のものが実装可能であったため、有効であると考えられる。
ただし、メンテナンスについては以下のような大きな課題が残ると考えられる。
- 追加要件
○○と△△の背景を□□色にしてほしい。
- 対応 :o:
○○と△△の共通的な要素を見出し、新しいカラーテンプレート$colorsを定義して適用する。
- 対応 :x:
○○と△△の背景を□□色にする`<style>`記載をそれぞれに実施する。
対応:x:のような安易な改修を行えないような、監視・レビュー体制を組めなかった場合、vue.jsの良さは発揮できず、ただただ新しい知識を覚えないと要件に対する対応ができないと言った==負荷の増加==だけが残ることとなる。
---