数据代理
在日常开发中,列表数据的分页查询是最为常见的场景,本章的目的是实现一个通用的请求数据代理,减少代码量,提高效率。 最终实现
本章目标
开发无须关心分页查询,条件查询等代码逻辑,只需要配置即可快速实现列表数据的分页查询功能。
例:
<template>
<div>
<div>
<!-- 省略查询html代码 -->
</div>
<el-table
:data="tableList.data"
>
<!-- 省略代码 -->
</el-table>
<el-pagination
@size-change="onSizeChange"
@current-change="onCurrentChange"
:current-page="tableList.pagination.curr"
:page-sizes="[5, 10, 20 ,30]"
:page-size="tableList.pagination.limit"
:total="tableList.pagination.total"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
</div>
</template>
<script lang='ts'>
import { Component, Vue } from "vue-property-decorator";
import { mixinDataStore } from "@/mixin/view/Store";
import { Action } from "vuex-class";
@Component({
name: "GridDemo",
mixins: [mixinDataStore]
})
export default class GridDemo extends Vue {
// 定义在vuex中的请求数据函数,只要返回的是Promise类型即可
@Action("list") gridList: any;
// 预留配置-列表配置
// 列表代理对象
tableList: any = {
// 列表数据源
data: [],
// 代理配置
proxy: {
// 请求数据函数
requestFun: this.gridList,
// 分页每页显示条数字段名称,默认为limit,此参数传递到服务端
limitParam: "pageSize",
// 分页页码字段名称,默认为page,此参数传递到服务端
pageParam: "current",
// 初始化后自动加载数据
autoLoad: true,
// 读取数据相关配置
reader: {
// 数据根节点
rootProperty: "data.data.records",
successProperty: "data.code",
totalProperty: "data.data.total",
messageProperty: "data.data.msg"
}
}
};
}
</script>具体实现
扩展模块结构设计
挂载代理
如上述代码所示我们通过proxy.init(this.tableList);将相应的函数挂在到了tableList上面,那么如何实现呢。
例:
列表数据请求场景一般分为移动端与web端,而这两者对数据结果集的处理逻辑是不一样的,所以这里我们可以把移动端与web端分成两个类,通过代理配置来挂在对应的类。
例:
classic类
modern类
预留扩展
以上代码能够覆盖大部分场景,并不能覆盖全部场景,所以我们需要预留出可扩展部分,将挂载代理中的类放置于promise文件夹中,我们再实现一个代理父类
例
整体结构
在代码实现过程中,我们会封装一些公用函数,那么创建一个帮助类是一个很好的选择
例:
如此,整个数据代理模块目录结构如下

填充代码
入口模块
代理可用配置
type
为了方便扩展,我们需要一个type配置,用来确定代理类型,默认为经典代理即promise.classic
分页配置
为了处理分页等逻辑需要以下配置 1. requestFun -> 请求数据函数 1. pageSize -> 每次加载几条数据,默认为10 1. page -> 当前页码,默认为1 1. limitParam -> 分页每页显示条数字段名称,默认为limit,此参数传递到请求数据函数 1. pageParam -> 分页页码字段名称,默认为page,此参数传递到请求数据函数 1. paginationParam -> 数据源对象接收分页配置节点名称,默认为pagination
defaultParams
默认参数,默认参数会被相同名称新参数覆盖
autoLoad
初始化成功后是否自动调用load函数
reader
读取数据相关配置 1. reader.rootProperty -> 数据根节点名称 1. reader.successProperty -> 判断请求是否成功的节点名称 1. reader.totalProperty -> 数据总数节点名称 1. reader.messageProperty -> 请求失败后失败消息节点名称
扩展配置
预留出一些扩展函数,用来处理一些额外的需求 1. disposeItem -> 处理单个数据对象的函数
数据源可用配置
扩展配置
预留出一些扩展函数,用来处理一些额外的需求 1. failure -> 请求失败后执行函数 1. writerTransform -> 请求数据前处理请求参数函数 1. readerTransform -> 请求数据成功后处理数据结果函数
函数
入口模块我们可以放一些通用逻辑函数,我们可以在里面实现failure、writerTransform扩展配置。
最终代码如下:
promise代理入口模块
函数
不管是移动端还是web端,读取数据的逻辑函数应该是通用的,我们可以在里面实现disposeItem、readerTransform扩展配置。
最终代码如下:
请求数据的函数与返回的数据需要遵循以下规则
此帮助类只是一个代理类,具体分页查询函数还是需要axios等扩展来实现,但是因为设计时考虑了扩展性,可以自定义一些扩展来实现请求数据的功能
返回数据必须是标准json格式数据,并且有以下字段,对应字段名称可以在reader配置中灵活配置,如果返回数据不标准可以用readerTransform函数处理成表格格式
success -> 用于判断请求是否成功
data -> 最终数据结果集
total -> 满足当前条件的数据总数,用于分页
message -> 用于请求失败消息提示
假如后端返回数据格式如下,使用axios请求数据并不做任何处理
代理中reader配置如下即可
promise.classic代理
应该有一个基础函数,然后再此基础函数的基础上封装出相应的扩展函数 最终代码如下
promise.modern代理
待实现,预留的移动端代理
使用时二次扩展
将以上模块发布为npm包,可以通过npm install ux-data-proxy命令直接引入。
一般来说后端返回的数据格式是固定的,请求参数也是固定规则,在实际使用中,我们可以自定义一个帮助类来使用,具体代码如下:
在实际使用场景引入这个类即可,使用方式不用改变
mixin类
大多数情况下,分页查询逻辑都是固定的,所以我们可以封装一个mixin类,在估计视图中直接引入这个mixin即可 代码如下:
结语
移动端代理并未实现,你想好怎么实现了吗?
假如我们需要对本地数据进行分页查询,并且也分区分web端与移动端,你应该怎么去实现这个扩展
你是否尝试封装一个查询组件,这个组件支持校验,条件级联等常用功能呢,你要如何去实现才能保证它具有通用性与可扩展性呢
你是否尝试封装一个列表组件?也许用现成的第三方组件是一个更好的选择哦。
你是否尝试对css进行封装,定制一个通用场景呢?
最后更新于
这有帮助吗?