ホームページ ウェブフロントエンド jsチュートリアル Vue を使用して再利用可能なページネーション コンポーネントを構築する

Vue を使用して再利用可能なページネーション コンポーネントを構築する

Mar 31, 2018 pm 05:38 PM
javascript ページネーション コンポーネント

ページング コンポーネントは Web プロジェクトで非常に一般的なコンポーネントです。Vue を使用して再利用可能なページング コンポーネントを構築しましょう。基本的な構造と関連するイベントの監視については、この記事を参照してください。

Web アプリケーションのリソース ページングは​​、パフォーマンスに非常に役立つだけではありません。また、ユーザー エクスペリエンスの観点からも非常に便利です。この記事では、Vue を使用して動的で使用可能なページネーション コンポーネントを作成する方法を学びます。

基本構造

ページネーションコンポーネントでは、ユーザーが最初と最後のページにアクセスしたり、前後に移動したり、近くのページに直接切り替えたりできるようにする必要があります。

ほとんどのアプリケーションは、ユーザーがページを変更するたびに API リクエストを作成します。コンポーネントがこれを許可していることを確認する必要がありますが、コンポーネント内でそのようなリクエストを行うことは望ましくありません。このようにして、コンポーネントがアプリケーション全体で再利用可能であり、リクエストがオペレーション層またはサービス層で行われることを保証します。これは、ユーザーがクリックしたページの番号を使用してイベントをトリガーすることで実行できます。

API エンドポイントでページネーションを実装するには、いくつかの方法があります。この例では、API が各ページの結果の数、ページの総数、および現在のページを通知すると仮定します。これらが動的プロップになります。

対照的に、API がレコードの合計数のみを通知する場合は、結果の数をページごとの結果の数で割ることでページ数を計算できます ( totalResults / resultsPerPage )。

最初のページ、前のページ、ページ番号の範囲、次のページ、最後のページにボタンをレンダリングしたいです:

[最初] [次] [1] [2] [3] [前] [最後]

たとえば、以下のようなエフェクト:

一連のページをレンダリングしたいとはいえ、利用可能なすべてのページをレンダリングする必要はありません。コンポーネント内で最も表示されるボタンにプロップを設定できるようにしましょう。

コンポーネントに何をさせたいのか、どのようなデータが必要なのかがわかったので、HTML 構造と必要な props を設定できます。


<template id="pagination">
  <ul class="pagination">
    <li>
      <button type="button">« First</button>
    </li>
    <li>
      <button type="button">«</button>
    </li>
    <!-- 页数的范围 -->
    <li>
      <button type="button">Next »</button>
    </li>
    <li>
      <button type="button">»</button>
    </li>
  </ul>
</template>
Vue.component(&#39;pagination&#39;, {
  template: &#39;#pagination&#39;,
  props: {
    maxVisibleButtons: {
      type: Number,
      required: false,
      default: 3
    },
    totalPages: {
      type: Number,
      required: true
    },
    total: {
      type: Number,
      required: true
    },
    currentPage: {
      type: Number,
      required: true
    }
  }
})
ログイン後にコピー


上記のコードは、このコンポーネントを呼び出すと、ページネーション コンポーネントを登録します。


<p id="app">
  <pagination></pagination>
</p>
ログイン後にコピー


この時点での効果は次のとおりです。

注意、コンポーネントの見栄えを良くし、コンポーネントに少しスタイルを追加することができます。


イベントリスニング

ここで、ユーザーがボタンをクリックしたときに、どのボタンをクリックしたかを親コンポーネントに通知する必要があります。 各ボタンにイベント リスナーを追加する必要があります。 v-on ディレクティブを使用すると、DOM イベントをリッスンできます。この例では、v-on ショートカットを使用してクリック イベントをリッスンします。

親ノードに通知するには、 $emit メソッドを使用して、ページのクリックでイベントを発行します。

また、ページが利用可能な場合、ページング ボタンには現在の状態のみが表示されるようにします。これを行うには、v-bind を使用して、disabled 属性の値を現在のページにバインドします。 :v-bind ショートカット キーを引き続き使用します。

