くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Nuxt/Vueでtooltip(v-tooktip)

Nuxtを使ったアプリではBuefyを使っているけど、
BuefyのTooptipが相性が悪く, うまくいかない。。

いろいろ調べたらv-tooktipがよかったので、そのときの備忘録。
v-tooltipの内部では、Popper.jsを使ってるらしい。

なにがうまくいかなかったか

BuefyのTooltipはこんな感じで、ツールチップを表示する要素を囲む感じ。

<b-tooltip label="I'm never closing" always>
  <b-button label="Always" />
</b-tooltip>

するとこんな感じのHTMLが生成される。

<span class="b-tooltip is-primary is-top is-medium is-always">
  <div class="tooltip-content">I'm never closing</div>
  <div class="tooltip-trigger">
    <button type="button" class="button">
      <span>Always</span>
    </button>
  </div>
</span>

CSSはこんな感じで、position: absolute;を使っている。
そのため、親要素にoverflow: hidden;とかを設定していると、うまく表示されない。。

.b-tooltip {
  position: relative;
  display: inline-flex;
}

.b-tooltip .tooltip-content {
    z-index: 38;
    position: absolute;
}

.b-tooltip.is-top .tooltip-content {
    top: auto;
    right: auto;
    bottom: calc(100% + 5px + 2px);
    left: 50%;
    transform: translateX(-50%);
}

いい感じに表示されるように、position: fixed;で位置を指定しているTooltipが必要な感じだった。
v-tooktipがまさにその形なので、いい感じに表示できる。

v-tooltipを使ってみる

インストール

まずはインストール

$ npm i v-tooltip

プラグインを作成

// ~/plugins/vue-tooltip.ts
import Vue from "vue";
import VTooltip from "v-tooltip";

Vue.use(VTooltip);

作成したプラグインをnuxt.config.tsに設定して有効化

// nuxt.config.ts
import { NuxtConfig } from "@nuxt/types";

const config: NuxtConfig = {
  plugins: [
    "~/plugins/vue-tooltip"
  ],
}
export default config;

スタイルを設定する

デフォルトのスタイルが提供されていないので、自分で.sassを用意する必要がある。

サンプルのスタイルが用意されているので、それをコピペすればだいたいOK。
背景色とかはそれをベースに調整する感じ。

使ってみる: 文字を出す

文字を出すだけだったら、こんな感じでOK。
v-tooltipディレクティブが使えるようになってる。

<button v-tooltip="'You have ' + count + ' new messages.'">

使ってみる: コンポーネントを指定

ツールチップ内にコンポーネントを利用したい場合は、v-popoverコンポーネント
v-tooltipディレクティブは使わない。

<v-popover>
  <!-- This will be the popover target (for the events and position) -->
  <button>Click me</button>
  <!-- This will be the content of the popover -->
  <MyAwesomeComponent slot="popover"/>
</v-popover>

ただし、<v-popover>を使う場合は、defaultTriggerがclickになっているので注意。
必要があれば、`~/plugins/vue-tooltip.tsでデフォルトのトリガーを変更する。

// ~/plugins/vue-tooltip.ts
import Vue from "vue";
import VTooltip from "v-tooltip";

Vue.use(VTooltip, {
  popover: {
    defaultTrigger: "hover",
  }
});

小ネタ: positionの指定がうまく行かない

v-tooltip.topなどで指定しても、下に表示される場合がある。。

<button v-tooltip.top="'You have ' + count + ' new messages.'">

これは、Popper.jsが配置場所を計算してくれるけど、
ネストなどしていると親要素を境界として計算されてしまうので、
defaultBoundariesElementを正しく指定する必要がある。

v-tooltipディレクティブとv-popoverコンポーネントのオプションが、
それぞれあるので2箇所指定しておくと良い感じ。

// ~/plugins/vue-tooltip.ts
import Vue from "vue";
import VTooltip from "v-tooltip";

Vue.use(VTooltip, {
  defaultBoundariesElement: "body",
  popover: {
    defaultTrigger: "hover",
    defaultBoundariesElement: "body"
  }
});

以上!!

参考にしたサイトさま