vue.js

Vue.jsでSPAサイトを作成するチュートリアル【6. ライブラリ編】

Vue.jsを使い始めていろいろできることが多くなってきたので、整理する意味も兼ねてチュートリアルにまとめます。
今回はコーポレートサイトを想定して作成していきます。
※記事が長くなったのでチュートリアルを分割しました。

目次

前提

  • タスクはnpm scriptsで一限管理
  • コマンドはyarnを使用
  • vue-cliwebpack-simpleを使用

バージョン

  • "vue": "^2.5.11"
  • "webpack": "^3.6.0"
  • "vue-awesome-swiper": "^3.1.2"
  • "vue-match-heights": "^0.1.0"
  • "vue-smoothscroll": "^0.1.1"
  • "vue-social-sharing": "^2.3.3"

使用するライブラリ

サイト制作で割とよく使用するライブラリのVue.js版を使用します。

  • vue-awesome-swiper
  • vue-match-heights
  • vue-smoothscroll
  • vue-social-sharing

vue-awesome-swiper

まずはパッケージを追加します。

$ yarn add vue-awesome-swiper

今回は基本的なswiperをindexに置きましょう。
swiperのコンポーネントを作成します。

/src/components/IndexSwiper/IndexSwiper.vue
<template
  lang="pug"
  src="./IndexSwiper.pug"
/>

<script src="./IndexSwiper.js" />

<style
  lang="scss"
  src="./IndexSwiper.scss"
/>

/src/components/IndexSwiper/IndexSwiper.pug
.indexSwiper
  swiper(:options="swiperOption")
    swiper-slide
      p swiper1
      p swiper1
      p swiper1
    swiper-slide
      p swiper2
      p swiper2
      p swiper2
    swiper-slide
      p swiper3
      p swiper3
      p swiper3
    swiper-slide
      p swiper4
      p swiper4
      p swiper4
    .swiper-pagination(slot="pagination")

/src/components/IndexSwiper/IndexSwiper.scss
.indexSwiper {
  .swiper-slide {
    background: #ddd;
  }
}

/src/components/IndexSwiper/IndexSwiper.js
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'

export default {
  components: {
    swiper,
    swiperSlide
  },
  data () {
    return {
      swiperOption: {
        loop: true,
        pagination: {
          el: '.swiper-pagination',
          clickable: true
        }
      }
    }
  }
}

コンポーネントが作成できたら配置するところに記述します。

/src/pages/Index/Index.pug
main.main
  p {{ text }}
  .block
    | block
  index-swiper

/src/pages/Index/Index.js
import IndexSwiper from '../../components/IndexSwiper/IndexSwiper.vue'

export default {
  components: {
    IndexSwiper
  },
  data: function () {
    return {
      text: 'index'
    }
  }
}

ブラウザで確認し、swiperが正しく動作すれば成功です。

参考:vue-awesome-swiper

vue-match-heights

コンテンツの高さを揃えるライブラリも意外と重宝します。
まずは、パッケージを追加します。

$ yan add vue-match-heights

こちらもindexに配置します。
ライブラリの本体は基本的に全ページで使えるようにmain.jsに書きます。

/src/mainjs
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import Routes from './router.js'
import BodyClass from 'vue-body-class'
import VueMatchHeights from 'vue-match-heights' // ← 追記

Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  routes: Routes
})

Vue.use(BodyClass, router)

Vue.use(VueMatchHeights) // ← 追記

const app = new Vue({
  router,
  render: h => h(App)
}).$mount('#app')
console.log(app)

vue-match-heightsは使用したいテンプレートに属性として記述すれば機能します。

/src/pages/Index/Index.pug
main.main
  p {{ text }}
  .block
    | block
  index-swiper
  .matchHeights(v-match-heights="{ el: ['.matchHeights_item'] }")
    .matchHeights_item
      | 吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。
    .matchHeights_item
      | 恥の多い生涯を送って来ました。自分には、人間の生活というものが、見当つかないのです。自分は東北の田舎に生れましたので、汽車をはじめて見たのは、よほど大きくなってからでした。
    .matchHeights_item
      | 木曾路はすべて山の中である。あるところは岨づたいに行く崖の道であり、あるところは数十間の深さに臨む木曾川の岸であり、あるところは山の尾をめぐる谷の入り口である。

ブラウザの開発ツールで確認し、style="height〜"とインラインで同じ高さが指定されていれば成功です。

参考:vue-match-heights

vue-smoothscroll

ページ内リンクやページトップへスムーズに移動するアレです。
パッケージを追加します。

