PHP前端开发

Vue组件实战:分页组件开发

百变鹏仔 3个月前 (09-25) #VUE
文章标签 组件

Vue组件实战:分页组件开发

介绍

在Web应用程序中,分页功能是必不可少的一个组件。一个好的分页组件应该展示简洁明了,功能丰富,而且易于集成和使用。

在本文中,我们将介绍如何使用Vue.js框架来开发一个高度可定制化的分页组件。我们将通过代码示例来详细说明如何使用Vue组件开发。

立即学习“前端免费学习笔记(深入)”;

技术栈

开发环境

分页组件需求

设计思路和代码实现

根据需求,我们将分页组件拆分为多个小组件来实现。我们需要创建以下3个小组件:

  1. Pagination.vue

主分页组件,负责分页数据和逻辑的处理。向子组件传递分页信息和响应子组件的事件。

  1. Button.vue

该组件为按钮组件,用于创建分页按钮。

  1. Page.vue

该组件用于创建单个页面块,包含页面标号和状态。页面块可以是当前页面或非当前页面。

接下来,让我们使用代码来实现以上3个组件。

  1. Pagination.vue
<template>  <div class="pagination-container">    <button-prev :current="current" @onPrev="prev"></button-prev>    <page v-for="page in pages"      :key="page"      :page="page"      :is-selected="page === current"      @on-page-selected="selectPage"></page>    <button-next :current="current" :total="total" @onNext="next"></button-next>  </div></template><script>import ButtonPrev from './ButtonPrev.vue';import ButtonNext from './ButtonNext.vue';import Page from './Page.vue';export default {  components: { ButtonPrev, ButtonNext, Page },  props: {    total: {      type: Number,      default: 10    },    current: {      type: Number,      default: 1    },    maxShown: {      type: Number,      default: 5    },    prevText: {      type: String,      default: '上一页'    },    nextText: {      type: String,      default: '下一页'    }  },  computed: {    pages () {      const start = Math.max(1, this.current - Math.floor(this.maxShown / 2));      const end = Math.min(this.total, start + this.maxShown - 1);      return Array.from({ length: end - start + 1 }, (v, k) => start + k);    }  },  methods: {    selectPage (page) {      if (this.current === page) return;      this.current = page;      this.$emit('onPageChanged', page);    },    prev () {      if (this.current > 1) {        this.selectPage(this.current - 1);      }    },    next () {      if (this.current < this.total) {        this.selectPage(this.current + 1);      }    }  }}</script>

上面的代码中,我们首先import了ButtonPrev、ButtonNext和Page组件。接着,用props方式获取了total, current, maxShown, prevText和nextText属性,并定义了计算属性pages,根据当前页码(current)和最大页码数(maxShown)得到一个包含页码数的数组,以在组件中呈现。

我们还定义了selectPage方法,在该方法中,如果页码(page)与当前页码(current)相同,则返回或不做任何事情。否则,将新页码发出给父组件。

prev()和next()方法用于处理上一页和下一页事件,并防止event被响应。

  1. ButtonPrev.vue
<template>    <button      class="btn-previous"      :disabled="current === 1"      @click="onPrev()">      {{ prevText }}    </button></template><script>export default {  props: {    prevText: {      type: String,      default: '上一页'    },    current: {      type: Number,      default: 1    }  },  methods: {    onPrev () {      this.$emit('onPrev');    }  }}</script><style scoped>.btn-previous {  border: none;  color: #333;  display: inline-block;  font-size: 16px;  padding: 6px 12px;  margin-right: 5px;  background-color:#fff;  cursor: pointer;  border-radius: 2px;  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);}.btn-previous:disabled {  color: #ccc;  cursor: default;}</style>

上述代码中,我们首先通过props获取了当前页码(current)和上一页按钮的文本(prevText)属性。在模版中,使用类绑定(disabled)控制按钮使用状态。定义了一个onPrev方法,该方法触发父组件的onPrev事件。

  1. ButtonNext.vue
<template>    <button      class="btn-next"      :disabled="current === total"      @click="onNext()">      {{ nextText }}    </button></template><script>export default {  props: {    total: {      type: Number,      default: 10    },    nextText: {      type: String,      default: '下一页'    },    current: {      type: Number,      default: 1    }  },  methods: {    onNext () {      this.$emit('onNext');    }  }}</script><style scoped>.btn-next {  border: none;  color: #333;  display: inline-block;  font-size: 16px;  padding: 6px 12px;  margin-left: 5px;  background-color: #fff;  cursor: pointer;  border-radius: 2px;  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);}.btn-next:disabled {  color: #ccc;  cursor: default;}</style>

上述代码中,我们将ButtonPrev.vue的代码复制了一份,稍微改了一下文本和判断条件。

  1. Page.vue
<template>  <button :class="{ current: isSelected }" class="btn-page" @click="onPageSelected(page)">    {{ page }}  </button></template><script>export default {  props: {    page: {      type: Number,      required: true    },    isSelected: {      type: Boolean,      default: false    }  },  methods: {    onPageSelected () {      this.$emit('onPageSelected', this.page);    }  }}</script><style scoped>.btn-page {  border: none;  color: #333;  display: inline-block;  font-size: 16px;  padding: 6px 12px;  margin-left: 5px;  background-color: #fff;  cursor: pointer;  border-radius: 2px;  box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);}.btn-page.current {  background-color: #0078d7;  color: #fff;}</style>

上述代码中,我们通过props获取了该页码的值(page)和按钮的isSelected属性。在模板中,使用类绑定("current")高亮显示选中的页面。

我们还定义了一个onPageSelected方法,该方法会触发父组件的onPageSelected事件。

最后,这些组件可以在任何Vue.js应用程序中的template中使用,如下所示:

<template>  <div>    <pagination      :total="total"      :current="current"      :maxShown="maxShown"      :prevText="prevText"      :nextText="nextText"      @onPageChanged="onPageChanged"></pagination>    <ul>      <li v-for="(item, index) in items" :key="index">{{ item.name }}</li>    </ul>  </div></template><script>import Pagination from './Pagination.vue';export default {  components: {    Pagination  },  data () {    return {      current: 1,      maxShown: 10,      prevText: '上一页',      nextText: '下一页',      total: 10,      pageSize: 10,      items: [{ name: 'Item 1' }, { name: 'Item 2' }, { name: 'Item 3' }]    }  },  methods: {    onPageChanged (page) {      console.log('Page changed to: ', page);      // 当前页面数据请求    }  }}</script>

上述代码中,我们引入了Pagination组件,并将其作为template中的父组件。我们还将total, current和maxShown绑定到组件,以便获取到它们的值。在onPageChanged方法中,我们可以处理页面更改事件,并根据当前页码请求相应的数据。