LoginSignup
11
9

More than 5 years have passed since last update.

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

Posted at

はじめに

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のイベントで登壇する機会があったらまたスライド作ろうかなーって思ってます。
ではまた!!!

11
9
0

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
  3. You can use dark theme
What you can do with signing up
11
9