> 文章列表 > IndexedDB的包装器JsStore - 分页功能

IndexedDB的包装器JsStore - 分页功能

IndexedDB的包装器JsStore - 分页功能

          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-paginationbackgroundlayout="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}
}

        以上操作完成后,页面分页功能即完成了,效果如下:

        当然,该分页事务函数还可以再优化一下,以便适应其他数据模型的查询。这里只作演示,不过多讲解,大家可以自己多加了解后,再做更好的优化操作。