Heim  >  Artikel  >  Web-Frontend  >  Mit Vue erstellte Paginierungskomponenten wiederverwenden

Mit Vue erstellte Paginierungskomponenten wiederverwenden

php中世界最好的语言
php中世界最好的语言Original
2018-05-03 13:58:211275Durchsuche

Dieses Mal werde ich Ihnen eine Paging-Komponente vorstellen, die durch die Wiederverwendung von Vue erstellt wurde. Was sind die Vorsichtsmaßnahmen für die Wiederverwendung von Vue zum Erstellen einer Paging-Komponente?

Grundstruktur

Die Paginierungskomponente sollte es dem Benutzer ermöglichen, auf die erste und letzte Seite zuzugreifen, sich vorwärts und rückwärts zu bewegen und direkt zu wechseln die Schlussseite.

Die meisten Anwendungen stellen jedes Mal eine API-Anfrage, wenn der Benutzer die Seite wechselt. Wir müssen sicherstellen, dass die Komponente dies zulässt, aber wir möchten eine solche Anfrage nicht innerhalb der Komponente stellen. Auf diese Weise stellen wir sicher, dass Komponenten in der gesamten Anwendung wiederverwendbar sind und Anforderungen in der Betriebs- oder Serviceschicht gestellt werden. Dies können wir erreichen, indem wir anhand der Nummer der Seite, auf die der Benutzer geklickt hat, ein Ereignis auslösen.

Es gibt mehrere Möglichkeiten, die Paginierung auf API-Endpunkten zu implementieren. Für dieses Beispiel gehen wir davon aus, dass die API uns die Anzahl der Ergebnisse für jede Seite, die Gesamtzahl der Seiten und die aktuelle Seite mitteilt. Dies werden unsere dynamischen Requisiten sein.

Wenn die API dagegen nur die Gesamtzahl der Datensätze angibt, können wir die Anzahl der Seiten berechnen, indem wir die Anzahl der Ergebnisse durch die Anzahl der Ergebnisse pro Seite dividieren: totalResults / resultsPerPage .

Wir möchten eine Schaltfläche zur ersten Seite, zur vorherigen Seite, zum Seitennummernbereich, zur nächsten Seite und zur letzten Seite rendern:

[erste] [nächste] [1] [2 ] [3 ] [vorherige] [letzte]

Zum Beispiel ein Effekt wie im Bild unten:

Obwohl wir eine Reihe von Seiten rendern möchten, ist dies der Fall Es wird nicht erwartet, dass alle verfügbaren Seiten gerendert werden. Lassen Sie uns eine Requisite für die sichtbarsten Schaltflächen in unserer Komponente festlegen.

Da wir nun wissen, was die Komponente tun soll und welche Daten sie benötigt, können wir die HTML-Struktur und die erforderlichen Requisiten einrichten.

<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('pagination', {
  template: '#pagination',
  props: {
    maxVisibleButtons: {
      type: Number,
      required: false,
      default: 3
    },
    totalPages: {
      type: Number,
      required: true
    },
    total: {
      type: Number,
      required: true
    },
    currentPage: {
      type: Number,
      required: true
    }
  }
})

Der obige Code registriert eine Paginierungskomponente. Wenn Sie diese Komponente aufrufen:

<p id="app">
  <pagination></pagination>
</p>

Der Effekt, den Sie zu diesem Zeitpunkt sehen, ist wie folgt:

Beachten Sie, dass der Komponente ein wenig Styling hinzugefügt wurde, damit sie besser aussieht.

Ereignisüberwachung

Jetzt müssen wir die übergeordnete Komponente benachrichtigen, wenn der Benutzer auf die Schaltfläche klickt, auf welche Schaltfläche der Benutzer geklickt hat.

Wir müssen für jede Schaltfläche einen Ereignis-Listener hinzufügen. Die v-on-Direktive ermöglicht das Abhören von DOM-Ereignissen. In diesem Beispiel verwende ich die V-On-Verknüpfung, um auf Klickereignisse zu warten.

