Nuxt.jsでvue-carouselで商品画像一覧をカスタマイズして表示する

# 概要
商品画像を画像と商品名の組み合わせのコンポーネントを作成し、カルーセルスライダーで表示を行う。
商品は４つずつ並べて横にスライドさせていけるイメージです。

### 画面イメージ
![screencapture-localhost-client-products-category-1-2019-12-18-00_29_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305479/26a7a21d-0c65-cdeb-888e-98408f3f7085.png)

# 参考
[nuxt.jsにvue-carouselを導入してスライダーを作成
](https://qiita.com/gakumac/items/cc3f1bb0dfcbbefa1eeb)

# 実装手順


## vue-carouselのインストール

```
npm install -S vue-carousel
```

Nuxtのプラグインで`vue-carousel.js`を作成し、下記を実装する

```vue-carousel.js
import Vue from 'vue'
import VueCarousel from 'vue-carousel'

Vue.use(VueCarousel)
```

```nuxt.config.js
plugins: [
    { src: '~/plugins/vue-carousel', ssr: false }
  ],
```

## コンポーネント設計

今回は、４枚ごとの商品画像を表示するようのコンポーネントとして実装していおきます。


![スクリーンショット 2019-12-18 0.37.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305479/fd499b68-11e7-e367-cb5d-29596c5747be.png)



## 実装

実際のコンポーネントの実装

`<carousel>`と`<slide>`の中に商品画像と価格と商品名を`v-for`で描画するようにする

`:per-page="4"`で４枚単位で表示するように指定しました。

中身のCSSの設定は`.VueCarousel-slide`の中に記載

```ProductCardCarousel.vue
<template>
  <carousel :per-page="4" :pagination-enabled="false">
    <slide v-for="(prodduct_item, key) in productList" :key="key">
      <div class="product-card">
        <div v-if="prodduct_item.imgURL != ''">
          <img class="product-card-img" :src="prodduct_item.imgURL" />
        </div>
        <div v-else>
          <img
            class="product-card-img"
            :src="require('@/assets/img/NoImage.png')"
          />
        </div>
        <div class="product-card-content">
          <div class="product-card-price">
            {{ prodduct_item.price }}ポイント
          </div>
          <div class="product-card-text">{{ prodduct_item.name }}</div>
        </div>
      </div>
    </slide>
  </carousel>
</template>

<script>
import Carousel from 'vue-carousel/src/Carousel.vue'
import Slide from 'vue-carousel/src/Slide.vue'
export default {
  components: {
    Carousel,
    Slide
  },
  layout: 'client/simple',
  props: {
    productList: {
      type: Array,
      required: true,
      default: () => []
    }
  }
}
</script>

<style lang="scss" scoped>
@import '~/assets/scss/base.scss';

.VueCarousel-slide {
  padding: $space_m $space_m $space_m $space_m;
  .product-card {
    .product-card-img {
      border-radius: 50%;
      height: 80px;
    }
    .product-card-content {
      text-align: center;
      .product-card-price {
        font-size: $font-size_xs;
        font-weight: bold;
        padding: $space-s 0 0 0;
      }

      .product-card-text {
        font-size: $font-size_xs;
        padding: $space-s 0 0 0;
      }
    }
  }
}
</style>

```

`ProductCardCarousel.vue` を使用する際には下記のように実装


```vuejs

<template>
  <div>
    <div v-for="(category_item, key) in categoryList" :key="key">
      <div class="category-title">{{ category_item.categoryTitle }}</div>
      <product-card-carousel
        :product-list="category_item.productList"
      ></product-card-carousel>
      <product-link
        :url="category_item.categoryLink"
        :link-name="category_item.categoryName"
      ></product-link>
    </div>
  </div>
</template>

<script>
import ProductCardCarousel from '~/components/client/ProductCardCarousel'
import ProductLink from '~/components/client/ProductLink'

export default {
  components: {
    ProductCardCarousel,
    ProductLink
  },
  layout: 'client/simple',
  data() {
    return {
      categoryList: []
    }
  },
  // レンダリングの前に商品情報を取得する
  async asyncData({ app, params, store, $axios }) {
    const { data } = await $axios
      .$get(
        `/api/user/product/category/${params.id}?event_id=${
          store.getters['event_info/eventSelected'].id
        }`
      )
      .catch(errors => {})

    return {
      categoryList: data
    }
  }
}
</script>
```

# まとめ
vue-carouselがあればデザインのカスタマイズもしつつ簡単に実装可能でした
あくまでメモ用なのでソースが汚かったりおかしかったりするかもしれませんが
良かったら参考にしてください。