$ yarn add vue-smoothscroll

ページ全体で支えるようにmain.jsに記述します。

/src/main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import Routes from './router.js'
import BodyClass from 'vue-body-class'
import VueMatchHeights from 'vue-match-heights'
import VueSmoothscroll from 'vue-smoothscroll' // ← 追記

Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  routes: Routes
})

Vue.use(BodyClass, router)

Vue.use(VueMatchHeights)
Vue.use(VueSmoothscroll) // ← 追記

const app = new Vue({
  router,
  render: h => h(App)
}).$mount('#app')
console.log(app)

ページトップのコンポーネントを作成します。
今回はtransitionを使ってフェード機能もつけます。

/src/components/PageTop.vue
<template
  lang="pug"
  src="./PageTop.pug"
/>

<script src="./PageTop.js" />

<style
  lang="scss"
  src="./PageTop.scss"
  scoped
/>

/src/components/PageTop.pug
transition(name="fade")
  #pageTop.pageTop(
    :class="{ 'is-visible': isVisible }"
    @click="goPageTop"
    v-if="show"
  )
    | page top

/src/components/PageTop.scss
.pageTop {
  position: fixed;
  right: 20px;
  bottom: 20px;
  cursor: pointer;
  transition: all .25s ease-in-out;
  &.is-visible {
    opacity: 1;
  }
  &.fade-enter,
  &.fade-leave-to {
    opacity: 0;
  }
}

/src/components/PageTop.js
export default {
  data () {
    return {
      isVisible: false,
      show: true
    }
  },
  methods: {
    goPageTop: function () {
      this.$SmoothScroll(0, 500)
    },
    handleScroll: function () {
      let scrollY = window.pageYOffset
      const LINE = 100
      if (scrollY > LINE) {
        this.show = true
        this.isVisible = true
      } else {
        this.show = false
        this.isVisible = false
      }
    }
  },
  created () {
    window.addEventListener('scroll', this.handleScroll)
  },
  destroyed () {
    window.removeEventListener('scroll', this.handleScroll)
  }
}

次に表示させるところに記述します。

/src/components/TheFooter/TheFooter.pug
footer#theFooter.theFooter
  page-top
  p.copyright &copy; {{ copyright }}

/src/components/TheFooter/TheFooter.js
import PageTop from '../../components/PageTop/PageTop.vue'

export default {
  components: {
    PageTop
  },
  data: function () {
    return {
      copyright: '2018 vue skelton'
    }
  }
}

参考:vue-smoothscroll

vue-social-sharing

SNSのシェア機能を追加します。
vue-social-sharingを追加します。

$ yarn add vue-social-sharing

main.jsに追加します。

/src/main.js
// 省略
import SocialSharing from 'vue-social-sharing'
// 省略
Vue.use(SocialSharing)
// 省略

SocialSharingのコンポーネントを作ってフッターに読み込ませましょう。

/src/components/SocialSharing/SocialSharing.vue
<template
  lang="pug"
  src="./SocialSharing.pug"
/>

<style
  lang="scss"
  src="./SocialSharing.scss"
  scoped
/>

/src/components/SocialSharing/SocialSharing.pug
social-sharing(
  url="https://example.com"
  titile=""
  description="サイトの説明文です。"
  quote="facebook用の引用文"
  hashtags="vuejs,javascript,framework"
  twitter-user="buchiya4th"
  inline-template
)
  ul.snsList
    li
      network(network="facebook")
        | facebook
    li
      network(network="twitter")
        | twitter
    li
      network(network="line")
        | line

/src/components/SocialSharing/SocialSharing.scss
.socialSharing {
}

/src/pages/TheFooter/TheFooter.pug
footer#theFooter.theFooter
  page-top
  social-sharing
  p.copyright &copy; {{ copyright }}

/src/pages/TheFooter/TheFooter.js
import PageTop from '../../components/PageTop/PageTop.vue'
import SocialSharing from '../../components/SocialSharing/SocialSharing.vue'

export default {
  components: {
    PageTop,
    SocialSharing
  },
  data: () => {
    return {
      copyright: '2018 vue skelton'
    }
  }
}

SNSによって表示できるものが違うようです。
詳細は以下の参考記事をご確認ください。

参考:vue-social-sharing

まとめ

ライブラリは基本的にmain.js等に記述しグローバルに読み込めるようにしますが、swiperのようにコンポーネントごとに設定する方法もあるようです。
詰まった時は公式ドキュメントを読んで理解を深めるようにすると良さそうです。
他にも何か使ったら追加するかもしれません。