Vue 3 で Vue Router リンクを拡張する方法

Vue 3 で Vue Router リンクを拡張する方法

序文

<router-link> タグは、Vue アプリ内のさまざまなページ間を移動するための優れたツールですが、外部リンクに移動するためのツールではありません。そのためには、通常の <a> タグを使用する必要があります。たぶん私だけかもしれませんが、多くの場合、違いを気にする気にはなりません。また、リンクは動的である場合もあります。つまり、データベースまたはユーザーが提供するデータ ソースからリンクが取得される場合もあります。この場合、リンクが外部リンクか内部リンクかはわかりません。また、このリンクが使用される可能性のあるすべての場所で V-if を手動で実行するのは面倒です。

すべての内部リンクと外部リンクを処理する単一のコンポーネントがあれば便利だと思いませんか?あなたも私と同じようなら、今まさにこれをやっているはずです。

ありがたいことに、<router-link> コンポーネントを拡張するのは非常に簡単です。独自のカスタム コンポーネントでラップするだけです。始めましょう! 外部リンクでも内部リンクでも、あらゆるリンクを処理できる AppLink コンポーネントを構築しましょう。

AppLink コンポーネント

最初に行うべきことは、AppLink コンポーネントがルーター リンクと同じプロパティをすべて受け入れるようにすることです。なぜ?この方法では、コンポーネントの「インターフェース」が Router Link のインターフェースを模倣できるため、覚えておくべき別の API がなくなります。これを実現するには、Vue Router から RouterLink をインポートし、そのプロパティをコンポーネントの props オプションに展開します。

// アプリリンク.vue
<スクリプト>
'vue-router' から {RouterLink} をインポートします。
エクスポートデフォルト{
  プロパティ:{ ...RouterLink.props }
}
</スクリプト>

テンプレート領域で、ルーター リンク タグを作成し、すべてのコンポーネントのプロパティをそれにバインドできるようになりました。また、タグ間に提供されたテキストとマークアップがルーター リンクに表示されるように、スロットを渡す必要があります。

// アプリリンク.vue
<テンプレート>
  <router-link v-bind="$props"><スロット /></router-link>
</テンプレート>

現時点では、すべての内部リンクの処理が完了しています。では、外部リンクはどうでしょうか?前述したように、外部リンクでは a タグが使用されるので、それをテンプレートに追加しましょう。 router-link と同様に、スロットを渡す必要があります。 href を to 属性にもバインドしましょう。

// アプリリンク.vue
<テンプレート>
  <a :href="to" rel="外部 nofollow" rel="外部 nofollow" ><slot/></a>
  <ルーターリンク v-bind="$props"><スロット/></ルーターリンク>
</テンプレート>

内部リンクと外部リンクについて説明しました。この時点で、上記の方法は、ルート要素が 1 つ以上含まれているため、Vue 3 でのみ機能することに注意してください。

ここで必要なのは、AppLink に提供するリンクの種類を指定するための条件だけです。これを判断するために、isExternal という計算プロパティを作成できます。まず、to プロパティの値が文字列かどうかを確認します。これが必要なのは、to プロパティがオブジェクトである場合があり、たとえば router-link に渡される場合があるためです (つまり、to="{name:'RouteNameHere'}" )。次に、文字列が http という文字列で始まるかどうかを確認します。これら両方の条件が当てはまる場合、外部リンクが存在します。

// アプリリンク.vue
<スクリプト>
エクスポートデフォルト{
   //...
  計算:{
    外部(){
      戻り値の型は this.to === 'string' && this.to.startsWith('http') です
    }
  }
}
</スクリプト>

router-link はテンプレート領域にあるので、 の場合は v-if で isExternal 計算プロパティを使用できるようになりました。それ以外の場合は true が表示されます。

// アプリリンク.vue
<テンプレート>
  <a v-if="isExternal" :href="to" rel="external nofollow" rel="external nofollow" ><slot/></a>
  <ルーターリンク v-else v-bind="$props"><スロット/></ルーターリンク>
</テンプレート>

これで完了です。コンポーネントをアプリケーションにグローバルに登録したら、次のように使用できるようになります。

// アプリ内のどこでも
<AppLink :to="[external-or-internal-link]">クリックしてください</AppLink>

さらなる柔軟性

新しいタブで開く

AppLink コンポーネントをさらに便利なものにしましょう。たとえば、すべての外部リンクを常に新しいタブで開くようにしたいとします。とても簡単です。コンポーネントの <a> タグに target="_blank" を追加するだけで、サイト全体のすべての外部リンクが新しいタブで開くようになります。

// アプリリンク.vue
<テンプレート>
  <a ... target="_blank"><スロット/></a>
  ...
</テンプレート>

これは、サイト上のほとんどの外部リンクに適用するルールですが、特定の外部リンクを同じタブで開くようにしたい場合は、html ターゲット属性を使用してそのリンク インスタンスにそのように指示できます。

<AppLink :to="https://vueschool.io" target="_self">Vue スクール</AppLink>

リンクセキュリティ

target="_blank" 属性を使用して別の Web サイトのページにリンクすると、Web サイトのパフォーマンスとセキュリティの問題が発生することになります。

  • リンクされたページは、あなたのページと同じプロセスで実行される可能性があります。リンク先のページによっては、自分のページの速度が低下する可能性があります。
  • 別のページも window.opener プロパティを通じて元のページ ウィンドウにアクセスできるため、セキュリティ上の問題が発生する可能性があります。