Um den übergeordneten Knoten zu benachrichtigen, verwenden wir die Methode $emit, um ein Ereignis mit einem Seitenklick auszusenden.

Wir stellen außerdem sicher, dass der Paging-Button nur dann einen aktuellen Status hat, wenn die Seite verfügbar ist. Zu diesem Zweck wird v-bind verwendet, um den Wert des deaktivierten Attributs an die aktuelle Seite zu binden. Wir verwenden immer noch die Tastenkombination :v-bind: .

Um unsere Vorlage sauber zu halten, verwenden wir das berechnete Attribut, um zu prüfen, ob die Schaltfläche deaktiviert ist. Die Verwendung von berechnet wird ebenfalls zwischengespeichert, was bedeutet, dass mehrere Zugriffe auf dieselbe berechnete Eigenschaft das zuvor berechnete Ergebnis zurückgeben, ohne dass die Funktion erneut ausgeführt werden muss, solange sich currentPage nicht ändert.

<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('pagination', {
  template: '#pagination',
  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('pagechanged', 1)
    },
    onClickPreviousPage: function () {
      this.$emit('pagechanged', this.currentPage - 1)
    },
    onClickPage: function (page) {
      this.$emit('pagechanged', page)
    },
    onClickNextPage: function () {
      this.$emit('pagechanged', this.currentPage + 1)
    },
    onClickLastPage: function () {
      this.$emit('pagechanged', this.totalPages)
    }
  }
})

Übergeben Sie beim Aufrufen der Paginierungskomponente totalPages, total und currentPage an die Komponente:

<p id="app">
  <pagination :total-pages="11" :total="120" :current-page="currentPage"></pagination>
</p>
let app = new Vue({
  el: '#app',
  data () {
    return {
      currentPage: 2
    }
  }
})

Führen Sie den obigen Code aus. Es wird ein Fehler gemeldet:

Es ist nicht schwer festzustellen, dass uns in der Paginierungskomponente Seiten fehlen. Aus dem, was zuvor eingeführt wurde, können wir leicht erkennen, dass wir den Wert von Seiten berechnen müssen.

Vue.component('pagination', {
  template: '#pagination',
  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('pagechanged', 1)
    },
    onClickPreviousPage: function () {
      this.$emit('pagechanged', this.currentPage - 1)
    },
    onClickPage: function (page) {
      this.$emit('pagechanged', page)
    },
    onClickNextPage: function () {
      this.$emit('pagechanged', this.currentPage + 1)
    },
    onClickLastPage: function () {
      this.$emit('pagechanged', this.totalPages)
    }
  }
})

Die zu diesem Zeitpunkt erhaltenen Ergebnisse melden keine Fehler mehr. Sie werden den folgenden Effekt im Browser sehen:

Stile hinzufügen

Jetzt macht unsere Komponente alles, was wir ursprünglich wollten, und hat außerdem einige Stile hinzugefügt, damit sie eher wie eine Paginierungskomponente und nicht nur wie eine Liste aussieht.

我们还希望用户能够清楚地识别他们所在的页面。让我们改变表示当前页面的按钮的颜色。

为此,我们可以使用对象语法将HTML类绑定到当前页面按钮上。当使用对象语法绑定类名时,Vue将在值发生变化时自动切换类。

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

Vue.component('pagination', {
  template: '#pagination',
  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('pagechanged', 1)
    },
    onClickPreviousPage: function () {
      this.$emit('pagechanged', this.currentPage - 1)
    },
    onClickPage: function (page) {
      this.$emit('pagechanged', page)
    },
    onClickNextPage: function () {
      this.$emit('pagechanged', this.currentPage + 1)
    },
    onClickLastPage: function () {
      this.$emit('pagechanged', 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: '#app',
  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 相关的属性就加上了:

 

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

iview自定义验证关键词输入框实现方法

Node module模块使用详解(附代码)

Das obige ist der detaillierte Inhalt vonMit Vue erstellte Paginierungskomponenten wiederverwenden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn