@[TOC]

background

Vue-admin-element is a popular open source project, which has a secondary encapsulation of el-Pagination component, pagination. This article will sort out the application of Sync when encapsulation of this component.

Paging plug-in

The pagination component provided by Element-UI is el-Pagination, which is fairly powerful. The main properties related to pagination are summarized as follows:

Encapsulates the code

Encapsulate the two events of El-Pagination as a unified function that triggers the parent component to receive the latest pageSize and currentPage parameters and update the list of the parent component. Encapsulation in open source projects is as follows:

<template>
  <div :class="{'hidden':hidden}" class="pagination-container">
    <el-pagination
      :background="background"
      :current-page.sync="currentPage"
      :page-size.sync="pageSize"
      :layout="layout"
      :page-sizes="pageSizes"
      :total="total"
      v-bind="$attrs"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<script>
import { scrollTo } from '@/utils/scroll-to'

export default {
  name: 'Pagination',
  props: {
    total: {
      required: true.type: Number
    },
    page: {
      type: Number,
      default: 1
    },
    limit: {
      type: Number,
      default: 20
    },
    pageSizes: {
      type: Array,
      default() {
        return [10, 20, 30, 50]
      }
    },
    layout: {
      type: String,
      default: 'total, sizes, prev, pager, next, jumper'
    },
    background: {
      type: Boolean,
      default: true
    },
    autoScroll: {
      type: Boolean,
      default: true
    },
    hidden: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    currentPage: {
      get() {
        return this.page
      },
      set(val) {
        this.$emit('update:page', val)
      }
    },
    pageSize: {
      get() {
        return this.limit
      },
      set(val) {
        this.$emit('update:limit', val)
      }
    }
  },
  methods: {
    handleSizeChange(val) {
      this.$emit('pagination', { page: this.currentPage, limit: val })
      if (this.autoScroll) {
        scrollTo(0, 800)
      }
    },
    handleCurrentChange(val) {
      this.$emit('pagination', { page: val, limit: this.pageSize })
      if (this.autoScroll) {
        scrollTo(0, 800)
      }
    }
  }
}
</script>

<style scoped>
.pagination-container {
  background: #fff;
  padding: 32px 16px;
}
.pagination-container.hidden {
  display: none;
}
</style>
Copy the code

The core code is the currentPage and pageSize computed properties:

this.$emit('update:limit', val)
Copy the code

The encapsulated component parameters include el-Pagination itself, plus a Pagination event.

A component reference

<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
Copy the code

The parent component needs to provide a listening event @pagination, whose function definition receives a JSON object triggered by the Pagination component to refresh the parent component’s list data.

This.$emit(‘update:page’, val) is used to emit bidirectional binding data from the child component via this.$emit(‘update:page’, val).

Vue Sync basics

There are many ways for a parent component to pass data to its child component, and props is one of them. However, its limitation is that data can only be transmitted in one direction. The child component cannot directly modify prop properties.

Vue provides one syntactic sugar, sync, which is an elegant way to trigger prop passed by the parent component.

update
prop
page
sync