アンカーリンクのようにctrl, cmdを押しながらクリックして別タブで開くを対応したいケースがあります。
複数タブを開くことで情報を同時に見れるようするユーザービリティの向上目的です。
最近はディスプレイの大きなものを使う人もいるので、こういった配慮もできるとうれしいなーということで対応してみました。
動いたコード
とりあえず動いてるコードを最初に記載しておきます。
Ctrl, Cmd押しながらクリックすると新しいタブが開き、押さなければ普通にページ遷移します。
解説は後述。
- 検証バージョン情報
- Nuxt: 3.0.0
# /pages/href/index.vue
<template>
<div>
<!-- /pages/href/newpage.vue リンク先 -->
<button @click="hrefTo('/href/newpage', $event, { id: 1111 })">LINK</button>
<br />
<button @click="hrefTo('/href/newpage', $event)">LINK</button>
<br />
<button @click="clickAction">LINK</button>
</div>
</template>
<script lang="ts" setup>
import { LocationQueryRaw, RouteLocationRaw } from 'vue-router'
const clickAction = (event?: MouseEvent) => {
hrefTo('/href/newpage', event)
}
const hrefTo = (path: string, event?: MouseEvent, query?: LocationQueryRaw) => {
const to: RouteLocationRaw = {
path: path,
query: query,
}
// ここでctrlキーかcmdキーが押されているか取得できる
if (event && (event.ctrlKey || event.metaKey)) {
// resolveによってURLが生成されるのでwindow.openさせる
window.open(useRouter().resolve(to).fullPath, '_blank')
return
}
navigateTo(to)
}
</script>
解説
- 解決ポイントは2つ
- 新しいタブを開く(nuxt3 open new tab問題)
- ctrl,cmdの状態を取得する
新しいタブを開く
Nuxt3にはリンクを開く方法がいくつかあります
- useRouter().push()
- https://nuxt.com/docs/api/composables/use-router#userouter
- これはnavigationToが推奨されてる
- navigationTo
- NuxtLinkタグ
この中で新しいタブで開く同じみのtarget="_blank"
を指定できるのがNuxtLinkタグだけになります。
(navigationTo何故ないんだ。。。)
しかしイベントの処理によって遷移先を変えるなど、ロジックを動かしたあとに画面移動したい場合が多く、そうなるとnavigationToを使うことになるので、NuxtLinkタグそこまで使ってない状況です。
しかしnavigationToはtargetに対応していないので、結局のところwindows.openを使うしかないという判断です。
window.openに渡すURLを生成するのはuseRouter().resolve()
を使えばnavigationTo用のパラメタと同じものから生成できます。
ctrl,cmdの状態を取得する
これがコード上にある$event
ですね。
MouseEvent型が取れるみたいなので、そこでctrlKey, metaKeyでctrl, cmdの状態を調べることができます。
queryのほうは、遷移先のパラメタ指定したいときあるよね、という意味でサンプル的につけてみました。
今回はclickに直接callしていますが、submitActionなどを作って$eventさえ渡していれば、何らかの処理後に今回作ったhrefTo()を呼べば良いわけです。
というわけで、これでctrl, cmdを押しながらクリックした場合別タブを開くという動作ができました。
composablesなどに定義しておけば、どこでも使える便利なやつになります。
Nuxt3用に書いてみましたが、よくよく見るとVue.js系ならどこでも使えそうな内容ですね。。。