search
LoginSignup
9

More than 3 years have passed since last update.

posted at

Vueでスライドショーを自作した

はじめに

Vue.js(以下Vue)いいですよね!!!
私はまだまだVue初心者です。
今年の6月頃から趣味で触り始めたVueですが、個人的にかなりハマり、自社アプリをVueでリプレイスしたり、実際の案件でも利用するまでになりました。
しかも関西でVueのコミュニティが立ち上がるので、さらにVueを深めて行かなければ…という気持ちですね。
そんな私ですがVueが好きすぎるので、ある発表スライドをVueで自作するというバカげたことをやりましたwww
このスライドは12/20に京都で開催されたv-kansai Vue.js/Nuxt.js meetup #1での発表スライドにしたものです。

前提条件

Vueファイルに直接書くのではなく、Pug / Scss / TypeScriptに書くようにして、Vueファイルに読み込ませるようにしています。

<template src="./hoge.pug" lang="pug"></template>

<script src="./hoge.ts" lang="ts"></script>

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

完成品

私のGitHubにPushしてあります。
基本的にソースコードの一部を抜粋して説明しているので、詳細はリポジトリに上がっているソースコードを参照してください。
あまりきれいに書けてないと思われるのでご了承くださいmm
git clone して npm i して npm run serve とやればローカルでスライドを確認することができます。

vue-slideshow.gif

工夫したところ

デザインごとにComponentを分ける

使い回しのできる部分は一つのComponentにする
例) 各ページのタイトル
slide_title.png

文字の内容(「工夫した点」など)はpropで各Componentに渡す(ここはVuex使えばよかったかも……)

親Component(スライドページ)。タイトルパーツのComponentに pageTitleText を渡す。


.main-contents
  PageTitle(:title-text="pageTitleText")

子Component(各パーツ)。親から受け取った pageTitleTexttitleText に代入されているので、Templateで表示する

.page-title
  .text {{ titleText }}

import { Component, Vue, Prop } from "vue-property-decorator";

@Component({})
export default class Conclusion extends Vue {
  @Prop() private titleText!: string;
}

動的セグメントを利用して、なるべくRouterを汚さない

基本的に一つのスライドに一つのPathが必要になってきます。
一つのPathごとにRouteを切っていたらRouterの中身ががが……となるので、動的セグメントを有効活用して、できるだけRouterを汚さないようにします。
ただ当然ですが、こうすると一つのComponentで複数のスライドを表現しなければいけないので、それはそれで工夫が必要です。(共通部分のComponentを作ったり、動的セグメントでTemplateを切り替えたり……)

import Vue from "vue";
import Router from "vue-router";
...
// 省略
...
Vue.use(Router);

export default new Router({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/",
      name: "title",
      component: Title
    },
    {
      path: "/selfIntroduction",
      name: "selfIntroduction",
      component: SelfIntroduction
    },
    {
      path: "/introduction/:pageName", // こういう書き方
      name: "introduction",
      component: Introduction
    },
    {
      path: "/summary/:pageName", // こういう書き方
      name: "summary",
      component: Summary
    },
    ...
    // 省略
    ...
  ]
});

画面(スライド)の切り替え

スライドなので、前後のスライドへ切り替えられるようにしなければなりません。
常に画面の一番上(前面)に要素を配置し、右半分に「次のスライドに進む」イベントを、左半分に「前のスライドに戻る」イベント持たせる。
表示中のスライドの前後のスライドが何かという情報はComponentに持たせる

transitionPageInfo: transitionPageInfoType = {
  preb: "",
  next: ""
};

イメージ的にはこんな感じ
スクリーンショット 2018-12-11 15.43.44.png


el-row.transition-page-area
  el-col(:span="12")
    .preb-page(@click="transitionPage('preb')" @mouseenter="showArrow('preb')" @mouseleave="hiddenArrow('preb')")
      .preb-arrow(v-show="prebArrow")
        img(src="../../assets/left_arrow.png", alt="")
  el-col(:span="12")
    .next-page(@click="transitionPage('next')" @mouseenter="showArrow('next')" @mouseleave="hiddenArrow('next')")
      .next-arrow(v-show="nextArrow")
        img(src="../../assets/right_arrow.png", alt="")
// ページ切り替え
public transitionPage(action: string) {
  // 表示中スライドのComponentから前後スライドのrouteを取得
  const targetRoute: string = this.$parent.$children[0].$children[1].$data
    .transitionPageInfo[action];
  if (targetRoute !== "") {
    router.push(targetRoute);
  }
}

// 矢印の表示
public showArrow(action: string) {
  switch (action) {
    case "preb":
      this.prebArrow = true;
      break;
    case "next":
      this.nextArrow = true;
      break;
    default:
      break;
  }
}

// 矢印の非表示
public hiddenArrow(action: string) {
  switch (action) {
    case "preb":
      this.prebArrow = false;
      break;
    case "next":
      this.nextArrow = false;
      break;
    default:
      break;
  }
}

さいごに

実際にVueでスライドを作ってみて、今まで知らなかった機能というか書き方を知ることができた、使うことができたのでいい機会だったなと思いました。
断片的にソースの紹介などをいたしましたが、実際のソースコードを見ていただいたほうがイメージ付きやすいと思います。
あとだーいぶサボって書いた部分が多いので、変数名とか、命名規則とかボロボロなところがあります。きっといつか直します。
今後Vueのイベントで登壇する機会があったらまたスライド作ろうかなーって思ってます。
ではまた!!!

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
What you can do with signing up
9