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-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.0 参数配置

属性描述
selectselect api用于从数据库中选择数据。
        -- skip用于指定要跳过的记录数。只有select选项可用。通过(page - 1) * pageSize计算
        -- limit用于指定要返回的记录数。只有select选项可用。即pageSize

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.0 参数配置

参数配置

方法描述 
transaction()IndexedDB是一个纯事务性数据库,这意味着所有查询都是使用事务执行的。JsStore提供了用于执行事务的事务api。

事务包含以下属性和方法:

方法描述
start()启动事务
select()用于从数据库中选择数据。
count()可用于对表中的记录进行计数
update()用于修改表中的现有记录
remove()可用于从表中删除记录
insert()用于在表中插入新记录
setResult()接受键和值。setResult用于保存事务完成时返回的值。事务返回一个对象,该对象是键和值的形式,使用seresult设置。
abort()用于终止事务
getResult()用于获取setResult设置的值。
data在事务API中作为数据传递的值。

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
  }
}

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

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值