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 ストレージ エンジン インデックスの実装原理の詳細説明

推薦する

js を使用して年カルーセル選択効果をネイティブに実装する例

序文js を使用して、年の回転選択効果を実現します。では早速、写真を見てみましょう。 1. アイデア...

CSSはコンテンツの高さが足りない場合にフッターを自動的に下部に固定します

UI カットのプロセスでは、ページはヘッダー、コンテンツ、フッターの 3 つの部分で構成されることが...

MySql における無効な Null セグメント判定と IFNULL() 失敗の解決策

MySql Nullフィールド判定とIFNULL失敗処理ps: (プロセスを表示したくない場合は、S...

WeChatミニプログラムページとコンポーネント間の情報伝達と機能呼び出し

今回は、私自身の開発経験を踏まえて、以下の観点で関連内容を解説します。ページからコンポーネントにデー...

Web 上の要素を非表示にする方法とその利点と欠点

ソースコードの例: https://codepen.io/shadeed/pen/03caf6b36...

Linux テキスト検索コマンド find の詳細な使用方法

find コマンドは主にディレクトリやファイルを検索するために使用され、一致のために複数のパラメータ...

Linuxはシェルスクリプトを使用して履歴ログファイルを定期的に削除します

1. ツールディレクトリのファイル構造 [root@www tools]# ツリーツール/ ツール/...

Pythonの関数知識についての簡単な説明

目次関数パラメータの2つの主要なカテゴリ位置パラメータ可変長パラメータ名前空間要約する関数パラメータ...

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

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

CocosCreator クラシック エントリー プロジェクト flappybird

目次開発環境ゲームエンジンのコンセプトCocos Creatorについてプロジェクト構造コード編集環...

テキストエリア テキストエリアの幅と高さ 幅と高さの自動適応実装コード

コードをコピーコードは次のとおりです。 <HTML> <ヘッド> <T...

VueはTeleportをベースにModalコンポーネントを実装します

目次1. テレポートについて知る2. テレポートの基本的な使い方3. 最初のステップの最適化4. 第...

Linux ユーザーとグループのコマンド例分析 [切り替え、ユーザーの追加、権限制御など]

この記事では、Linux のユーザーおよびグループのコマンドについて例を挙げて説明します。ご参考まで...

MySQLの保存時間の不一致の問題を解決する

Java を使用してシステム時間を取得し、それを MySQL データベースに保存した後、時間タイプが...

MySQL グリーンバージョン設定コードと 1067 エラーの詳細

MySQL グリーンバージョン設定コードと 1067 エラーMySQL エンコーディングを表示 &#...