この問題の詳細については、この有益な投稿を参照してください。

この問題の解決策は、すべての外部リンク タグに rel="noopener" 属性を付与することです。しかし、そうすることがいかに苦痛であるかを思い出してください…ああ、待ってください…そうする必要はありません。 AppLink コンポーネントに一度追加するだけで済みます。

// アプリリンク.vue
<テンプレート>
  <a ... rel="noopener"><スロット/></a>
  ...
</テンプレート>

外部リンクのユニークなスタイル

いくつかのサイトでは、サイト内の外部リンクのスタイルが、サイト内の他の場所につながるリンクとは少し異なっているのを見たことがあります。これにより、ユーザーは、当初訪問していなかったサイトにどのようにたどり着いたのかをよりよく理解できるようになります。リンクの横にある控えめな「外部リンク」アイコンから、リンクの下に「サードパーティのサイトへのリンクです」などと書かれた小さな警告まで、何でもかまいません。コンポーネントにこれを実装するのは、テンプレートの a タグに external-link クラスを追加し、CSS でスタイルを設定するか、:after sudo 要素を追加するだけです。 Font Awesome アイコンのようなまったく新しい要素を外部リンクに追加することもできます。

// アプリリンク.vue
// (プロジェクトに font awesome フォントが含まれている必要があります)
<テンプレート>
  <a ... class="external-link">
    <スロット/> <i class="fas fa-external-link-alt"></i>
  </a>
  ...
</テンプレート>

<スタイルスコープ>
.外部リンク i {
  フォントサイズ: 0.8em;
  不透明度: 0.7;
}
</スタイル>

要約する

これは、一般的なニーズや特殊なケースのニーズに合わせて router-link を拡張する方法のほんの一例です。さらに、すべてのリンクが 1 つのコンポーネントにカプセル化されているため、すべてのリンクのさまざまな側面を簡単に更新できます。 AppLink コンポーネントを改善するための他の便利な方法を思いつきますか?あなたのアプリケーションでも同様のアプローチを使用しており、共有できる知恵はありますか?

Vue 3 で Vue Router リンクを拡張する方法に関するこの記事はこれで終わりです。Vue3 拡張 Vue Router リンクの関連コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vue3ルーティングVueRouter4を使用する簡単な例
  • vue-router 4 の使用例の詳しい説明

<<:  tomcat をインストールし、Linux で Web サイトを展開します (推奨)

>>:  MySQL 学習 (VII): Innodb ストレージ エンジン インデックスの実装原理の詳細説明

推薦する

nginxのデフォルトポートを変更する方法の詳細な説明

まず設定ファイルがどこにあるか調べる nginx.confはどこにありますかこれらのディレクトリを調...

Day.js をベースにした JavaScript での日付処理のよりエレガントな方法

目次day.js を使用する理由モーメントデイ.js day.js がなければどうなるでしょうか? ...

Win10 での MySQL 8.0 ログインでユーザー 'root'@'localhost' のアクセスが拒否される (パスワード使用: YES) 問題の解決方法

最近、MySQL を学び始めました。インストールはスムーズに進み、インターネット上の既成のチュートリ...

ウォーターフォールレイアウト+ダイナミックレンダリングの実装

目次典型的なウォーターフォールウェブサイトウォーターフォールフローレイアウトの原則一般的な考え方具体...

KVM 仮想マシンのオンライン ホット マイグレーションを実装する方法 (画像とテキスト)

1. KVM仮想マシンの移行方法と注意すべき点KVM 仮想マシンを移行する方法は 2 つあります。...

Vueモバイル端末に最適な適応ソリューションについての簡単な説明

序文: 最近の医療モバイル プロジェクトに基づいて、Vue はさまざまな画面のさまざまな画面サイズに...

CentOS7 環境で gcc (バージョン 10.2.0) をアップグレードする詳細な手順

目次簡単な紹介1. 現在のgccバージョンを確認する2. gccインストールパッケージ(バージョン1...

dockerでデプロイされたjenkinsでgitプログラムを実行する際の問題について

1. まず、gitを関連付けるときにエラーメッセージが報告されます: エラー: ビルドするリビジョン...

MySQLを5.7にアップグレードすると、WordPressはデータをインポートするときにエラー1067を報告します

最近MySQLを5.7にアップグレードしましたが、WordPressでデータのインポート時にエラーが...

Alibaba Cloud Centos7.3 インストール mysql5.7.18 rpm インストール チュートリアル

MariaDBをアンインストールするCentOS7 ではデフォルトで MySQL の代わりに Mar...

IDEAでVUEプロジェクトをデバッグするための詳細な手順

js コードをデバッグするには、コード内にデバッガーを記述するか、Chrome で毎回ブレークポイン...

MySQL の非主キー自己増分使用例の分析

この記事では、例を使用して、MySQL の非主キーの自己増分の使用方法を説明します。ご参考までに、詳...

MySQL 最適化接続最適化

記事「MySQL の最適化: キャッシュの最適化」では、システムによってコンパイルされた変数値、また...

MySQL グローバルロックとテーブルレベルロックの具体的な使用法

目次序文グローバルロックテーブルロックテーブルロックメタデータ ロック (MDL ロック)要約する参...