background

A lot of what we do is back-end management systems, and for this kind of system, we find that the business inside is actually quite simple.

A lot of it is like this, search criteria, tables, pagination

Every page should handle page flipping, search, mounted table data and so on

It’s not complicated, but it’s tiring.

Therefore, we need to encapsulate some DSLS to reduce our duplication effort

What is CompositionAPI/hook

Look at the document

Our request is encapsulated in something like this format

// /api/index.js
import API from '@szyx/axios';
// Request interceptor
API.interceptors.request.use((config) = > {
  // xxxx
  return config;
});

// Result interceptor
API.interceptors.response.use(
  (response) = > {
    // Determine the status
    if (response.status === '0') {
      return response.data;
    }
    // Otherwise it is all wrong
    throw new Error(JSON.stringify(response));
  },
  (error) = > {
    throwerror; });export default {
  getExample: (params) = > API.POSTJSON('/xxx/xxx/xxx', params),
};

Copy the code

Extract CompositionAPI

tableCompositions.js

import { ref, onMounted } from 'vue';
import API from '@/api/index';

export default function tableCompositon(params, urlName, pageDefault = 1, pageSizeDefault = 10) {
  // Table data
  const tableData = ref([]);
  / / total
  const total = ref(0);
  // Current page, default 1
  const page = ref(pageDefault);
  // Number of pages, default 10
  const pageSize = ref(pageSizeDefault);

  const getTableData = () = >{ API[urlName]({ ... params,pageNum: page.value,
      pageSize: pageSize.value,
    }).then((data) = > {
      tableData.value = data.list;
      page.value = data.pageNum;
      pageSize.value = data.pageSize;
      total.value = data.total;
    });
  };
  // Page load request
  onMounted(() = > { getTableData(); });

  return {
    tableData,
    total,
    page,
    pageSize,
    getTableData,
  };
}

Copy the code

Argument parsing

  • paramsEntry refers to the current page exceptThe page number.Number of pagesAdditional business parameters are required
  • urlNameIs the method name of the request. As can be seen from the above, the export of our request is a method after encapsulation, such as callgetExampleMethod is passedgetExampleThis string will do.

The return analytic

  • tableDataPage table data, table must be array type data
  • totalHow many pieces of data are there
  • pageThe current page number
  • pageSizeCurrent page count
  • getTableDataMethods to get table data

Content analysis

It should be easy to understand, define some data, a request method, and make a request in onMounted, and return all that stuff out

use

Like a page like this

Omit code related to form popovers

<template> <div class="flex row align-items-center header"> <div class="flex row align-items-center flex1"> <p Class ="title"> </p> <el-input v-model=" namestate. username" placeholder=" username" class="name-input" @keyup.enter="getTableData" /> </div> <div class="flex row "> <el-button type="primary" @click="page.value = 1; getTableData();" </el-button plain @click=" namestate. username ="; getTableData();" </el-button> </div> <div class="table"> < EL-table :data="tableData" border stripe :header-cell-style="tableHeaderStyle" :cell-style="tableCellStyle" > <el-table-column prop="name" label=" user name" Align ="center" /> <el-table-column prop="roleName" label=" roleName" align="center" /> <el-table-column label=" operation" align="center"> <template #default="scope"> <el-button type="primary" v-permission="'100001002'" @click="editUser(scope.row)"> modify </el-button> <el-button type="danger" v-permission="'100001003'" @click="deleteUser(scope.row)"> delete </el-button> </template> </el-table-column> </el-table> </div> <Pagination class="pagination" v-model:total="total" v-model:page="page" v-model:limit="pageSize" @pagination="getTableData" /> </template> <script> import { defineComponent, reactive, } from 'vue'; import Pagination from '@/components/Pagination/index.vue'; import tableCompositions from '@/compositions/tableCompositions'; Export default defineComponent({components: {Pagination}, setup() {const nameState = reactive({username: "}); Const {tableData, getTableData, total, pageSize, page,} = tableCompositions(nameState, 'getUserList', ); return { total, pageSize, page, nameState, tableData, getTableData, }; }}); </script>Copy the code

Probably less than 100 lines of code, and it’s over.

Js basically has no logic. You only need to define the business parameters you need in addition to page and pageSize

Let’s say I need a username for this page

  const nameState = reactive({
      username: ' '});Copy the code

Then pass nameState as a parameter to tableCompositions to get everything

  const {
      tableData, getTableData, total, pageSize, page,
    } = tableCompositions(
      nameState,
      'getUserList',);Copy the code

And then you just throw the tableData directly to the EL-Table

pagination

For pagination, you can just do el-Pagination

We just put in some of the usual ones, just a layer

Pagination/index.vue

<template> <el-pagination :background="background" v-model:current-page="currentPage" v-model:page-size="pageSize" :layout="layout" :page-sizes="pageSizes" :total="total" v-bind="$attrs" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </template> <script> 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 [5, 10, 20, 30, 50]; }, }, layout: { type: String, default: 'total, sizes, prev, pager, next, jumper', }, background: { 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) { console.log('handleSizeChange', val); this.$emit('pagination', { page: this.currentPage, limit: val }); }, handleCurrentChange(val) { console.log('handleCurrentChange', val); this.$emit('pagination', { page: val, limit: this.pageSize }); ,}}}; </script>Copy the code

So the logic on the next page, tied up, ends

  <Pagination
    class="pagination"
    v-model:total="total"
    v-model:page="page"
    v-model:limit="pageSize"
    @pagination="getTableData"
  />
Copy the code

React is the same thing. I won’t put the React code here, but I can wrap it myself

Our purpose is only one: lazy