咱們作的大量都是後臺管理系統,對於這種系統,咱們會發現,裏面的業務其實至關單一。html
大量都是相似這種, 搜索條件,表格,分頁vue
每一個頁面都要處理上下翻頁,搜索,mounted加載首頁table數據等等邏輯react
雖然不復雜,但很累。ios
所以,咱們須要封裝一些DSL
來下降咱們的重複工做量axios
看看文檔api
// /api/index.js
import API from '@szyx/axios';
// 請求攔截器
API.interceptors.request.use((config) => {
// xxxx
return config;
});
// 結果攔截器
API.interceptors.response.use(
(response) => {
// 判斷狀態
if (response.status === '0') {
return response.data;
}
// 不然都是錯了
throw new Error(JSON.stringify(response));
},
(error) => {
throw error;
},
);
export default {
getExample: (params) => API.POSTJSON('/xxx/xxx/xxx', params),
};
複製代碼
tableCompositions.js數組
import { ref, onMounted } from 'vue';
import API from '@/api/index';
export default function tableCompositon(params, urlName, pageDefault = 1, pageSizeDefault = 10) {
// 表格數據
const tableData = ref([]);
// 總量
const total = ref(0);
// 當前頁面,默認1
const page = ref(pageDefault);
// 頁面數量,默認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;
});
};
// 頁面加載請求
onMounted(() => { getTableData(); });
return {
tableData,
total,
page,
pageSize,
getTableData,
};
}
複製代碼
params
入參是指當前頁面除了頁碼
,分頁數量
之外還須要的業務參數urlName
是指請求的方法名,上面能夠看到咱們的請求封裝完之後的導出都是一個個的方法,例如調用getExample
方法,則傳遞getExample
這個字符串便可。tableData
頁面的表格數據,表格確定是數組類型的數據total
一共多少條數據page
當前頁碼pageSize
當前分頁數getTableData
獲取表格數據的方法應該很簡單,都能看懂,定義了一些數據,一個請求方法,還有onMounted
中發起請求,而後return
了這些東西出去markdown
好比像這樣的一個頁面flex
省略掉表單彈窗相關的代碼ui
<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="用戶名稱"
class="name-input"
@keyup.enter="getTableData"
/>
</div>
<div class="flex row ">
<el-button type="primary" @click="page.value = 1;
getTableData();">
搜索
</el-button>
<el-button plain @click="nameState.username = '';getTableData();">清空</el-button>
</div>
</div>
<div class="table">
<el-table :data="tableData" border stripe
:header-cell-style="tableHeaderStyle" :cell-style="tableCellStyle"
>
<el-table-column prop="name" label="用戶名" align="center" />
<el-table-column prop="roleName" label="角色名稱" align="center" />
<el-table-column label="操做" align="center">
<template #default="scope">
<el-button type="primary" v-permission="'100001002'" @click="editUser(scope.row)">
修改
</el-button>
<el-button type="danger" v-permission="'100001003'" @click="deleteUser(scope.row)">
刪除
</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: '',
});
// 獲取table數據
const {
tableData, getTableData, total, pageSize, page,
} = tableCompositions(
nameState,
'getUserList',
);
return {
total,
pageSize,
page,
nameState,
tableData,
getTableData,
};
},
});
</script>
複製代碼
大概不到100行的代碼,就結束了。
js基本沒什麼邏輯。只須要定義除page
和pageSize
之外還須要的業務參數
好比我這個頁面還須要一個用戶名
const nameState = reactive({
username: '',
});
複製代碼
而後將nameState
做爲參數傳遞給tableCompositions
,獲取全部的東西
const {
tableData, getTableData, total, pageSize, page,
} = tableCompositions(
nameState,
'getUserList',
);
複製代碼
而後tableData
直接丟給el-table
就好了
至於pagination
,其實直接用el-pagination
就能夠了
咱們也只是把一些經常使用的放進去,包了一層而已
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>
複製代碼
因此上下頁的邏輯,往上一綁,就結束了
<Pagination class="pagination" v-model:total="total" v-model:page="page" v-model:limit="pageSize" @pagination="getTableData" />
複製代碼
react也同樣,我這裏就不放react代碼了,能夠本身封裝一下