テンプレートをクリーンに保つために、計算された属性を使用してボタンが無効になっているかどうかを確認します。 computed の使用もキャッシュされます。つまり、currentPage が変更されない限り、同じ computed プロパティに複数回アクセスすると、関数を再度実行することなく、以前に計算された結果が返されます。

<template id="pagination">
  <ul class="pagination">
    <li>
      <button type="button" @click="onClickFirstPage" :disabled="isInFirstPage">« First</button>
    </li>
    <li>
      <button type="button" @click="onClickPreviousPage" :disabled="isInFirstPage">«</button>
    </li>
    <li v-for="page in pages">
      <button type="button" @click="onClickPage(page.name)" :disabled="page.isDisabled"> {{ page.name }}</button>
    </li>
    <li>
      <button type="button" @click="onClickNextPage" :disabled="isInLastPage">Next »</button>
    </li>
    <li>
      <button type="button" @click="onClickLastPage" :disabled="isInLastPage">»</button>
    </li>
  </ul>
</template>

Vue.component(&#39;pagination&#39;, {
  template: &#39;#pagination&#39;,
  props: {
    maxVisibleButtons: {
      type: Number,
      required: false,
      default: 3
    },
    totalPages: {
      type: Number,
      required: true
    },
    total: {
      type: Number,
      required: true
    },
    currentPage: {
      type: Number,
      required: true
    }
  },
  computed: {
    isInFirstPage: function () {
      return this.currentPage === 1
    },
    isInLastPage: function () {
      return this.currentPage === this.totalPages
    }
  },
  methods: {
    onClickFirstPage: function () {
      this.$emit(&#39;pagechanged&#39;, 1)
    },
    onClickPreviousPage: function () {
      this.$emit(&#39;pagechanged&#39;, this.currentPage - 1)
    },
    onClickPage: function (page) {
      this.$emit(&#39;pagechanged&#39;, page)
    },
    onClickNextPage: function () {
      this.$emit(&#39;pagechanged&#39;, this.currentPage + 1)
    },
    onClickLastPage: function () {
      this.$emit(&#39;pagechanged&#39;, this.totalPages)
    }
  }
})
ログイン後にコピー


ページネーションコンポーネントを呼び出すとき、totalPages と total と currentPage をコンポーネントに渡します:


<p id="app">
  <pagination :total-pages="11" :total="120" :current-page="currentPage"></pagination>
</p>

let app = new Vue({
  el: &#39;#app&#39;,
  data () {
    return {
      currentPage: 2
    }
  }
})
ログイン後にコピー


上記のコードを実行すると、エラーが報告されます:


ページネーション コンポーネントでページが欠落していることを見つけるのは難しくありません。前に紹介したことから、ページの価値を計算する必要があることがわかります。


Vue.component(&#39;pagination&#39;, {
  template: &#39;#pagination&#39;,
  props: {
    maxVisibleButtons: {
      type: Number,
      required: false,
      default: 3
    },
    totalPages: {
      type: Number,
      required: true
    },
    total: {
      type: Number,
      required: true
    },
    currentPage: {
      type: Number,
      required: true
    }
  },
  computed: {
    isInFirstPage: function () {
      return this.currentPage === 1
    },
    isInLastPage: function () {
      return this.currentPage === this.totalPages
    },
    startPage: function () {
      if (this.currentPage === 1) {
        return 1
      }
      if (this.currentPage === this.totalPages) {
        return this.totalPages - this.maxVisibleButtons + 1
      }
      return this.currentPage - 1
    },
    endPage: function () {
      return Math.min(this.startPage + this.maxVisibleButtons - 1, this.totalPages)
    },
    pages: function () {
      const range = []
      for (let i = this.startPage; i <= this.endPage; i+=1) {
        range.push({
          name: i,
          isDisabled: i === this.currentPage
        })
      }
      return range
    }
  },
  methods: {
    onClickFirstPage: function () {
      this.$emit(&#39;pagechanged&#39;, 1)
    },
    onClickPreviousPage: function () {
      this.$emit(&#39;pagechanged&#39;, this.currentPage - 1)
    },
    onClickPage: function (page) {
      this.$emit(&#39;pagechanged&#39;, page)
    },
    onClickNextPage: function () {
      this.$emit(&#39;pagechanged&#39;, this.currentPage + 1)
    },
    onClickLastPage: function () {
      this.$emit(&#39;pagechanged&#39;, this.totalPages)
    }
  }
})
ログイン後にコピー


この時点で得られた結果は、ブラウザに次のような効果が表示されます:


これでコンポーネントが実装されました。当初意図されていたすべての機能に、単なるリストではなくページネーション コンポーネントのように見えるようにいくつかのスタイルを追加しました。

また、ユーザーが自分が閲覧しているページを明確に識別できるようにしたいと考えています。現在のページを表すボタンの色を変更してみましょう。

これを行うには、オブジェクト構文を使用して HTML クラスを現在のページ ボタンにバインドします。オブジェクト構文を使用してクラス名をバインドする場合、値が変更されると Vue は自動的にクラスを切り替えます。

虽然 v-for 中的每个块都可以访问父作用域范围,但是我们将使用 method 来检查页面是否处于 active 状态,以便保持我们的 templage 干净。


Vue.component(&#39;pagination&#39;, {
  template: &#39;#pagination&#39;,
  props: {
    maxVisibleButtons: {
      type: Number,
      required: false,
      default: 3
    },
    totalPages: {
      type: Number,
      required: true
    },
    total: {
      type: Number,
      required: true
    },
    currentPage: {
      type: Number,
      required: true
    }
  },
  computed: {
    isInFirstPage: function () {
      return this.currentPage === 1
    },
    isInLastPage: function () {
      return this.currentPage === this.totalPages
    },
    startPage: function () {
      if (this.currentPage === 1) {
        return 1
      }
      if (this.currentPage === this.totalPages) {
        return this.totalPages - this.maxVisibleButtons + 1
      }
      return this.currentPage - 1
    },
    endPage: function () {
      return Math.min(this.startPage + this.maxVisibleButtons - 1, this.totalPages)
    },
    pages: function () {
      const range = []
      for (let i = this.startPage; i <= this.endPage; i+=1) {
        range.push({
          name: i,
          isDisabled: i === this.currentPage
        })
      }
      return range
    }
  },
  methods: {
    onClickFirstPage: function () {
      this.$emit(&#39;pagechanged&#39;, 1)
    },
    onClickPreviousPage: function () {
      this.$emit(&#39;pagechanged&#39;, this.currentPage - 1)
    },
    onClickPage: function (page) {
      this.$emit(&#39;pagechanged&#39;, page)
    },
    onClickNextPage: function () {
      this.$emit(&#39;pagechanged&#39;, this.currentPage + 1)
    },
    onClickLastPage: function () {
      this.$emit(&#39;pagechanged&#39;, this.totalPages)
    },
    isPageActive: function (page) {
      return this.currentPage === page;
    }
  }
})
ログイン後にコピー


接下来,在 pages 中添加当前状态:


<li v-for="page in pages">
  <button type="button" @click="onClickPage(page.name)" :disabled="page.isDisabled" :class="{active: isPageActive(page.name)}"> {{ page.name }}</button>
</li>
ログイン後にコピー


这个时候你看到效果如下:


但依然还存在一点点小问题,当你在点击别的按钮时, active 状态并不会随着切换:


继续添加代码改变其中的效果:


let app = new Vue({
  el: &#39;#app&#39;,
  data () {
    return {
      currentPage: 2
    }
  },
  methods: {
    onPageChange: function (page) {
      console.log(page)
      this.currentPage = page;
    }
  }
})
ログイン後にコピー


在调用组件时:


<p id="app">
  <pagination :total-pages="11" :total="120" :current-page="currentPage" @pagechanged="onPageChange"></pagination>
</p>
ログイン後にコピー


这个时候的效果如下了:


到这里,基本上实现了咱想要的分页组件效果。

无障碍化处理

熟悉Bootstrap的同学都应该知道,Bootstrap中的组件都做了无障碍化的处理,就是在组件中添加了WAI-ARIA相关的设计。比如在分页按钮上添加 aria-label 相关属性:


在我们这个组件中,也相应的添加有关于WAI-ARIA相关的处理:


<template id="pagination">
  <ul class="pagination" aria-label="Page navigation">
    <li>
      <button type="button" @click="onClickFirstPage" :disabled="isInFirstPage" aria-label="Go to the first page">« First</button>
    </li>
    <li>
      <button type="button" @click="onClickPreviousPage" :disabled="isInFirstPage" aria-label="Previous">«</button>
    </li>
    <li v-for="page in pages">
      <button type="button" @click="onClickPage(page.name)" :disabled="page.isDisabled" :aria-label="`Go to page number ${page.name}`"> {{ page.name }}</button>
    </li>
    <li>
      <button type="button" @click="onClickNextPage" :disabled="isInLastPage" aria-label="Next">Next »</button>
    </li>
    <li>
      <button type="button" @click="onClickLastPage" :disabled="isInLastPage" aria-label="Go to the last page">»</button>
    </li>
  </ul>
</template>
ログイン後にコピー


这样有关于 aria 相关的属性就加上了:

 

最终的效果如下,可以点击下面的连接访问:


https://codepen.io/airen/pen/mxMLrG

相关推荐:

vue构建一个自动建站项目

vue构建多页面应用实例代码分享


以上がVue を使用して再利用可能なページネーション コンポーネントを構築するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Windows 10 旧バージョンコンポーネント DirectPlay のインストール方法 Windows 10 旧バージョンコンポーネント DirectPlay のインストール方法 Dec 28, 2023 pm 03:43 PM

win10で一部のゲームをプレイすると、画面がフリーズしたり画面がぼやけるなどの不具合が多くのユーザーに発生しますが、現時点ではダイレクトプレイ機能をオンにすることで問題を解決でき、機能の操作方法も非常に簡単です。 win10 の古いコンポーネントである Directplay をインストールする方法 1. 検索ボックスに「コントロール パネル」と入力して開きます 2. 表示方法として大きなアイコンを選択します 3. 「プログラムと機能」を見つけます 4. 左側をクリックして有効にするか、 Win 機能をオフにする 5. ここで古いバージョンを選択します チェックボックスをオンにするだけです

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

Angular コンポーネントとその表示プロパティ: 非ブロックのデフォルト値について Angular コンポーネントとその表示プロパティ: 非ブロックのデフォルト値について Mar 15, 2024 pm 04:51 PM

Angular フレームワークのコンポーネントのデフォルトの表示動作は、ブロックレベルの要素ではありません。この設計の選択により、コンポーネント スタイルのカプセル化が促進され、開発者が各コンポーネントの表示方法を意識的に定義することが促進されます。 CSS プロパティの表示を明示的に設定することで、Angular コンポーネントの表示を完全に制御して、目的のレイアウトと応答性を実現できます。

古いバージョンのwin10コンポーネントの設定を開く方法 古いバージョンのwin10コンポーネントの設定を開く方法 Dec 22, 2023 am 08:45 AM

Win10 の古いバージョンのコンポーネントは、デフォルトで閉じられていることが多いため、ユーザー自身が設定で有効にする必要があります。まず、設定を入力する必要があります。操作は非常に簡単です。以下の手順に従ってください。Win10 の古いバージョンはどこにありますか?バージョン コンポーネント? 開く 1. [スタート] をクリックし、[Win システム] をクリックします 2. クリックしてコントロール パネルに入ります 3. 次に、下のプログラムをクリックします 4. [Win 機能を有効または無効にする] をクリックします 5. ここで必要なものを選択できます開く

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

See all articles