0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

vue3でオンボーディングツアーを作成する (vue-shepherd)

Last updated at Posted at 2023-06-03

vue3でオンボーディングツアー機能(?)を作ってみました。
(オンボーディングツアー機能:ヌルヌルとポッポアップがついてきてアプリの使い方を教えてくれるやつです)
ライブラリとしてvue-shepherdを使用しました。
shepherd.jsのvue3用のラッパーライブラリです。そのライブラリの使い方のメモになります。
誰かの参考になれば幸いです!:grinning:

動きです↓
ezgif-5-790dc453e1.gif

公式サイト:https://shepherdjs.dev/
image.png

やりたいことは簡単に大体できるので超便利です!
ただ思ったこととして、そのまま使うと、
トリガーとポップアップが以下の画像のように被る&トリガーを囲む枠がぴったりすぎるので
image.png
ポップアップの位置を変更する&トリガーを囲む枠にマージンをつけるなどの
オプションを設定した方が見た目が良くなると思いました。
image.png
そのオプションをつけるコードはこんな感じです。
offsetをfloating-uiからインポートするところで少し時間がかかりました。
(参考:https://github.com/shipshapecode/vue-shepherd/issues/199)

app.vue
<script setup>
import { offset } from "@floating-ui/core";

// 一部省略

onMounted(() => {
  tour.addStep({
    text: "3rd Modal with modified style",
    attachTo: {
      element: ".third-trigger",
      on: "bottom",
    },
    modalOverlayOpeningPadding: 5, // ←これ
    modalOverlayOpeningRadius: 5, // ←これ
    floatingUIOptions: {          // ←これ
      middleware: [offset({ mainAxis: 20, crossAxis: 0 })],
    },
    // 一部省略
  });
});
</script>

ちなみに実際の動きを見たい方はごちらをご覧ください。
CodeSandBox:https://codesandbox.io/s/fervent-wood-ol05ju?file=/src/App.vue
全体のサンプルコード↓

app.vue
<template>
  <link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/shepherd.js@8.3.1/dist/css/shepherd.css"
  />

  <img alt="Vue logo" src="./assets/logo.png" />
  <div ref="el">
    <div class="first-trigger">1st trigger</div>
    <div>
      <span class="second-trigger">2nd trigger</span>
    </div>
    <div>
      <span class="third-trigger">3rd trigger</span>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import { useShepherd } from "vue-shepherd";
import { offset } from "@floating-ui/core";

const el = ref(null);
const tour = useShepherd({
  useModalOverlay: true,
});

onMounted(() => {
  tour.addStep({
    text: "1st Modal",
    buttons: [
      {
        action() {
          return this.cancel();
        },
        classes: "shepherd-button-secondary",
        text: "Skip",
      },
      {
        action() {
          return this.next();
        },
        text: "Next",
      },
    ],
  });
  tour.addStep({
    text: "2nd Modal with default popover style",
    attachTo: {
      element: ".second-trigger",
      on: "bottom",
    },
    buttons: [
      {
        action() {
          return this.back();
        },
        classes: "shepherd-button-secondary",
        text: "Back",
      },
      {
        action() {
          return this.next();
        },
        text: "Next",
      },
    ],
  });
  tour.addStep({
    text: "3rd Modal with modified style",
    attachTo: {
      element: ".third-trigger",
      on: "bottom",
    },
    modalOverlayOpeningPadding: 5,
    modalOverlayOpeningRadius: 5,
    floatingUIOptions: {
      middleware: [offset({ mainAxis: 20, crossAxis: 0 })],
    },
    buttons: [
      {
        action() {
          return this.back();
        },
        classes: "shepherd-button-secondary",
        text: "Back",
      },
      {
        action() {
          return this.complete();
        },
        text: "Done!",
      },
    ],
  });

  tour.start();
});
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

追記:progress barをつける

shepherd.jsのドキュメントとは、要素の指定方法が違うので注意。
(Shepherd.activeTour? -> tour)

app.vue
const tour = useShepherd({
    defaultStepOptions: {
        ~~~
        when: {
            show() {
                const currentStep = tour.getCurrentStep();
                const currentStepElement = currentStep?.getElement();
                const footer = currentStepElement?.querySelector('.shepherd-footer');
                const progress = document.createElement('span');
                progress.className = 'shepherd-progress';
                const progress_percentage = (tour.steps.indexOf(currentStep) + 1) / tour.steps.length * 100;
                progress.innerHTML = `<div class="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700">
                                        <div class="bg-blue-600 h-2.5 rounded-full" style="width: ` + progress_percentage + `%"></div>
                                      </div>`
                footer?.insertBefore(progress, currentStepElement.querySelector('.shepherd-button:first-child'));
            }
        }
    },
});
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?