This is the 10th day of my participation in the August More Text Challenge. For details, see:August is more challenging

Why secondary encapsulation

In general, in the background management project, the page function involved in the data display will be more places, and there is no table, paging and conditional retrieval. If the code is copy and copy, is not very technical content.

And UI designers on each project have their own ideas.

According to our straight male thought, the color and style of UI components are not good ~ you don’t have to design, I don’t have to change the style, fragrant ~

However, we should respect the work of others. When there is a difference between the design style and the style or layout provided by the UI framework, it should be implemented manually

The other thing is, if you need to change something, if your page is actually copying from copy to copy, then congratulations, some changes have been made.

For all of these reasons, secondary encapsulation of the paging component of the ElementUI should come into being.

Child component code

In the paging subcomponent, there are only three areas we need to focus on

  • What is the current page?
  • How many pages are there,
  • How many pieces of data to display per page

Obviously, by default, the first page must be the first page,

It is up to the user to define how many pieces of data to display per page, and we will give a default value if the user does not choose

How many pages are there? You need to see the total amount of data returned in the background, divided by the amount of data displayed per page.

Based on elementUI paging, we can define our paging component code this way

// components/page/index.vue
<template>
  <el-pagination
    background
    layout="slot, prev, pager, next"
    :current-page.sync="currentPage"
    :page-size="pageSize"
    prev-text="Previous page"
    next-text="Next page"
    :total="count"
    @current-change="handleCurrentChange"
  >
    <span v-html="Article ` total ${count}&nbsp;&nbsp;&nbsp;A total of ${pages} page `" />
  </el-pagination>
</template>
Copy the code

We use the built-in slot component to define some of the personalizations, and then we use script to define the parameters for the subcomponents. In this case, we need two parameters

  1. Total data volume
  2. The number of items displayed per page
props: {
    count: {
      type: Number.default: 0
    },
    pageSize: {
        type: Number.default: 10}},Copy the code

PageSize is the amount of data that I define to be displayed per page. The user can set it as needed. By default, 10 pieces of data are displayed

Then use the compute attribute to calculate how many pages there are

computed: {
    pages() {
      return Math.ceil(this.count / this.pageSize)
    }
},
Copy the code

Also, we need to define the current default page number

Data () {return {currentPage: 1}},Copy the code

Finally, we define the page turn event, which is triggered when the user clicks on a specific page number, or on a previous or next page button

Since we used the.sync modifier to bind to currentPage, this property will automatically accept the updated value, so we don’t need to do any more assignment

Within the event, through the $emit method, we pass the page number of the current jump to the parent component for the updated data

methods: {
    handleCurrentChange(page) {  // Click the page number event to notify the parent component
      this.$emit('pageEvent'.this.currentPage)
    }
}
Copy the code

In this way, a child component is complete.

Let’s see how to use it in a parent component.

Use in the parent component

<template>
<div>
    <el-table v-loading="loading" :data="data"/>
    <my-pagination :count="count" @pageEvent="fetchData" />
</div>
</template>
<script>
// First, we introduce the child component and register it with the parent component
import myPagination from '@/components/page/index'
import { getLog } from '@/api/user'
export default {
    // Then register the child component in the parent component
  components: { myPagination },
  data(){
	return {
		loading: true.page: 1.data: [].count: 0}},methods: {
    fetchData(currentpage) {
      if (typeof currentpage === 'number') { // Switch the page number
        this.page = currentpage
      } else { // Set the current page to 1 when entering search criteria
        this.page = 1
      }
      const { page, searchKey } = this
      getLog({ page, searchKey }).then(r= > {
        this.data = r.results
        this.count = r.count
      }).catch().finally(this.loading = false)}}}</script>
Copy the code

In multiple parent components, we can introduce registration and use it in the same way.

Demand behind if there is any change, we change/components/page/index directly. The vue, without having to use in each place all change at a time.

Let us know in the comments if you have any better ideas