Vue.jsでECサイトのモックアップを作ってみた。

この記事は、Vue.js Advent Calendar 201９ #1 1日目の記事です。https://qiita.com/advent-calendar/2019/vue

AdventCalendar初参加です。よろしくお願い致します。

# VueCLIでECサイトのモックを作ってみる

はじめに出来た物の画像です。
デプロイしたサンプルのアドレスです。https://ec-sample-vue-cli.web.app/
コードはここです。https://github.com/yujiteshima/ec-sample-vue-cli

<img width="1677" alt="スクリーンショット 2019-12-01 18.11.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252625/9833152e-3cef-90ad-b993-7c12385ca445.png">

## モチベーション
Nuxt.jsを使ってみて、その便利さに、SSRの簡単さにVueCliをめっきり使わなくなってしまいました。
でも、VueCliを使ってCompositionApiの勉強をしている時にVueCliで作るのも面白いなと思いました。
何か作ってみたいと思い、今回ECサイトのモックを作ってみます。Nuxt.js風に作ってみるというのをテーマにしていきます。
何かを勉強する時のサンプルアプリを作るレパートリーを増やして行って、学習を楽しくしたいと思います。

## 環境
@vue/cli 4.1.1
node v10.15.3
yarn 1.19.0

## 仕様

データは外部APIから取って来ず、storeに仮のデータを入れておきます。
認証もAuth0やFirebaseAuthentication等の実装はせず仮の実装にします。
ページ構成は、Nuxt.jsでPageで実現する様な感じで作ってみます。


## プロジェクト作成

```bash
$ vue create ec-sample-vue-cli

Vue CLI v4.1.1
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex, CSS Pre-processors, Linter
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with node-sass)
? Pick a linter / formatter config: Basic
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No
```

## CSSフレームワークは、bulmaを使います。
bulmaの勉強を兼ねています。軽量だと聞きました。使っていない部分は使わずに部分的に取り込むことも出来ると聞きました。
まずは色々作ってみて、慣れてから使っている部分だけ部分的に取り込むことにチャレンジしてみます。

```bash
$ yarn add bulma
```

初期のsrcディレクトリ

```bash
.
├── App.vue 　
├── assets
│   └── logo.png
├── components
│   └── HelloWorld.vue
├── main.js
├── router
│   └── index.js
├── store
│   └── index.js
└── views
    ├── About.vue
    └── Home.vue
```
## Nuxt.jsを真似てフォルダ構成を作成してみる。

App.vueをNuxt.jsでのDefault.vueのにしたいと思います。名前もDefault.vueに変えちゃいます。
viewsの中にindex.vueを作ってルートディレクトリとして、Nuxt.jsと同じ様にページを配置して作ってみたいと思います。

```bash
.
├── assets
│   ├── filters.js
│   ├── logo.png
│   └── validators.js
├── components
│   ├── footer
│   │   └── Footer.vue
│   ├── header
│   │   └── Header.vue
│   ├── hero
│   │   └── Hero.vue
│   ├── menu
│   │   └── Menu.vue
│   ├── modal
│   │   ├── Checkout.vue
│   │   ├── Login.vue
│   │   └── Registration.vue
│   ├── products_list
│   │   ├── Products.vue
│   │   └── ProductsListContainer.vue
│   └── search
│       └── Search.vue
├── defalt.vue
├── main.js
├── router
│   └── index.js
├── store
│   └── index.js
└── views
    ├── index.vue
    ├── produst_detail
    │   └── _id.vue
    └── user
        └── wishlist
            └── index.vue
```
## Default.vueで全ページ共通のComponentsを配置する。

default.vueのコード
全ページ、ヘッダーとフッター、モーダルは共通です。

```Vue
<template>
  <div>
    <Header />
    <main>
　　　 <!--ルーティングで表示するのはこちらです-->
      <router-view />
      <!--モーダルはここにまとめました-->
      <LoginModal />
      <RegistrationModal />
      <CheckoutModal />
    </main>
    <Footer />
  </div>
</template>
<script>
import LoginModal from "@/components/modal/Login";
import Header from "@/components/header/Header";
import Footer from "@/components/footer/Footer";
import RegistrationModal from "@/components/modal/Registration";
import CheckoutModal from "@/components/modal/Checkout";
export default {
  components: {
    Header,
    Footer,
    LoginModal,
    RegistrationModal,
    CheckoutModal
  }
};
</script>

...scssは省略...
```
## Pageファイル

ルーティングで使うNuxt.jsでいうPagesに格納するファイル群はviewsフォルダにまとめます。
これでNuxt.jsに教えてもらったフォルダの配置に近くなったと思います。

```bash
└── views
    ├── index.vue
    ├── produst_detail
    │   └── _id.vue
    └── user
        └── wishlist
            └── index.vue
```

routerも掲載しておきます。

```js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/home.vue'
Vue.use(VueRouter)

const routes = [{
    path: '/',
    name: '',
    component: Home,
  },
  {
    path: '/product_detail/:id',
    name: 'product_detail-id',
    component: () => import('../views/produst_detail/_id.vue')
  },
  {
    path: 'user/wishlist',
    name: 'user-wishlist',
    component: () => import('../views/user/wishlist/index.vue')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: '/ec-sample-vue-cli/', // new!
  routes
})

export default router
```

## まとめ
ルーティングは、自分で書く必要がありますが、VueCliで書くのも面白いと思います。
Jsファイルの軽量化や、CompositionAPIの様な新しい仕様を試したり、新しいライブラリを試したりする時は出来る事が多い分、
Nuxt.jsよりやりやすいと思いました。今回、作ったSampleで次はCompositionAPIで作ってみたいと思います。