JsStore是IndexedDB的包装器。它提供了简单的SQL像api,这是容易学习和使用。IndexedDb查询可以在web worker内部执行,JsStore通过提供一个单独的worker文件来保持这种功能。
由于之前使用IndexedDB时,提供api不太丰富,就自己写了一个分页功能函数,后期使用JsStore时一直沿用之前分页功能函数(缺点:需把所有数据查询出来,通过函数进行筛选分页显示);其实JsStore提供了更为方便的分页查询功能,查询Api中提供了skip起始位和limit查询长度属性外,结合事务功能可以实现数据总长度的查询。
这里是在之前“学员管理系统”基础上给大家演示,管理员列表通过JsStore的api来实现分页功能。由于在上篇进行功能叠加,所以登录部分就不作讲解了,自己可以先看这篇后,再来了解该篇分页内容。
地址:https://blog.csdn.net/jiciqiang/article/details/128311568?spm=1001.2014.3001.5501JsStore是IndexedDB的包装器。它提供了简单的SQL像api,这是容易学习和使用。IndexedDb查询可以在web worker内部执行,JsStore通过提供一个单独的worker文件来保持这种功能。这里将之前使用IndexedDB写的登录功能,改为JsStore来实现。对于事务,简单的理解就是,一个事务里的操作,要么全部执行成功,要么全部执行失败。https://blog.csdn.net/jiciqiang/article/details/128311568?spm=1001.2014.3001.5501
需要实现效果图如下:
一、页面开发
在上篇“IndexedDB的包装器JsStore - 实现登录功能及事务处理”上,路由定义中已创建好“/sys/index”路由地址作为管理员列表页显示。这里先完善页面列表显示样式及相关变更、函数的定义。index.vue中代码如下:
html代码:
<template>
<div class="index-wrap">
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>管理员列表</el-breadcrumb-item>
</el-breadcrumb>
<br /><br />
<div class="filter-wrap">
<div class="item left">
<el-form :inline="true" class="demo-form-inline">
<el-form-item label="账号">
<el-input size="small" v-model="keyword" placeholder="请输入账号"></el-input>
</el-form-item>
<el-form-item>
<el-button size="small" type="primary" @click="updateUserList">查询</el-button>
</el-form-item>
</el-form>
</div>
<div class="item right">
</div>
</div>
<div class="table-wrap">
<el-table
:data="tableList"
style="width: 100%">
<el-table-column prop="username" label="账号"></el-table-column>
<el-table-column prop="createtime" label="创建日期"></el-table-column>
<el-table-column prop="updatetime" label="更新日期"></el-table-column>
</el-table>
<div style="padding-top: 30px; text-align: right;">
<el-pagination
background
layout="prev, pager, next"
:page-size="pageSize"
:total="pageTotal"
@current-change="currentPageChange">
</el-pagination>
</div>
</div>
</div>
</template>
javascript代码:
<script>
export default {
data () {
return {
//查询关键字
keyword: "",
/**
* 列表数据
*/
tableList: [],
page: 1,
pageSize: 5,
pageTotal: 13,
}
},
created() {
},
methods: {
/**
* 分页事件
*/
currentPageChange(e){
this.page = e;
this.updateUserList();
},
/**
* 获取用户列表数据
*/
updateUserList(){
},
//end
}
}
</script>
页面效果如下:
二、分页查询
2.1 用户模型中添加查询函数
在上篇“IndexedDB的包装器JsStore - 实现登录功能及事务处理”中,db/model/user.js创建了用户模型类,在这里我们添加分页查询getPageList()函数。
对传入参数进行判断,保证必须字段完整性。代码如下:
import connection from "@/db/index.js";
export class UserService {
constructor(){
this.tableName = "Users";
}
//略...
/**
* 分页查询功能
* @param {Object} params
*/
getPageList(params){
params = 'undefined'===typeof params ? { page: 1, pageSize: 10 } : params;
if('undefined'===typeof params['page']) params['page'] = 1;
if('undefined'===typeof params['pageSize']) params['pageSize'] = 10;
return connection.select({
from: this.tableName,
skip: (params.page - 1) * params.pageSize, //查询超始位置
limit: params.pageSize, //查询范围
order: {
by: "updatetime",
type: "desc"
},
})
}
//略...
}
2.2 API接口中添加查询函数
然后在api/index.js中,添加分页查询getPageDataList()函数,代码如下:
import { UserService } from '@/db/model/user'
const Users = new UserService();
/**
* 获取分页参数
*/
export const getPageDataList = (params) => {
return Users.getPageList(params);
}
/**
* 登录
*/
export const loginInfo = (params) => {
return Users.login(params);
}
//略...
2.3 引入页面查询数据列表
在index.vue的updateUserList()函数中执行getPageDataList()函数,进行分页查询。获取到当前分页范围数据列表后,将日期进行格式化,并通过map生成新数组赋值给tableList变量。
import { getPageDataList } from '@/api'
import { formatDate } from '@/utils/utils'
export default {
data () {
return {
//查询关键字
keyword: "",
/**
* 列表数据
*/
tableList: [],
page: 1,
pageSize: 5,
pageTotal: 0,
}
},
created() {
this.updateUserList();
},
methods: {
/**
* 分页改变
*/
currentPageChange(e){
this.page = e;
this.updateUserList();
},
/**
* 获取用户列表数据
*/
updateUserList(){
let param = {
page: this.page,
pageSize: this.pageSize
}
if(this.keyword){
param['where'] = {
username: this.keyword
}
}
//查询数据
getPageDataList(param).then(res => {
this.tableList = res.map(item => {
item['createtime'] = formatDate(item.createtime);
item['updatetime'] = formatDate(item.updatetime);
return item;
});
console.log('getPageDataList', res);
}).catch(e => {
console.error(e);
});
//ajax end
},
//end
}
}
目前这些操作完成后,页面只有一条当前登录账号信息,所以这里我们需要手动插入多条测试数据,来完成分页功能的数量。在create()函数中,运行一次循环追加10条测试用户数据。addUserInfo()在上一篇中已使用,这里不再详解。代码如下:
created() {
for(var i = 0; i < 10; i++){
addUserInfo({
username: "test-admin-" + i,
password: "123456",
role: 2
});
}
this.updateUserList();
}
完后数据插入后,注释掉该代码:
created() {
/*
for(var i = 0; i < 10; i++){
addUserInfo({
username: "test-admin-" + i,
password: "123456",
role: 2
});
} */
this.updateUserList();
}
获取数据列表结构如下图:
此时页面效果如下:
我们把变量page改成2后,则可以查询到第2页的数据,代码如下:
data () {
return {
//查询关键字
keyword: "",
/**
* 列表数据
*/
tableList: [],
page: 2,
pageSize: 5,
pageTotal: 0,
}
}
页面效果如下:
三、结合事务获取分页数
前面已完成了分页查询功能,但是这里还缺少一个数据,当前条件下数据的总条数。这里需要结合事务,同时查询到总条数和当前页数据列表。事务在上一篇中已使用,还在之前的transaction.js中创建getPageData()函数,用来实现事务的查询。添加如下代码:
const userTableName = "Users";
/**
* 获取分页数据
* @param {Object} ctx
*/
async function getPageData(ctx){
}
//获取分页数据
window.getPageData = getPageData;
3.1 开始事务
执行start()函数开始事务,并准备查询条件,当where对象存在并且搜索关键字用户名存在时,才具备条件查询,否则不创建where条件。
/**
* 获取分页数据
* @param {Object} ctx
*/
async function getPageData(ctx){
ctx.start();
let whereData = {};
if('undefined'!==typeof ctx.data.where
&& 'undefined'!== typeof ctx.data.where['username']
){
whereData['where'] = ctx.data.where;
}
}
3.2 查询总条数
通过JsStore的count()函数实现条件查询。
/**
* 获取分页数据
* @param {Object} ctx
*/
async function getPageData(ctx){
ctx.start();
let whereData = {};
if('undefined'!==typeof ctx.data.where
&& 'undefined'!== typeof ctx.data.where['username']
){
whereData['where'] = ctx.data.where;
}
//查询条件内数据总数
const count = await ctx.count({
from: userTableName,
...whereData
});
}
3.3 查询当前页数据列表
通过JsStore的select()函数查询当前页列表数据,公式:page - 1 * pageSize 计算出每页起始位置,limit为查询长度。
/**
* 获取分页数据
* @param {Object} ctx
*/
async function getPageData(ctx){
ctx.start();
let whereData = {};
if('undefined'!==typeof ctx.data.where
&& 'undefined'!== typeof ctx.data.where['username']
){
whereData['where'] = ctx.data.where;
}
//查询条件内数据总数
const count = await ctx.count({
from: userTableName,
...whereData
});
const data = await ctx.select({
from: userTableName,
skip: (ctx.data.page - 1) * ctx.data.pageSize,
limit: ctx.data.pageSize,
order: {
by: "updatetime",
type: "desc"
},
...whereData
});
}
3.4 返回数据结果
通过setResult()函数,返回相应数据。
/**
* 获取分页数据
* @param {Object} ctx
*/
async function getPageData(ctx){
ctx.start();
let whereData = {};
if('undefined'!==typeof ctx.data.where
&& 'undefined'!== typeof ctx.data.where['username']
){
whereData['where'] = ctx.data.where;
}
//查询条件内数据总数
const count = await ctx.count({
from: userTableName,
...whereData
});
const data = await ctx.select({
from: userTableName,
skip: (ctx.data.page - 1) * ctx.data.pageSize,
limit: ctx.data.pageSize,
order: {
by: "updatetime",
type: "desc"
},
...whereData
});
ctx.setResult('code', 0);
ctx.setResult('msg', "查询成功~");
ctx.setResult('data', {
data,
count,
page: ctx.data.page,
pageSize: ctx.data.pageSize
});
}
3.5 用户模型分页函数修改
事务功能完成后,我们将其引入到db/model/user.js中,通过事务查询返回对应数据。getPageList()函数改造代码如下:
import connection from "@/db/index.js";
import { hex_md5 } from '@/utils/md5'
import { randomStrName } from '@/utils/utils'
import '../transaction.js'
export class UserService {
constructor(){
this.tableName = "Users";
}
//略...
/**
* 分页查询功能
* @param {Object} params
* @date 2023/4/21
*/
getPageList(params){
params = 'undefined'===typeof params ? { page: 1, pageSize: 10 } : params;
if('undefined'===typeof params['page']) params['page'] = 1;
if('undefined'===typeof params['pageSize']) params['pageSize'] = 10;
return connection.transaction({
tables: [this.tableName],
method: "getPageData",
data: {
where: params['where'],
page: params.page,
pageSize: params.pageSize
}
})
}
/* getPageList(params){
params = 'undefined'===typeof params ? { page: 1, pageSize: 10 } : params;
if('undefined'===typeof params['page']) params['page'] = 1;
if('undefined'===typeof params['pageSize']) params['pageSize'] = 10;
return connection.select({
from: this.tableName,
skip: (params.page - 1) * params.pageSize,
limit: params.pageSize,
order: {
by: "updatetime",
type: "desc"
},
})
} */
//略...
}
此时返回的数据结果如下图:
3.6 列表页中数据结果调整
因返回数据结构变化,所以列表页中updateUserList()函数须稍作调整一下。代码如下:
import { addUserInfo, getPageDataList } from '@/api'
import { formatDate } from '@/utils/utils'
export default {
data () {
return {
// 查询关键字
keyword: "",
// 列表数据
tableList: [],
page: 1,
pageSize: 5,
pageTotal: 0,
}
},
created() {
this.updateUserList();
},
methods: {
/**
* 分页改变
* @date 2023/4/21
*/
currentPageChange(e){
this.page = e;
this.updateUserList();
},
/**
* 获取用户列表数据
*/
updateUserList(){
let param = {
page: this.page,
pageSize: this.pageSize
}
if(this.keyword){
param['where'] = {
username: this.keyword
}
}
//查询数据
getPageDataList(param).then(res => {
if(res.code==0){
this.pageTotal = res.data.count;
this.tableList = res.data.data.map(item => {
item['createtime'] = formatDate(item.createtime);
item['updatetime'] = formatDate(item.updatetime);
return item;
});
}
}).catch(e => {
console.error(e);
});
//ajax end
},
/* updateUserList(){
let param = {
page: this.page,
pageSize: this.pageSize
}
if(this.keyword){
param['where'] = {
username: this.keyword
}
}
//查询数据
getPageDataList(param).then(res => {
this.tableList = res.map(item => {
item['createtime'] = formatDate(item.createtime);
item['updatetime'] = formatDate(item.updatetime);
return item;
});
console.log('getPageDataList', res);
}).catch(e => {
console.error(e);
});
//ajax end
}, */
//end
}
}
以上操作完成后,页面分页功能即完成了,效果如下:
当然,该分页事务函数还可以再优化一下,以便适应其他数据模型的查询。这里只作演示,不过多讲解,大家可以自己多加了解后,再做更好的优化操作。