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の具体的なコードを参考までに共有します。具体的な内...

select count() と select count(1) の違いと実行方法

Count(*) または Count(1) または Count([column]) は、おそらく S...

一般的な JavaScript メモリ エラーと解決策

目次1. タイマー監視2. イベント監視3.オブザーバー4. ウィンドウオブジェクト5. DOM参照...

アップロード画像コントロールを実現するネイティブ js

この記事の例では、アップロード画像コントロールを実装するためのjsの具体的なコードを参考までに共有し...

React 入門レベルの詳細なメモ

目次1. Reactの基本的な理解1. はじめに2. Reactの特徴3. Reactが効率的な理由...

CSS は、小さな鋭角のチャット ダイアログ ボックスで鋭角の吹き出し効果を実現します。

1. CSS を使用して、小さな尖った角のチャット ダイアログ ボックスと尖った角の吹き出しを描画...

Tableとdivの簡単な紹介と使い方

ウェブフロントエンド1学生証名前性別年01張三男20 02李思女性21総人数60フォームのコンポーネ...

MySQLアカウントのIP制限条件を変更する方法

序文最近、仕事で、MySQL ユーザーの権限を変更するには、特定の IP アドレスへのアクセスを制限...

CentOS7 64 ビットでの MySQL 5.7 のインストールと設定のチュートリアル

インストール環境: CentOS7 64ビットMINI版、MySQL5.7をインストール1. YUM...

...

MySql データベースのサブクエリと高度なアプリケーションの簡単な分析

MySql データベースのサブクエリ:サブクエリ: 選択クエリ ステートメント内に別の選択ステートメ...

Dockerfile を使用して Docker イメージをカスタマイズする方法

Dockerfile を使用したイメージのカスタマイズイメージのカスタマイズとは、実際には各レイヤー...

Django は Pillow を使用して検証コード機能を簡単に設定します (Python)

1. モジュールをインポートし、検証状態を定義する PIL から Image、ImageDraw、...

cobbler ベースの Linux システムを自動的にインストールする

1. コンポーネントをインストールする yum install epel-rpm-macros.no...