まえおき
この投稿は木更津高専アドカレ 飛び込み18日目の記事でーす!
<< prev-17日目 AtCoder入緑したよ by @ku_senjan
>> next-19日目 Discordで勉強時間記録botを作る by @kokastar
dialogとかtooltipとか使いたいのよ
こんにちは、Vuetifyで遊んでいたらNuxtがVue3に正式対応になっていて、Composition APIを学びたいなあとなっているtos_upです。
Vuetifyって面白いですよね。ぼくは大好きです。
さて、<v-tooltip>
と<v-dialog>
を一つのボタンに重ねがけたい私は、一つの要素にv-bind
、v-on
を重ねる方法を知らなくて困っていました。
というところからお話は始まります。
※要は備忘録です。
結論
長い説明をするので、結果だけ聞きたい人にはこちらです。
<v-dialog v-model="dialog">
<template #[`activator`]="{ on: dialogOn, attrs: dialogAttrs }">
<!-- on: (任意のon名), attrs: (任意のbind名) -->
<v-tooltip bottom>
<template #[`activator`]="{ on: tooltipOn, attrs: tooltipAttrs }">
<!-- on: (任意のon名), attrs: (任意のbind名) -->
<v-btn v-bind="{dialogAttrs, tooltipAttrs}" v-on="{...dialogOn, ...tooltipOn}">アップロード</v-btn>
<!-- v-bind="{(1つめのattrs), (2つめのattrs)}" v-on="{...(1つめのon), ...(2つめのon)}" -->
</template>
</v-tooltip>
</template>
</v-dialog>
そもそも
私「<template #[`activator`]="{ on, attrs }">
って何やってるの」
私が調べたVue公式「(シーン)」
ちゃんと調べたら公式サイトに載っているのかもしれません。
検索英語が下手な私は辿り着くことができませんでした。
なのでコードで検証してみましょう。
環境はこちらです。
環境
node: v16.18.1
nuxt: v2.15.8
vue: v2.7.10
vuetify: v2.6.10
検証①
<v-dialog>
<template #[`activator`]="{ on, attrs }">
<v-btn v-on="on" v-bind="attrs" @click="showAny(on, attrs)">
</v-btn>
</template>
</v-dialog>
// 中略
showAny(on: any, attrs: any): void {
console.log('on is ', on);
console.log('attrs is ', attrs);
}
// ---
出力
ここからわかる情報は
on
にはclickのハンドラが入っていること
from https://vuetifyjs.com/ja/api/v-dialog/#slots-activator
attrs
にはアクセシビリティの情報が入っていること
from https://qiita.com/Gedyra/items/9d05e10329808367396f
ということでした。
複数指定はどうやるの
失敗例
上のサイトを参考にして、以下のコードを書きました。
<v-btn v-bind="[dialogAttrs, tooltipAttrs]" v-on="[dialogOn, tooltipOn]">
私「ボタンポチー」
動きませんでした。
attrsは増えていません。
エラーも出ています。
原因を探っていきましょう。
原因①: attrsが増えない
結論から言うと、原因まではわかりませんでした。
というか動作に支障をきたすのかどうかすらもわかりませんでした。
ですが、もとはObjectだったので[]
のかわりに{}
で囲ってObjectにしてあげたところ、画像のようになりました。
原因②: v-onのエラー
動かない原因はこっちだと思います。
多分v-on
を複数指定できていないのが原因ですね。
解決?
ここで、v-onについて、こんな記事を見つけてしまいました。
<!-- オブジェクト構文 (2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
そういうことだったんですね。
と思って書いたコードは失敗でした。
<v-btn v-on="{dialogOn, tooltipOn}" ... >
動きません。
成功へ
エラーも出ず、いよいよわからなくなってしまったところ
見つけてしまいました。
<template v-slot:activator="{ on }">
<my-comp v-on="{...on, ...$listeners}" />
</template>
という記述をもとに
<v-btn v-on="{...dialogOn, ...tooltipOn}" v-bind="{dialogAttrs, tooltipAttrs}"></v-btn>
動いたー!!!
参考
この問題を解決するにあたって、参考にさせていただいたサイトです。
成功のコード