IndexedDB是浏览器提供的本地数据库,它可以被网页脚本创建和操作。IndexedDB允许存储大量数据,提供查找接口,还能建立索引。这些都是LocalStorage或Cookie不具备的。就数据库类型而言,IndexedDB不属于关系型数据库(不支持SQL查询语句),更接近NoSQL数据库。
通过上一篇“本地数据库IndexedDB - 学员管理系统之登录(一)”,我们已完成了系统的登录功能,这一章节则完成相关列表管理功能,实现管理员列表、年级管理、班级管理、教师列表、学员列表等栏目的增删改查。
由于这中间工作较忙,离下篇发布时间相隔较长,并且结合后期开发过程,对前期部分定义内容进行了修改,有些地方差异,大家可以重新翻看上一篇。
上篇地址:本地数据库IndexedDB - 学员管理系统之登录(一)_觉醒法师的博客-CSDN博客
在开始前,我们将上一章节的用户登录信息再修复一下;当用户登录成功后,会将信息缓存到localStorage中,本地状态管理器中也会只在一份;用户列表管理时,遇到登录用户信息,需要判断是否可以修改或删除等,需要从store中获取用户信息,但是页面刷新后,store状态中的用户信息会丢失,这时我们在校验Token有效情况下,需要重新将缓存中的用户信息,保存到store状态中。打开store/actions.js文件,添加以下代码:
- import Vue from 'vue'
- import { USERINFO, TOKEN } from './mutationsType'
- import { tokenIsFailure } from '@/api'
-
- const actions = {
- /**
- * 重新加载缓存中用户信息
- */
- reloadUserInfo({commit}){
- let token = Vue.ls.get(TOKEN),
- userInfo = Vue.ls.get(USERINFO);
- if(token) {
- commit(TOKEN, token);
- }
- if(userInfo) {
- commit(USERINFO, userInfo);
- }
- },
-
- //...
- }
首先我们在db/model/user.js中,定义loadUserAllList用户加载所有用户信息;筛选用户功能可通过传入name进行筛选,获取所有数据时通过filter进行过滤下即可;另外这里我们先使用getAll()方法来获取所有数据,在后期中我们会讲解如何进行分页查询。代码如下:
- /**
- * 获取用户列表
- */
- export const loadUserAllList = name => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //获取所有数据
- let alls = store.getAll();
-
- alls.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- alls.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- let data = result.map(item => {
- delete item['password'];
- delete item['accesstoken'];
- return item;
- });
- //如果name值存在,则进行过滤
- if(name){
- data = data.filter(item => item.name.includes(name));
- }
- resolve(
- rJson(1, data, '获取成功~')
- )
- }else{
- reject(
- rJson(0, null, '未查询到数据~')
- )
- }
- // console.log('store', result);
- }
-
- });
- }
第二步,在api/index.js中定义userAllList接口函数,代码如下:
- import { loadUserAllList } from '@/db/model/user'
-
-
- /**
- * 获取用户列表
- */
- export const userAllList = keyword => {
- return loadUserAllList(keyword);
- }
html代码:
- <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">
- <el-form :inline="true" class="demo-form-inline">
- <el-form-item>
- <el-button size="small" type="primary" @click="addUserEvent">新增el-button>
- <el-button size="small" type="danger" @click="deleteSelectedUser">删除el-button>
- el-form-item>
- el-form>
- div>
- div>
-
-
-
- <div class="table-wrap">
- <el-table
- :data="tableList"
- style="width: 100%">
- <el-table-column type="selection" label="选择" width="50" :selectable="selectableFunc">el-table-column>
- <el-table-column prop="name" label="账号">el-table-column>
- <el-table-column prop="phone" label="手机号">el-table-column>
- <el-table-column prop="createtime" label="创建日期">el-table-column>
- <el-table-column prop="updatetime" label="更新日期">el-table-column>
- <el-table-column label="操作" width="150">
- <template slot-scope="scope">
- <el-button type="primary" size="mini" icon="el-icon-edit" circle>el-button>
- <el-button type="danger" size="mini" :disabled="userInfo.id==scope.row.id" icon="el-icon-delete" circle>el-button>
- template>
- el-table-column>
- el-table>
- div>
-
- div>
样式部分:
- .index-wrap{
- padding: 20px;
- }
-
- .filter-wrap{
- display: table;
- width: 100%;
-
- .item{
- display: table-cell;
- vertical-align: middle;
-
- &.left{
- text-align: left;
- }
- //left end
- &.right{
- text-align: right;
- }
- //right end
- }
- }
JS代码部分:
- import { userAllList } from '@/api'
- import { formatDate } from '@/utils/utils'
- import { mapGetters } from 'vuex'
-
- export default {
- data () {
- return {
- //选择ID
- selectId: 0,
- //查询关键字
- keyword: "",
- /**
- * 是否显示弹框
- */
- isShowDialog: false,
- /**
- * 列表数据
- */
- tableList: [],
- /**
- * 选的项
- */
- multipleSelection: []
- }
- },
- computed: {
- ...mapGetters(['userInfo'])
- },
- created() {
- this.updateUserList();
- },
- methods: {
- /**
- * 禁用当前登录用户的删除判断
- * @param {Object} row
- * @param {Object} index
- */
- selectableFunc(row, index){
- return row.id!=this.userInfo.id;
- },
- /**
- * 获取用户列表数据
- */
- updateUserList(){
- userAllList(this.keyword).then(res => {
- if(res.code==1&&Array.isArray(res['data'])){
- this.tableList = res.data.map(item => {
- item['createtime'] = formatDate(item.createtime);
- item['updatetime'] = formatDate(item.updatetime);
- return item;
- });
- }
- // console.log(res);
- }).catch(e => {
- this.tableList = [];
- console.log('e', e);
- });
- //ajax end
- }
- }
- }
以上准备工作做完后,我们页面就有用户数据了,如下图:

大家可以观察到admin的多选项 和 删除 按钮都是禁用的,这里因为当前登录用户是无法删除自己的。如何实现的呢,删除按钮是通过store中取到的用户ID和列表渲染用户ID进行对比,判断为当前登录用户则禁用;多选功能则是通过selectable功能,与store中的用户ID进行对比来判断的。
当然,现在列表数据是显示了,但是只有一条数据,无法通过条件进行筛选,这块等我们将新增功能完成后,再来操作。
首先,我们在db/model/user.js中定义toggleUser函数,用于新增 或 编辑用户信息;当数据为新增时,先判断用户名是否已存在,如已存在返回错误信息,不存在直接新增为新用户;当数据为编辑时,先获取该用户原始数据,用原始数据和新数据进行合并,如果使用put保存,会覆盖掉之前未修改数据。
当编辑时候,先通过get()方法获取该用户所有信息,再合并数据。
当新增时候,先通过name索引判断该用户是否存在,存在则返回提示信息;不存在则直接添加。
代码如下:
- /**
- * 增加 或 编辑用户信息
- */
- export const toggleUser = data => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store, index} = openTransactionIndex(storeName, 'name', CONST_READ.READWRITE);
-
- let res;
- //md5处理密码
- if(data['password']){
- data.password = hex_md5(data.password);
- }
-
- //用户ID存在,则为编辑
- if(data['id']&&data.id!=0){
- data['updatetime'] = new Date().getTime();
-
- //获取原数据
- res = store.get(data.id);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- //合并数据,并保存
- res = store.put(Object.assign(result, data));
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '保存成功~')
- )
- }
- }else{
- reject(
- rJson(0, e, '用户数据不存在~')
- );
- }
- }
-
- }
- //新增(需要判断用户名是否已存在)
- else{
- //通过索引 获取用户名,判断用户名是否已存在
- res = index.getKey(data.name);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(e){
- let result = e.target.result;
- //如果用户名已存在,返回错误信息
- if(result){
- reject(
- rJson(0, e, '该用户名已存在~')
- );
- }
- //用户名不存在,则直接添加
- else{
-
- data['createtime'] = new Date().getTime();
- data['updatetime'] = new Date().getTime();
- res = store.add(data);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '保存成功~')
- )
- }
- }
- //if 2 end
- }
-
- //索引 End
- }
-
- //if end
-
- });
- }
api/index.js添加addUserInfo()方法,代码如下:
- import { toggleUser } from '@/db/model/user'
-
- /**
- * 添加用户信息
- */
- export const addUserInfo = param => {
- return toggleUser(param);
- }
接下来,我们来创建新增弹框组件,在components目录中创建UserDailog目录,再新增index.vue。
弹框页面html代码部分:
- <el-dialog :title="uid!=0?'编辑':'新增'" :visible="visible" @close="closeEvent" width="420px" class="dialog-wrap">
- <el-form :model="form" :rules="rules" status-icon ref="ruleForm">
- <el-form-item label="用户名" :label-width="formLabelWidth" prop="name">
- <el-input v-model="form.name" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item v-if="uid!=0" label="原密码" :label-width="formLabelWidth" prop="opwd">
- <el-input v-model="form.opwd" type="password" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item label="密码" :label-width="formLabelWidth" prop="password">
- <el-input v-model="form.password" type="password" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item v-if="uid==0||(uid!=0&&form.password)" label="确认密码" :label-width="formLabelWidth" prop="checkPass">
- <el-input v-model="form.checkPass" type="password" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item label="手机号" :label-width="formLabelWidth" prop="phone">
- <el-input v-model="form.phone" autocomplete="off" size="small">el-input>
- el-form-item>
- el-form>
- <div slot="footer" class="dialog-footer">
- <el-button size="small" @click="closeEvent">取 消el-button>
- <el-button size="small" type="primary" @click="submitForm">保 存el-button>
- div>
- el-dialog>
JS代码部分:
- import { getUserById, addUserInfo, editUserInfo } from '@/api'
- import { hex_md5 } from '@/utils/md5'
- export default {
- props: {
- //用户ID
- uid: {
- type: Number,
- default: () => 0
- },
- visible: {
- type: Boolean,
- default: () => false
- }
- },
- data(){
- var validateUsername = (rule, value, callback) => {
- if (value === '') {
- callback(new Error('请输入用户名'));
- } else {
- callback();
- }
- };
- var validatePhone = (rule, value, callback) => {
- if (value === '') {
- callback(new Error('请输入手机号'));
- } else if(!/^1[0-9]{10}$/.test(value)){
- callback(new Error('请输入正确的手机号'));
- } else {
- callback();
- }
- };
- var validatePass = (rule, value, callback) => {
- if(this.uid == 0){
- if (value === '') {
- callback(new Error('请输入密码'));
- } else if(value.length < 6){
- callback(new Error('密码不能小于6位'));
- } else {
- if (this.form.checkPass !== '') {
- this.$refs.ruleForm.validateField('checkPass');
- }
- callback();
- }
- }else if(this.form.password){
- if (value === '') {
- callback(new Error('请输入密码'));
- } else if(value.length < 6){
- callback(new Error('密码不能小于6位'));
- } else {
- if (this.form.checkPass !== '') {
- this.$refs.ruleForm.validateField('checkPass');
- }
- callback();
- }
- }else{
- callback();
- }
- };
- var validatePass2 = (rule, value, callback) => {
- if (value === '') {
- callback(new Error('请再次输入密码'));
- } else if (value !== this.form.password) {
- callback(new Error('两次输入密码不一致!'));
- } else {
- callback();
- }
- };
-
- var validateOldPwd = (rule, value, callback) => {
- if (value === '') {
- callback(new Error('请输入原密码'));
- } else if (hex_md5(value) !== this.oldPassword) {
- callback(new Error('密码错误!'));
- } else {
- callback();
- }
- };
-
- return {
- oldPassword: "", //编辑时,记录旧密码
- form: {
- name: "",
- password: "",
- checkPass: "",
- phone: "",
- opwd: ""
- },
- formLabelWidth: '80px',
- rules: {
- name: [
- { validator: validateUsername, trigger: 'blur' }
- ],
- phone: [
- { validator: validatePhone, trigger: 'blur' }
- ],
- password: [
- { validator: validatePass, trigger: 'blur' }
- ],
- checkPass: [
- { validator: validatePass2, trigger: 'blur' }
- ],
- opwd: [
- { validator: validateOldPwd, trigger: 'blur' }
- ]
- }
- }
- },
- methods: {
- /**
- * 获取提交的数据
- * @date 2022/10/22
- */
- getParam(){
- let data = {};
- if(this.form['name']){
- data['name'] = this.form.name;
- }
- if(this.form['password']){
- data['password'] = this.form.password;
- }
- if(this.form['phone']){
- data['phone'] = this.form.phone;
- }
- return data;
- },
- /**
- * 添加用户信息
- * @date 2022/10/22
- */
- addUserInfo(){
- addUserInfo(this.getParam()).then(() => {
- this.$emit('saveSuccessChange', {});
- this.closeEvent();
- }).catch(e => {
- this.$message.error(e.msg);
- });
- },
- /**
- * 提交表单
- */
- submitForm(){
- this.$refs['ruleForm'].validate((valid) => {
- if(valid){
- this.addUserInfo();
- }else{
- return false;
- }
- });
- },
- /**
- * 关闭事件
- */
- closeEvent(){
- this.$refs['ruleForm'].resetFields();
- this.$emit('closeChange', {});
- },
- }
- }
新增弹框组件创建完成后,我们在列表页(pages/mange/index.vue)中引入该组件,在打开新增用户弹框前,将selectId 置为0表示为新增。代码如下:
- import UserDailog from '@/components/UserDailog'
-
- export default {
- data () {
- return {
- //选择ID
- selectId: 0,
- //查询关键字
- keyword: "",
- /**
- * 是否显示弹框
- */
- isShowDialog: false,
- /**
- * 列表数据
- */
- tableList: [],
- /**
- * 选的项
- */
- multipleSelection: []
- }
- },
- components: {
- UserDailog
- },
-
- //...
-
- methods: {
- /**
- * 关闭弹框
- */
- closeChange(){
- this.isShowDialog = false;
- },
-
- /**
- * 新增用户信息
- */
- addUserEvent(){
- this.selectId = 0;
- this.isShowDialog = true;
- },
-
- //...
- }
- }
列表html部分引入组件,代码如下:
- <UserDailog :visible="isShowDialog"
- :uid="selectId"
- @closeChange="closeChange"
- @saveSuccessChange="updateUserList"
- >UserDailog>
并在新增按钮添加打开弹框事件,代码如下:
"small" type="primary" @click="addUserEvent">新增
此时,我们可以看到新增弹框界面了,如下图:

现在可以添加多条数据,进行筛选操作了。如添加test1、test2、test3、tom1、tom2,创建完后列表如下图:

当我们在账号输入框中输入test,点击查询则只会显示包含test的账号,如下图:

在账号输入框中输入tom,点击查询则只会显示包含tom的账号,如下图:

这里列表查询、条件筛选和新增用户功能则完成了,接下来我们需要来完成修改数据功能。
在“1.2 新增数据”中,我们已经完成了db/model/user.js中的编辑部分的代码功能,这里我们只需要在pages/mange/index.vue中添加打开编辑弹框,并传入选中数据ID。代码如下:
- methods: {
- /**
- * 编辑用户信息
- * @param {Object} id
- */
- editUserEvent(id){
- this.selectId = id;
- this.isShowDialog = true;
- },
- }
当弹框为编辑状态时,需要获取当前用户的信息,所在在db/model/user.js中需要添加通过ID获取用户信息的功能函数,直接通过get()函数获取指定用户信息即可。代码如下:
- /**
- * 通过ID获取用户信息
- */
- export const getUserInfoById = id => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //通过ID获取数据
- let data = store.get(id);
-
- data.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- data.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- delete result['accesstoken'];
-
- resolve(
- rJson(1, result, '获取成功~')
- )
- }else{
- reject(
- rJson(0, e, '数据不存在~')
- );
- }
- }
- });
- }
api/index.js中添加编辑和获取用户信息接口,代码如下:
- import { toggleUser, getUserInfoById } from '@/db/model/user'
-
- /**
- * 获取用户信息
- */
- export const getUserById = id => {
- return getUserInfoById(id);
- }
-
- /**
- * 编辑用户信息
- */
- export const editUserInfo = param => {
- return toggleUser(param);
- }
编辑的时候,不是所有信息都是必填的,其实在“1.2 新增数据”的JS部分代码中,已经完成此部分功能。用户的密码在修改时,是非必填的,只有填入新密码时才会交验;另外修改用户信息,需要输入原密码 进行校验,校验错误进无法进行保存。
此时UserDialog/index.vue中的JS部分修改如下:
- import { getUserById, addUserInfo, editUserInfo } from '@/api'
- import { hex_md5 } from '@/utils/md5'
- export default {
- props: {
- //用户ID
- uid: {
- type: Number,
- default: () => 0
- },
- visible: {
- type: Boolean,
- default: () => false
- }
- },
- data(){
- var validateUsername = (rule, value, callback) => {
- if (value === '') {
- callback(new Error('请输入用户名'));
- } else {
- callback();
- }
- };
- var validatePhone = (rule, value, callback) => {
- if (value === '') {
- callback(new Error('请输入手机号'));
- } else if(!/^1[0-9]{10}$/.test(value)){
- callback(new Error('请输入正确的手机号'));
- } else {
- callback();
- }
- };
- var validatePass = (rule, value, callback) => {
- if(this.uid == 0){
- if (value === '') {
- callback(new Error('请输入密码'));
- } else if(value.length < 6){
- callback(new Error('密码不能小于6位'));
- } else {
- if (this.form.checkPass !== '') {
- this.$refs.ruleForm.validateField('checkPass');
- }
- callback();
- }
- }else if(this.form.password){
- if (value === '') {
- callback(new Error('请输入密码'));
- } else if(value.length < 6){
- callback(new Error('密码不能小于6位'));
- } else {
- if (this.form.checkPass !== '') {
- this.$refs.ruleForm.validateField('checkPass');
- }
- callback();
- }
- }else{
- callback();
- }
- };
- var validatePass2 = (rule, value, callback) => {
- if (value === '') {
- callback(new Error('请再次输入密码'));
- } else if (value !== this.form.password) {
- callback(new Error('两次输入密码不一致!'));
- } else {
- callback();
- }
- };
-
- var validateOldPwd = (rule, value, callback) => {
- if (value === '') {
- callback(new Error('请输入原密码'));
- } else if (hex_md5(value) !== this.oldPassword) {
- callback(new Error('密码错误!'));
- } else {
- callback();
- }
- };
-
- return {
- oldPassword: "", //编辑时,记录旧密码
- form: {
- name: "",
- password: "",
- checkPass: "",
- phone: "",
- opwd: ""
- },
- formLabelWidth: '80px',
- rules: {
- name: [
- { validator: validateUsername, trigger: 'blur' }
- ],
- phone: [
- { validator: validatePhone, trigger: 'blur' }
- ],
- password: [
- { validator: validatePass, trigger: 'blur' }
- ],
- checkPass: [
- { validator: validatePass2, trigger: 'blur' }
- ],
- opwd: [
- { validator: validateOldPwd, trigger: 'blur' }
- ]
- }
- }
- },
- watch: {
- uid(){
- if(this.uid!=0){
- this.updateUserInfo();
- }
- }
- },
- methods: {
- /**
- * 获取用户信息
- */
- updateUserInfo(){
- getUserById(this.uid).then(res => {
- if(res.code==1&&res['data']){
- this.form['name'] = res.data.name;
- this.form['phone'] = res.data.phone;
- this.oldPassword = res.data.password;
- }
- }).catch(e => {
- this.$message.error(e.msg);
- this.closeEvent();
- // console.error(e);
- })
- },
- /**
- * 获取提交的数据
- */
- getParam(){
- let data = {};
- if(this.form['name']){
- data['name'] = this.form.name;
- }
- if(this.form['password']){
- data['password'] = this.form.password;
- }
- if(this.form['phone']){
- data['phone'] = this.form.phone;
- }
- return data;
- },
- /**
- * 添加用户信息
- */
- addUserInfo(){
- addUserInfo(this.getParam()).then(() => {
- this.$emit('saveSuccessChange', {});
- this.closeEvent();
- }).catch(e => {
- this.$message.error(e.msg);
- });
- },
- /**
- * 编辑用户信息
- */
- editUserInfo(){
- editUserInfo({
- id: this.uid,
- ...this.getParam()
- }).then(() => {
- this.$emit('saveSuccessChange', {});
- this.closeEvent();
- }).catch(e => {
- this.$message.error(e.msg);
- });
- },
- /**
- * 提交表单
- */
- submitForm(){
- this.$refs['ruleForm'].validate((valid) => {
- if(valid){
- //新增用户
- if(this.uid==0){
- this.addUserInfo();
- }
- //编辑用户
- else{
- this.editUserInfo();
- }
- }else{
- return false;
- }
- });
- },
- /**
- * 关闭事件
- */
- closeEvent(){
- this.$refs['ruleForm'].resetFields();
- this.$emit('closeChange', {});
- },
- }
- }
编辑界面如下图:

当我们需要修改用户名或手机号是,是必须输入原密码才能校验成功并进行保存。当密码框输入新密码后,则会显示再次确认密码框,不输入则非必填项。如将tom2修改为Peter,则列表则会更新为最新数据,如下图:

删除单表数据,直接通过delete(’id‘)即可,在db/model/user.js中添加deleteUserById函数,代码如下:
- /**
- * 通过ID删除用户信息
- */
- export const deleteUserById = id => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName, undefined, CONST_READ.READWRITE);
- //删除指定用户信息
- let res = store.delete(id);
- res.onerror = function(e){
- reject(
- rJson(0, e, '操作出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '删除成功~')
- )
- }
- });
- }
api/index.js添加deleteUserInfo函数,代码如下:
- import { deleteUserById } from '@/db/model/user'
-
- /**
- * 删除用户信息
- */
- export const deleteUserInfo = id => {
- return deleteUserById(id);
- }
pages/mange/index.vue中添加删除方法,代码如下:
- methods: {
- /**
- * 删除用户信息
- * @param {Object} id
- */
- deleteEvent(id){
- this.$confirm('确认要删除该用户吗?', '提示', {
- confirmButtonText: '删除',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(res => {
- deleteUserInfo(id).then(() => {
- this.$message.success('删除成功!');
- this.updateUserList();
- }).catch(e => {
- this.$message.error(e.msg);
- })
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消删除'
- });
- });
- }
- }
给表格中的删除按钮绑定删除事件,代码如下:
"danger" - size="mini"
- :disabled="userInfo.id==scope.row.id"
- icon="el-icon-delete"
- circle
- @click="deleteEvent(scope.row.id)"
- >
删除成功后,调用updateUserList()函数刷新数据列表即可。
删除多项则需要使用到游标相关知识点了,在db/model/user.js中添加deleteUserByIds函数,用来删除多条数据记录。通过openCursor()函数,对用户表进行遍历,通过includes判断遍历数据ID是否在删除数组中,在则直接调用delete()函数(注:这里不需要指定唯一ID,当前游标指向当前遍历数据实例对象)。
- /**
- * 通过ID删除多条用户信息
- */
- export const deleteUserByIds = ids => {
- return new Promise((resolve, reject) => {
- if(Array.isArray(ids)){
- //打开游标
- let {store} = openTransactionIndex(storeName, undefined, CONST_READ.READWRITE);
- //打开游标
- let cursor = store.openCursor();
-
- cursor.onerror = function(e){
- reject(
- rJson(0, e, '操作出错了~')
- );
- }
-
- cursor.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- if(ids.includes(result.key)){
- result.delete();
- }
- result.continue();
- }else{
- resolve(
- rJson(1, null, '删除成功~')
- )
- }
- }
- }else{
- reject(
- rJson(0, e, '请传入数组形式ID数据~')
- );
- }
- //end
- });
- }
api/index.js中添加删除多项数据功能函数,代码如下:
- import { deleteUserByIds } from '@/db/model/user'
-
- /**
- * 删除选择中项的用户信息
- */
- export const deleteUserChecked = ids => {
- return deleteUserByIds(ids);
- }
pages/mange/index.vue中添加删除多项数据的方法,代码如下:
- methods: {
- /**
- * 删除选中的ID项
- */
- deleteSelectedUser(){
- if(this.multipleSelection.length==0){
- this.$message({
- type: 'info',
- message: '请选择删除项'
- });
- return;
- }
-
- this.$confirm('确认要删除选中的用户吗?', '提示', {
- confirmButtonText: '删除',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(res => {
- deleteUserChecked(this.multipleSelection.map(item => item.id)).then(() => {
- this.$message.success('删除成功!');
- this.updateUserList();
- }).catch(e => {
- this.$message.error(e.msg);
- })
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消删除'
- });
- });
- }
-
- }
再给多项删除按钮添加绑定事件,代码如下:
"small" type="danger" @click="deleteSelectedUser">删除
到此为止,用户管理的增删除改查功能就全部完成了;这里讲解比较碎片化,如果不清楚地方,可以留言询问;如有不足之处,欢迎指出。
年级管理的增删改查就不细讲了,增删改查也不复杂,可以按照“一、管理员列表” 中的功能进行复制,修改相应参数数据即可,都是大同小异。
创建db/model/grade.js,代码如下:
- import { DBIsLoadSuccess, openTransactionIndex, CONST_READ } from '@/db'
- import { rJson } from '@/utils/utils'
-
- let storeName = 'grade';
-
- /**
- * 获取年级列表
- */
- export const loadGradeAllList = name => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //获取所有数据
- let alls = store.getAll();
-
- alls.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- alls.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- let rData = result;
- if(name){
- rData = result.filter(item => item.name.includes(name));
- }
- resolve(
- rJson(1, rData, '获取成功~')
- )
- }else{
- reject(
- rJson(0, null, '未查询到数据~')
- )
- }
- // console.log('store', result);
- }
-
- });
- }
-
-
- /**
- * 增加 或 编辑 年级信息
- */
- export const toggleGrade = data => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store, index} = openTransactionIndex(storeName, 'name', CONST_READ.READWRITE);
-
- let res;
-
- //用户ID存在,则为编辑
- if(data['id']&&data.id!=0){
- data['updatetime'] = new Date().getTime();
-
- //获取原数据
- res = store.get(data.id);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- //合并数据,并保存
- res = store.put(Object.assign(result, data));
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '保存成功~')
- )
- }
- }else{
- reject(
- rJson(0, e, '年级不存在~')
- );
- }
- }
-
- }
- //新增(需要判断用户名是否已存在)
- else{
- //通过索引 获取用户名,判断用户名是否已存在
- res = index.getKey(data.name);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(e){
- let result = e.target.result;
- //如果用户名已存在,返回错误信息
- if(result){
- reject(
- rJson(0, e, '该年级已存在~')
- );
- }
- //用户名不存在,则直接添加
- else{
-
- data['createtime'] = new Date().getTime();
- data['updatetime'] = new Date().getTime();
- res = store.add(data);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '保存成功~')
- )
- }
- }
-
- }
-
- }
-
- });
- }
-
- /**
- * 通过ID删除 年级信息
- */
- export const deleteGradeById = id => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName, undefined, CONST_READ.READWRITE);
- //删除指定用户信息
- let res = store.delete(id);
- res.onerror = function(e){
- reject(
- rJson(0, e, '操作出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '删除成功~')
- )
- }
- });
- }
-
- /**
- * 通过ID删除多条 年级信息
- */
- export const deleteGradeByIds = ids => {
- return new Promise((resolve, reject) => {
- if(Array.isArray(ids)){
- //打开游标
- let {store} = openTransactionIndex(storeName, undefined, CONST_READ.READWRITE);
- //打开游标
- let cursor = store.openCursor();
-
- cursor.onerror = function(e){
- reject(
- rJson(0, e, '操作出错了~')
- );
- }
-
- cursor.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- if(ids.includes(result.key)){
- result.delete();
- }
- result.continue();
- }else{
- resolve(
- rJson(1, null, '删除成功~')
- )
- }
- }
- }else{
- reject(
- rJson(0, e, '请传入数组形式ID数据~')
- );
- }
- });
- }
api/index.js中添加年级部分接口函数,代码如下:
- import {
- loadGradeAllList,
- toggleGrade,
- deleteGradeById,
- deleteGradeByIds
- } from '@/db/model/grade'
-
- /**
- * 获取年级列表
- */
- export const gradeAllList = keyword => {
- return loadGradeAllList(keyword);
- }
-
- /**
- * 添加 或 修改指定年级信息
- */
- export const toggleGradeInfo = name => {
- return toggleGrade(name);
- }
-
- /**
- * 删除指定年级
- */
- export const deleteGradeInfo = id => {
- return deleteGradeById(id);
- }
-
- /**
- * 删除指定多项年级信息
- */
- export const deleteGradeChecked = ids => {
- return deleteGradeByIds(ids);
- }
打开年级列表页面pages/grade/index.vue,添加html、样式和JS部分功能。
html代码部分:
- <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="updateList">查询el-button>
- el-form-item>
- el-form>
- div>
- <div class="item right">
- <el-form :inline="true" class="demo-form-inline">
- <el-form-item>
- <el-button size="small" type="primary" @click="addEvent">新增el-button>
- <el-button size="small" type="info" @click="deleteCheckedEvent">删除el-button>
- el-form-item>
- el-form>
- div>
- div>
-
- <div class="table-wrap">
- <el-table
- :data="tableList"
- @selection-change="selectionChange"
- style="width: 100%">
- <el-table-column type="selection" label="选择" width="50"> el-table-column>
- <el-table-column prop="name" label="年级名称">el-table-column>
- <el-table-column prop="createtime" label="创建日期">el-table-column>
- <el-table-column prop="updatetime" label="更新日期">el-table-column>
- <el-table-column label="操作" width="150">
- <template slot-scope="scope">
- <el-button type="primary" size="mini" icon="el-icon-edit" circle @click="editEvent(scope.row.id, scope.row.name)">el-button>
- <el-button type="danger" size="mini" icon="el-icon-delete" circle @click="deleteEvent(scope.row.id)">el-button>
- template>
- el-table-column>
- el-table>
- div>
-
- div>
样式部分:
- .index-wrap{
- padding: 20px;
- }
-
- .filter-wrap{
- display: table;
- width: 100%;
-
- .item{
- display: table-cell;
- vertical-align: middle;
-
- &.left{
- text-align: left;
- }
- &.right{
- text-align: right;
- }
- }
- }
JS部分:
- import { gradeAllList, toggleGradeInfo, deleteGradeInfo, deleteGradeChecked } from '@/api'
- import { formatDate } from '@/utils/utils'
-
- export default {
- data () {
- return {
- /**
- * 搜索关键词
- */
- keyword: "",
- /**
- * 列表数据
- */
- tableList: [],
- /**
- * 选中项
- */
- multipleSelection: []
- }
- },
- created() {
- this.updateList();
- },
- methods: {
- /**
- * 获取列表数据
- */
- updateList(){
- gradeAllList(this.keyword).then(res => {
- if(res.code==1&&Array.isArray(res.data)){
- this.tableList = res.data.map(item => {
- item['createtime'] = formatDate(item.createtime);
- item['updatetime'] = formatDate(item.updatetime);
- return item;
- });
- }
- }).catch(msg => {
- console.log('msg', msg);
- });
- //end
- },
- /**
- * 添加事件
- */
- addEvent(){
- this.$prompt('请输入年级名称', '提示', {
- confirmButtonText: '保存',
- cancelButtonText: '取消',
- inputValidator: function(value){
- if(value&&value.toString().length>0){
- return true;
- }else{
- return "请输入年级名称";
- }
- },
- inputErrorMessage: "请输入年级名称"
- }).then(({ value }) => {
- toggleGradeInfo({
- name: value
- }).then(res => {
- this.$message.success('添加成功');
- this.updateList();
- }).catch(e => {
- this.$message({
- type: 'info',
- message: e.msg
- });
- });
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消'
- });
- });
- },
- /**
- * 编辑事件
- */
- editEvent(id, name){
- this.$prompt('请输入年级名称', '提示', {
- confirmButtonText: '保存',
- cancelButtonText: '取消',
- inputValidator: function(value){
- if(value&&value.toString().length>0){
- return true;
- }else{
- return "请输入年级名称";
- }
- },
- inputValue: name,
- inputErrorMessage: "请输入年级名称"
- }).then(({ value }) => {
- toggleGradeInfo({
- id: id,
- name: value
- }).then(res => {
- this.$message.success('保存成功');
- this.updateList();
- }).catch(e => {
- this.$message({
- type: 'info',
- message: e.msg
- });
- });
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消'
- });
- });
- },
- /**
- * 删除事件
- * @param {Object} id
- */
- deleteEvent(id){
- this.$confirm('确认要删除该年级吗?', '提示', {
- confirmButtonText: '删除',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(res => {
- deleteGradeInfo(id).then(() => {
- this.$message.success('删除成功!');
- this.updateList();
- }).catch(e => {
- this.$message.error(e.msg);
- })
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消删除'
- });
- });
- },
- /**
- * check 选中项项值
- * @param {Object} val
- */
- selectionChange(val){
- this.multipleSelection = val;
- },
- /**
- * 删除多项指定年级信息
- */
- deleteCheckedEvent(){
- if(this.multipleSelection.length==0){
- this.$message({
- type: 'info',
- message: '请选择删除项'
- });
- return;
- }
-
- this.$confirm('确认要删除选中的年级吗?', '提示', {
- confirmButtonText: '删除',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(res => {
- deleteGradeChecked(this.multipleSelection.map(item => item.id)).then(() => {
- this.$message.success('删除成功!');
- this.updateList();
- }).catch(e => {
- this.$message.error(e.msg);
- })
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消删除'
- });
- });
- }
- //end
- }
- }
到此为止,年级部分功能就完成了;由于这里添加信息只有年级名称,所以使用了Element的this.$prompt弹框进行添加和编辑。界面效果如下:
列表页面:
![]()

新增页面:

这里先讲教师列表的功能实现,因为班级管理中需要关联对应班主任,这项为必填项;而教师对应的班级是非必填项。
这部分和前面并无太大差异,还是常规的新删改查部分功能,所以也不作功能分解,直接按代码操作即可。
db/model/teacher.js代码如下:
- import { DBIsLoadSuccess, openTransactionIndex, CONST_READ } from '@/db'
- import { rJson } from '@/utils/utils'
-
- let storeName = 'teacher';
-
- /**
- * 获取 教师列表
- */
- export const loadTeacherAllList = name => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //获取所有数据
- let alls = store.getAll();
-
- alls.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- alls.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- let rData = result;
- if(name){
- rData = result.filter(item => item.name.includes(name));
- }
- resolve(
- rJson(1, rData, '获取成功~')
- )
- }else{
- reject(
- rJson(0, null, '未查询到数据~')
- )
- }
- // console.log('store', result);
- }
-
- });
- }
-
-
- /**
- * 获取教师信息
- */
- export const getTecharInfoById = id => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //通过ID获取数据
- let data = store.get(id);
-
- data.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- data.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- resolve(
- rJson(1, result, '获取成功~')
- )
- }else{
- reject(
- rJson(0, e, '数据不存在~')
- );
- }
- }
- });
- }
-
- /**
- * 增加 或 编辑 教师信息
- */
- export const toggleTeacher = data => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store, index} = openTransactionIndex(storeName, 'name', CONST_READ.READWRITE);
-
- let res;
- //ID存在,则为编辑
- if(data['id']&&data.id!=0){
- data['updatetime'] = new Date().getTime();
-
- //获取原数据
- res = store.get(data.id);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- //合并数据,并保存
- res = store.put(Object.assign(result, data));
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '保存成功~')
- )
- }
- }else{
- reject(
- rJson(0, e, '年级不存在~')
- );
- }
- }
-
- }
- //新增(需要判断是否已存在)
- else{
- //通过索引获取,判断是否已存在
- res = index.getKey(data.name);
-
- res.onerror = function(){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(e){
- let result = e.target.result;
- //如果已存在,返回错误信息
- if(result){
- reject(
- rJson(0, e, '该教师已存在~')
- );
- }
- //不存在,则直接添加
- else{
-
- data['createtime'] = new Date().getTime();
- data['updatetime'] = new Date().getTime();
- res = store.add(data);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '保存成功~')
- )
- }
- }
- //if 2 end
- }
-
- //索引 End
- }
-
- //if end
-
- });
- }
-
- /**
- * 通过ID删除教师信息
- */
- export const deleteTeacherById = id => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName, undefined, CONST_READ.READWRITE);
- //删除指定信息
- let res = store.delete(id);
- res.onerror = function(e){
- reject(
- rJson(0, e, '操作出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '删除成功~')
- )
- }
- });
- }
-
- /**
- * 通过ID删除多条教师信息
- */
- export const deleteTeacherByIds = ids => {
- return new Promise((resolve, reject) => {
- if(Array.isArray(ids)){
- //打开游标
- let {store} = openTransactionIndex(storeName, undefined, CONST_READ.READWRITE);
- //打开游标
- let cursor = store.openCursor();
-
- cursor.onerror = function(e){
- reject(
- rJson(0, e, '操作出错了~')
- );
- }
-
- cursor.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- if(ids.includes(result.key)){
- result.delete();
- }
- result.continue();
- }else{
- resolve(
- rJson(1, null, '删除成功~')
- )
- }
- }
- }else{
- reject(
- rJson(0, e, '请传入数组形式ID数据~')
- );
- }
-
- });
- }
api/index.js文件添加以下代码:
- import {
- loadTeacherAllList,
- toggleTeacher,
- deleteTeacherById,
- deleteTeacherByIds,
- getTecharInfoById
- } from '@/db/model/teacher'
-
- /**
- * 获取教师列表
- */
- export const getTeachersList = name => {
- return loadTeacherAllList(name);
- }
-
- /**
- * 新增或修改教师信息
- */
- export const toggerTeacherInfo = params => {
- return toggleTeacher(params);
- }
-
- /**
- * 通过ID获取教师信息
- */
- export const loadTeacherById = id => {
- return getTecharInfoById(id);
- }
-
- /**
- * 单个教师信息删除
- */
- export const deleteTeacherInfo = id => {
- return deleteTeacherById(id);
- }
-
- /**
- * 删除指定多个教师信息
- */
- export const deleteSelectedTeacherInfo = ids => {
- return deleteTeacherByIds(ids);
- }
在components中添加TeacherDialog/index.vue新增页面组件,html部分代码:
- <el-dialog :title="uid!=0?'编辑':'新增'" :visible="visible" @close="closeEvent" width="420px" class="dialog-wrap">
- <el-form :model="form" :rules="rules" status-icon ref="ruleForm">
- <el-form-item label="教师姓名" :label-width="formLabelWidth" required prop="name">
- <el-input v-model="form.name" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item label="户籍" :label-width="formLabelWidth" required prop="registration">
- <el-input v-model="form.registration" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item label="手机号" :label-width="formLabelWidth" required prop="phone">
- <el-input v-model="form.phone" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item label="居住地址" :label-width="formLabelWidth" required prop="address">
- <el-input v-model="form.address" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item label="出生日期" :label-width="formLabelWidth" required prop="birthday">
- <el-date-picker v-model="form.birthday" value-format="yyyy-MM-dd" type="date" placeholder="选择日期">el-date-picker>
- el-form-item>
- el-form>
-
- <div slot="footer" class="dialog-footer">
- <el-button size="small" @click="closeEvent">取 消el-button>
- <el-button size="small" type="primary" @click="submitForm">保 存el-button>
- div>
-
- el-dialog>
js部分代码:
- import { toggerTeacherInfo, loadTeacherById } from '@/api'
- import { formatDate } from '@/utils/utils'
- export default {
- props: {
- //用户ID
- uid: {
- type: Number,
- default: () => 0
- },
- visible: {
- type: Boolean,
- default: () => false
- }
- },
- data(){
- return {
- formLabelWidth: '80px',
- gradeOptions: [],
- classOptions: [],
- dateValue: "",
- form: {
- name: "",
- registration: "",
- phone: "",
- address: "",
- birthday: ""
- },
- rules: {
- name: [
- { required: true, message: '请输入教师姓名', trigger: 'blur' },
- { required: true, message: '请输入教师姓名', trigger: 'change' },
- ],
- registration: [
- { required: true, message: '请输入户籍', trigger: 'blur' },
- { required: true, message: '请输入户籍', trigger: 'change' },
- ],
- phone: [
- { required: true, message: '请输入手机号', trigger: 'blur' },
- { required: true, message: '请输入手机号', trigger: 'change' },
- { tel: true, message: '请输入手机号', trigger: 'blur' },
- { tel: true, message: '请输入手机号', trigger: 'change' },
- ],
- address: [
- { required: true, message: '请输入现居住地址', trigger: 'blur' },
- { required: true, message: '请输入现居住地址', trigger: 'change' },
- ],
- birthday: [
- { required: true, message: '请选择出生日期', trigger: 'blur' },
- { required: true, message: '请选择出生日期', trigger: 'change' },
- { date: true, message: '请选择出生日期', trigger: 'blur' },
- { date: true, message: '请选择出生日期', trigger: 'change' },
- ]
- }
- }
- },
- watch: {
- uid(){
- if(this.uid!=0){
- this.updateClassInfo();
- }
- }
- },
- methods: {
- /**
- * 获取都老师信息
- */
- updateClassInfo(){
- loadTeacherById(this.uid).then(res => {
- if(res.code==1){
- this.form = {
- name: res.data['name'],
- registration: res.data['registration'],
- phone: res.data['phone'],
- address: res.data['address'],
- birthday: res.data['birthday']
- }
- }
- }).catch(e => {
- console.error(e);
- })
- },
- /**
- * 获取保存数据
- */
- getParams(){
- let { name, registration, phone, address, birthday } = this.form;
- return {
- name, registration, phone, address, birthday
- }
- },
- /**
- * 添加教师信息
- */
- addUserInfo(){
- let param = this.getParams();
- toggerTeacherInfo(param).then(res => {
- if(res.code==1){
- this.$message.success('保存成功');
- this.$emit('saveChange', {});
- }
- }).catch(e => {
- this.$message.success(e.msg);
- });
- },
- /**
- * 编辑教师信息
- */
- editUserInfo(){
- let param = this.getParams();
- param['id'] = this.uid;
- toggerTeacherInfo(param).then(res => {
- if(res.code==1){
- this.$message.success('保存成功');
- this.$emit('saveChange', {});
- }
- }).catch(e => {
- this.$message.success(e.msg);
- });
- },
- /**
- * 提交表单
- */
- submitForm(){
- // console.log(this.form)
- this.$refs['ruleForm'].validate((valid) => {
- if(valid){
- //新增
- if(this.uid==0){
- this.addUserInfo();
- }
- //编辑
- else{
- this.editUserInfo();
- }
- }else{
- return false;
- }
- });
- },
- /**
- * 关闭事件
- */
- closeEvent(){
- this.$refs['ruleForm'].resetFields();
- this.$emit('closeChange', {});
- },
- }
- }
添加界面如下:

在pages目录中teacher/index.vue添加列表页面,html部分代码如下:
- <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" placeholder="请输入教师姓名" v-model="keyword">el-input>
- el-form-item>
- <el-form-item>
- <el-button size="small" type="primary" @click="updateList">查询el-button>
- el-form-item>
- el-form>
- div>
- <div class="item right">
- <el-form :inline="true" class="form-inline">
- <el-form-item>
- <el-button size="small" type="primary" @click="showAddDialog">新增el-button>
- <el-button size="small" type="info" @click="deleteSelectedTeacher">删除el-button>
- el-form-item>
- el-form>
- div>
- div>
-
- <div class="table-wrap">
- <el-table
- @selection-change="selectionChange"
- :data="tableList"
- style="width: 100%">
- <el-table-column type="selection" label="选择" width="50"> el-table-column>
- <el-table-column prop="name" label="教师姓名">el-table-column>
- <el-table-column prop="registration" label="户籍">el-table-column>
- <el-table-column prop="address" label="居住地址">el-table-column>
- <el-table-column prop="age" label="年龄" width="80">
- <template slot-scope="scope">
- <span>{{scope.row.birthday | filterAge}}span>
- template>
- el-table-column>
- <el-table-column prop="createtime" label="创建日期" width="180">el-table-column>
- <el-table-column prop="updatetime" label="更新日期" width="180">el-table-column>
- <el-table-column label="操作" width="150">
- <template slot-scope="scope">
- <el-button type="primary" size="mini" icon="el-icon-edit" circle @click="editDialog(scope.row.id)">el-button>
- <el-button type="danger" size="mini" icon="el-icon-delete" circle @click="deleteTeacherEvent(scope.row.id)">el-button>
- template>
- el-table-column>
- el-table>
- div>
-
- <TeacherDialog :uid="selectId" :visible="isShowDialog" @closeChange="closeChange" @saveChange="saveChange">TeacherDialog>
- div>
js部分代码:
- import TeacherDialog from '@/components/TeacherDialog'
- import { getTeachersList, toggerTeacherInfo, deleteTeacherInfo, deleteSelectedTeacherInfo } from '@/api'
- import { formatDate } from '@/utils/utils'
-
- export default {
- data () {
- return {
- //编辑选择用户ID
- selectId: 0,
- //搜索关键词
- keyword: "",
- /**
- * 是否显示弹框
- */
- isShowDialog: false,
- /**
- * 列表数据
- */
- tableList: [],
- /**
- * 选择项
- */
- multipleSelection: []
- }
- },
- components: {
- TeacherDialog
- },
- created() {
- this.updateList();
- },
- filters: {
- filterAge(val){
- let current = new Date(),
- bDate = new Date(val);
- return current.getFullYear() - bDate.getFullYear();
- }
- },
- methods: {
- /**
- * 获取教师列表数据
- */
- updateList(){
- getTeachersList(this.keyword).then(res => {
- if(res.code==1){
- this.tableList = res.data.map(item => {
- item['createtime'] = formatDate(item.createtime);
- item['updatetime'] = formatDate(item.updatetime);
- return item;
- });
- }
- //if end
- }).catch(msg => {
- console.error(msg);
- });
- //ajax end
- },
- /**
- * 编辑教师信息
- */
- editDialog(id){
- this.selectId = id;
- this.isShowDialog = true;
- },
- /**
- * 显示弹框事件
- */
- showAddDialog(){
- this.isShowDialog = true;
- },
- /**
- * 新增教师保存事件
- */
- saveChange(){
- this.updateList();
- this.isShowDialog = false;
- },
- /**
- * 关闭弹框事件
- */
- closeChange(){
- this.selectId = 0;
- this.isShowDialog = false;
- },
- /**
- * 删除指定教师信息
- * @param {Object} id
- */
- deleteTeacherEvent(id){
- this.$confirm('确认要删除该教师信息吗?', '提示', {
- confirmButtonText: '删除',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(res => {
- deleteTeacherInfo(id).then(() => {
- this.$message.success('删除成功!');
- this.updateList();
- }).catch(e => {
- this.$message.error(e.msg);
- })
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消删除'
- });
- });
- },
- /**
- * check 选中项项值
- * @param {Object} val
- */
- selectionChange(val){
- this.multipleSelection = val;
- },
- /**
- * 删除指定多个教师信息
- */
- deleteSelectedTeacher(){
- if(this.multipleSelection.length==0){
- this.$message({
- type: 'info',
- message: '请选择删除项'
- });
- return;
- }
-
- this.$confirm('确认要删除选中的教师信息吗?', '提示', {
- confirmButtonText: '删除',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(res => {
- deleteSelectedTeacherInfo(this.multipleSelection.map(item => item.id)).then(() => {
- this.$message.success('删除成功!');
- this.updateList();
- }).catch(e => {
- this.$message.error(e.msg);
- })
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消删除'
- });
- });
- }
- //
- }
- }
列表界面如下:

班级这部分由于关联了教师ID和年级ID,所以在做查询时,会稍微复杂点,同时需要之前的grade.js和teacher.js中增加单独查询功能,下面会一一阐述。
db/model/classify.js代码:
- import { DBIsLoadSuccess, openTransactionIndex, CONST_READ } from '@/db'
- import { rJson } from '@/utils/utils'
- import { getTeacherByIdsCursor } from './teacher.js'
- import { getGradeByIdsCursor } from './grade.js'
-
- let storeName = 'classify';
-
- /**
- * 获取 班级信息
- */
- export const loadClassAllList = async (name) => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //获取所有数据
- let alls = store.getAll();
-
- alls.onerror = function(e){
- console.log('error', e)
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- alls.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- let rData = result;
- if(name){
- rData = result.filter(item => item.name.includes(name));
- }
-
- resolve(
- rJson(1, rData, '获取成功~')
- )
- }else{
- reject(
- rJson(0, null, '未查询到数据~')
- )
- }
- // console.log('store', result);
- }
-
- });
- }
-
- /**
- * 通过ID获取 班级信息
- */
- export const getClassInfoById = id => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //通过ID获取数据
- let data = store.get(id);
-
- data.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- data.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- resolve(
- rJson(1, result, '获取成功~')
- )
- }else{
- reject(
- rJson(0, e, '数据不存在~')
- );
- }
- }
- });
- }
-
-
- /**
- * 通过年级ID获取对应班级信息
- */
- export const getClassInfoByKey = key => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store, cursor} = openTransactionIndex(storeName, 'gid'),
- reData = [];
-
- cursor.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- cursor.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- if(result.key==key){
- reData.push({
- id: result.value.id,
- name: result.value.name
- });
- }
- result.continue();
- }else{
- resolve(
- rJson(1, reData, '获取成功~')
- )
- // console.log('end')
- }
- }
- });
- }
-
- /**
- * 增加 或 编辑 班级信息
- */
- export const toggleClass = data => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store, index} = openTransactionIndex(storeName, 'name', CONST_READ.READWRITE);
-
- let res;
-
- //ID存在,则为编辑
- if(data['id']&&data.id!=0){
- data['updatetime'] = new Date().getTime();
-
- //获取原数据
- res = store.get(data.id);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- //合并数据,并保存
- res = store.put(Object.assign(result, data));
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '保存成功~')
- )
- }
- }else{
- reject(
- rJson(0, e, '年级不存在~')
- );
- }
- }
-
- }
- //新增(需要判断是否已存在)
- else{
- //通过索引获取,判断是否已存在
- res = index.getKey(data.name);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(e){
- let result = e.target.result;
- //如果已存在,返回错误信息
- if(result){
- reject(
- rJson(0, e, '该年级已存在~')
- );
- }
- //不存在,则直接添加
- else{
-
- data['createtime'] = new Date().getTime();
- data['updatetime'] = new Date().getTime();
- res = store.add(data);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '保存成功~')
- )
- }
- }
- //if 2 end
- }
-
- //索引 End
- }
-
- //if end
-
- });
- }
-
- /**
- * 通过ID删除班级
- */
- export const deleteClassById = id => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName, undefined, CONST_READ.READWRITE);
- //删除指定信息
- let res = store.delete(id);
- res.onerror = function(e){
- reject(
- rJson(0, e, '操作出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '删除成功~')
- )
- }
- });
- }
-
- /**
- * 通过ID删除多条班级
- */
- export const deleteClassByIds = ids => {
- return new Promise((resolve, reject) => {
- if(Array.isArray(ids)){
- //打开游标
- let {store} = openTransactionIndex(storeName, undefined, CONST_READ.READWRITE);
- //打开游标
- let cursor = store.openCursor();
-
- cursor.onerror = function(e){
- reject(
- rJson(0, e, '操作出错了~')
- );
- }
-
- cursor.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- if(ids.includes(result.key)){
- result.delete();
- }
- result.continue();
- }else{
- resolve(
- rJson(1, null, '删除成功~')
- )
- }
- }
- }else{
- reject(
- rJson(0, e, '请传入数组形式ID数据~')
- );
- }
- //end
- });
- }
api/index.js中添加班级接口,代码如下:
- import {
- loadClassAllList,
- toggleClass,
- getClassInfoById,
- deleteClassById,
- deleteClassByIds,
- getClassInfoByKey
- } from '@/db/model/classify'
-
- /**
- * 获取班级列表
- */
- export const getClassList = name => {
- return loadClassAllList(name);
- }
-
- /**
- * 新增或保存 班级信息
- */
- export const toggleClassInfo = param => {
- return toggleClass(param);
- }
-
- /**
- * 通过索引获取对应班级信息
- */
- export const getClassByKey = key => {
- return getClassInfoByKey(key);
- }
-
- /**
- * 获取班级信息 通过ID
- */
- export const getClassifyById = id => {
- return getClassInfoById(id);
- }
-
- /**
- * 通过ID删除指定班级信息
- */
- export const deleteClassInfoById = id => {
- return deleteClassById(id);
- }
-
- /**
- * 通过选择中的ID删除 班级信息
- */
- export const deleteClassSelectedInfoByIds = ids => {
- return deleteClassByIds(ids);
- }
在components目录中添加ClassDialog/index.vue新增页面组件,html部分代码:
- <el-dialog :title="uid!=0?'编辑':'新增'" :visible="visible" @close="closeEvent" width="420px" class="dialog-wrap">
- <el-form :model="form" :rules="rules" status-icon ref="ruleForm">
- <el-form-item label="班级名称" :label-width="formLabelWidth" prop="name" required>
- <el-input v-model="form.name" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item label="选择年级" :label-width="formLabelWidth" prop="grade" required>
- <el-select size="small" v-model="form.grade" placeholder="请选择">
- <el-option
- v-for="item in gradeOptions"
- :key="item.id"
- :label="item.name"
- :value="item.id">
- el-option>
- el-select>
- el-form-item>
- <el-form-item label="班主任" :label-width="formLabelWidth" prop="master" required>
- <el-select size="small" v-model="form.master" placeholder="请选择">
- <el-option
- v-for="item in masterOptions"
- :key="item.id"
- :label="item.name"
- :value="item.id">
- el-option>
- el-select>
- el-form-item>
- <el-form-item label="授课老师">
- <el-table
- :data="courseList"
- size="mini"
- border
- style="width: 100%">
- <el-table-column prop="name" label="名称">
- el-table-column>
- <el-table-column label="教师名称" width="180">
- <template slot-scope="scope">
- <el-select size="small" v-model="scope.row.tid" placeholder="请选择">
- <el-option
- v-for="item in masterOptions"
- :key="item.id"
- :label="item.name"
- :value="item.id">
- el-option>
- el-select>
- template>
- el-table-column>
- el-table>
- el-form-item>
- el-form>
- <div slot="footer" class="dialog-footer">
- <el-button size="small" @click="closeEvent">取 消el-button>
- <el-button size="small" type="primary" @click="submitForm">保 存el-button>
- div>
- el-dialog>
这里与其他新增页面不同之处在于加载时,同时需要获取年级和教师数据列表,用于下拉选项,这两个接口已在api/index.js定义过,直接调用即可。
这里也作了些偷懒操作,每个班级所对应课程并未作动态添加功能,而是写死在新增页面。保存的时候是以数组形式存库的,所以在编辑的时候,通过班级ID获取到班级信息,需将拿到ts字段对应信息,重新赋值给courseList。
js代码部分:
- import { gradeAllList, getTeachersList, toggleClassInfo, getClassifyById } from '@/api'
- export default {
- props: {
- //用户ID
- uid: {
- type: Number,
- default: () => 0
- },
- visible: {
- type: Boolean,
- default: () => false
- }
- },
- data(){
- return {
- formLabelWidth: '80px',
- gradeOptions: [], //年级
- masterOptions: [], //教师
- courseList: [
- {"name": "语文", "tid": ""},
- {"name": "数据", "tid": ""},
- {"name": "英文", "tid": ""},
- ],
- form: {
- name: "",
- master: "",
- grade: ""
- },
- rules: {
- name: [
- { required: true, message: '请输入班级名称', trigger: 'blur' },
- { required: true, message: '请输入班级名称', trigger: 'change' },
- ],
- grade: [
- { required: true, message: '请选择年级', trigger: 'blur' },
- { required: true, message: '请选择年级', trigger: 'change' },
- ],
- master: [
- { required: true, message: '请选择班主任', trigger: 'blur' },
- { required: true, message: '请选择班主任', trigger: 'change' },
- ],
- }
- }
- },
- watch: {
- uid(){
- if(this.uid!=0){
- this.updateClassInfo();
- }
- }
- },
- created() {
- this.updatePropsInfo();
- },
- methods: {
- /**
- * 获取班级信息
- */
- updateClassInfo(){
- getClassifyById(this.uid).then(res => {
- if(res.code==1){
- this.form = {
- name: res.data.name,
- master: res.data.mid,
- grade: res.data.gid
- }
- if(Array.isArray(res.data['ts'])&&res.data.ts.length>0){
- this.courseList = res.data.ts;
- }
- }
- // console.log(res);
- }).catch(e => {
- console.error(e);
- })
- },
- /**
- * 获取属性信息
- */
- updatePropsInfo(){
- Promise.all([gradeAllList(), getTeachersList()]).then(res => {
- let gradeList = res[0]['data'],
- teacherList = res[1]['data'];
-
- if(Array.isArray(gradeList)){
- this.gradeOptions = gradeList.map(item => item);
- }
-
- if(Array.isArray(teacherList)){
- this.masterOptions = teacherList;
- }
- }).catch(e => {
- console.error(e);
- })
- },
-
- /**
- * 添加班级信息
- */
- addUserInfo(){
- let params = this.getParams();
- toggleClassInfo(params).then(res => {
- if(res.code==1){
- this.$message.success('保存成功');
- this.$emit('saveSuccessChange', {});
- }
- }).catch(e => {
- this.$message.success(e.msg);
- console.error(e);
- });
- },
- /**
- * 编辑班级信息
- */
- editUserInfo(){
- let params = this.getParams();
- params['id'] = this.uid;
- toggleClassInfo(params).then(res => {
- if(res.code==1){
- this.$message.success('保存成功');
- this.$emit('saveSuccessChange', {});
- }
- }).catch(e => {
- this.$message.success(e.msg);
- console.error(e);
- });
- },
- /**
- * 获取保存参数
- */
- getParams(){
- let { name, grade, master } = this.form;
- return {
- name,
- gid: grade,
- mid: master,
- ts: this.courseList
- }
- },
- /**
- * 提交表单
- */
- submitForm(){
- this.$refs['ruleForm'].validate((valid) => {
- if(valid){
- //新增班级
- if(this.uid==0){
- this.addUserInfo();
- }
- //编辑班级
- else{
- this.editUserInfo();
- }
- }else{
- return false;
- }
- });
- },
- /**
- * 关闭事件
- */
- closeEvent(){
- this.$refs['ruleForm'].resetFields();
- this.courseList = this.courseList.map(item => {
- item['tid'] = "";
- return item;
- })
- this.$emit('closeChange', {});
- },
- }
- }
新增界面如下:

在pages/classify/index.vue中添加列表页面,html代码如下:
- <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" placeholder="请输入班级名称" v-model="keyword">el-input>
- el-form-item>
- <el-form-item>
- <el-button size="small" type="primary" @click="updateList">查询el-button>
- el-form-item>
- el-form>
- div>
- <div class="item right">
- <el-form :inline="true" class="demo-form-inline">
- <el-form-item>
- <el-button size="small" type="primary" @click="showAddDialog">新增el-button>
- <el-button size="small" type="info" @click="deleteSelectedClass">删除el-button>
- el-form-item>
- el-form>
- div>
- div>
-
- <div class="table-wrap">
- <el-table
- @selection-change="selectionChange"
- :data="tableList"
- style="width: 100%">
- <el-table-column type="selection" label="选择" width="50"> el-table-column>
- <el-table-column prop="name" label="班级名称">el-table-column>
- <el-table-column prop="master" label="班主任">el-table-column>
- <el-table-column prop="grade" label="年级">el-table-column>
- <el-table-column prop="createtime" label="创建日期">el-table-column>
- <el-table-column prop="updatetime" label="更新日期">el-table-column>
- <el-table-column prop="trs" label="授课教师" type="expand" width="100px">
- <template slot-scope="scope">
- <el-table
- size="small"
- :show-header="false"
- :data="scope.row.ts"
- style="width: 100%">
- <el-table-column prop="name" width="100px">el-table-column>
- <el-table-column prop="teacher">el-table-column>
- el-table>
- template>
- el-table-column>
- <el-table-column label="操作" width="150">
- <template slot-scope="scope">
- <el-button type="primary" size="mini" icon="el-icon-edit" circle @click="editClassEvent(scope.row.id)">el-button>
- <el-button type="danger" size="mini" icon="el-icon-delete" circle @click="deleteEvent(scope.row.id)">el-button>
- template>
- el-table-column>
- el-table>
- div>
-
- <ClassDialog :visible="isShowDialog" :uid="selectedId" @closeChange="closeChange" @saveSuccessChange="saveSuccessChange">ClassDialog>
-
- div>
js部分代码:
- import ClassDialog from '@/components/ClassDialog'
- import { formatDate } from '@/utils/utils'
- import { getClassList, deleteClassInfoById, deleteClassSelectedInfoByIds } from '@/api'
-
- export default {
- data () {
- return {
- //选中的ID
- selectedId: 0,
- //搜索关键事件
- keyword: "",
- /**
- * 是否显示弹框
- */
- isShowDialog: false,
- /**
- * 列表数据
- */
- tableList: [],
- /**
- * 选择项
- */
- multipleSelection: []
- }
- },
- components: {
- ClassDialog
- },
- created() {
- this.updateList();
- },
- methods: {
- /**
- * 更新地址
- */
- updateList(){
- getClassList(this.keyword).then(res => {
- if(res.code==1){
- this.tableList = res.data.map(item => {
- item['createtime'] = formatDate(item.createtime);
- item['updatetime'] = formatDate(item.updatetime);
- return item;
- });
- // console.log(this.tableList)
- }
- }).catch(e => {
- console.error(e);
- })
- },
- /**
- * 保存成功
- */
- saveSuccessChange(){
- this.updateList();
- this.isShowDialog = false;
- },
- /**
- * 显示弹框
- */
- showAddDialog(){
- this.isShowDialog = true;
- },
- /**
- * 关闭弹框
- */
- closeChange(){
- this.selectedId = 0;
- this.isShowDialog = false;
- },
- /**
- * 编辑班级信息
- */
- editClassEvent(id){
- this.selectedId = id;
- this.isShowDialog = true;
- },
- /**
- * 删除指定班级信息
- * @param {Object} id
- */
- deleteEvent(id){
- this.$confirm('确认要删除该班级信息吗?', '提示', {
- confirmButtonText: '删除',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(res => {
- deleteClassInfoById(id).then(() => {
- this.$message.success('删除成功!');
- this.updateList();
- }).catch(e => {
- this.$message.error(e.msg);
- })
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消删除'
- });
- });
- },
- /**
- * check 选中项项值
- * @param {Object} val
- */
- selectionChange(val){
- this.multipleSelection = val;
- },
- /**
- * 删除选中的班级信息
- */
- deleteSelectedClass(){
- if(this.multipleSelection.length==0){
- this.$message({
- type: 'info',
- message: '请选择删除项'
- });
- return;
- }
-
- this.$confirm('确认要删除选中的班级信息吗?', '提示', {
- confirmButtonText: '删除',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(res => {
- deleteClassSelectedInfoByIds(this.multipleSelection.map(item => item.id)).then(() => {
- this.$message.success('删除成功!');
- this.updateList();
- }).catch(e => {
- this.$message.error(e.msg);
- })
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消删除'
- });
- });
- },
-
- }
- }
列表界面如下:

如上图所示,现在班主任和年级信息无法显示,因为这里我们保存的是教师ID和年级ID,所以现在需要在列表查询功能中,增加master和grade两个字段,将查询到对应的数据赋值即可。
并且想要拿到对应id的name值,则需要去对应teacher表和grade表中进行查询,所以还要在对应表的操作文件中添加相应查询功能函数。通过传入的ID集进行匹配相应数据,并以ID为键名保存到新的变量值中,以便与教师列表中的ID相关联。
第一步:打开db/model/teacher.js,添加getTeacherByIdsCursor()函数,代码如下:
- /**
- * 通过游标获取对应数据集
- */
- export const getTeacherByIdsCursor = ids => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //通过ID获取数据
- let cursor = store.openCursor(),
- reData = {};
-
- cursor.onerror = function(e){
- reject();
- }
-
- cursor.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- if(ids.includes(result.value.id)){
- reData[result.value.id] = result.value;
- }
- result.continue();
- }else{
- resolve(reData);
- }
- }
- //end
- });
- }
第二步:打开db/model/grade.js,添加getGradeByIdsCursor()函数,代码如下:
- /**
- * 通过游标获取对应数据集
- */
- export const getGradeByIdsCursor = ids => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //通过ID获取数据
- let cursor = store.openCursor(),
- reData = {};
-
- cursor.onerror = function(e){
- reject();
- }
-
- cursor.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- if(ids.includes(result.value.id)){
- reData[result.value.id] = result.value;
- }
- result.continue();
- }else{
- resolve(reData);
- }
- }
- //end
- });
- }
第三步:打开db/model/classify.js文件,修改loadClassAllList()函数,代码如下:
- /**
- * 获取 班级信息
- */
- export const loadClassAllList = async (name) => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //获取所有数据
- let alls = store.getAll();
-
- alls.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- alls.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- let rData = result;
- if(name){
- rData = result.filter(item => item.name.includes(name));
- }
-
- let teacherIds = [];
- //拿到不重复的教师ID
- rData.forEach(item => {
- if(!teacherIds.includes(item.mid)){
- teacherIds.push(item.mid);
- }
-
- if(Array.isArray(item['ts'])&&item.ts.length>0){
- item.ts.forEach(sub => {
- if(!teacherIds.includes(sub.tid)){
- teacherIds.push(sub.tid);
- }
- });
- }
- })
-
- //查询关联数据
- Promise.all([
- getTeacherByIdsCursor(teacherIds),
- getGradeByIdsCursor(rData.map(item => item.gid))
- ]).then(res => {
- let teacher = res[0],
- grade = res[1];
-
- //重组数据
- rData = rData.map(item => {
- if('undefined'!==typeof teacher[item.mid]){
- item['master'] = teacher[item.mid]['name'];
- }
- if('undefined'!==typeof grade[item.gid]){
- item['grade'] = grade[item.gid]['name'];
- }
- //查询到授课教师信息
- if(Array.isArray(item['ts'])&&item.ts.length>0){
- item.ts = item.ts.map(sub => {
- if('undefined'!==typeof teacher[sub.tid]){
- sub['teacher'] = teacher[sub.tid]['name'];
- }
- return sub;
- })
- }
- return item;
- });
-
- resolve(
- rJson(1, rData, '获取成功~')
- )
- }).catch(e => {
- reject(
- rJson(0, null, '关联数据查询错误~')
- )
- });
-
-
- }else{
- reject(
- rJson(0, null, '未查询到数据~')
- )
- }
- }
-
- });
- }
此时再查看列表页,班主任和年级信息则显示出来了,如下图:

db/model/student.js代码如下:
- import { DBIsLoadSuccess, openTransactionIndex, CONST_READ } from '@/db'
- import { rJson } from '@/utils/utils'
- import { getClassByIdsCursor } from './classify.js'
-
- let storeName = 'student';
-
- /**
- * 获取 学员列表
- */
- export const loadStudentAllList = name => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //获取所有数据
- let alls = store.getAll();
-
- alls.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- alls.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- let rData = result;
- if(name){
- rData = result.filter(item => item.name.includes(name));
- }
-
- resolve(
- rJson(1, rData, '获取成功~')
- )
-
- }else{
- reject(
- rJson(0, null, '未查询到数据~')
- )
- }
- // console.log('store', result);
- }
-
- });
- }
-
- /**
- * 获取学员信息
- */
- export const getStudentInfoById = id => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //通过ID获取数据
- let data = store.get(id);
-
- data.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- data.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- resolve(
- rJson(1, result, '获取成功~')
- )
- }else{
- reject(
- rJson(0, e, '数据不存在~')
- );
- }
- }
- });
- }
-
- /**
- * 增加 或 编辑 员学信息
- */
- export const toggleStudent = data => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store, index} = openTransactionIndex(storeName, 'name', CONST_READ.READWRITE);
-
- let res;
- //ID存在,则为编辑
- if(data['id']&&data.id!=0){
- data['updatetime'] = new Date().getTime();
-
- //获取原数据
- res = store.get(data.id);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- //合并数据,并保存
- res = store.put(Object.assign(result, data));
-
- res.onerror = function(){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '保存成功~')
- )
- }
- }else{
- reject(
- rJson(0, e, '年级不存在~')
- );
- }
- }
-
- }
- //新增(需要判断是否已存在)
- else{
- //通过索引获取,判断是否已存在
- res = index.getKey(data.name);
-
- res.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(e){
- let result = e.target.result;
- //如果用已存在,返回错误信息
- if(result){
- reject(
- rJson(0, e, '该学员已存在~')
- );
- }
- //不存在,则直接添加
- else{
-
- data['createtime'] = new Date().getTime();
- data['updatetime'] = new Date().getTime();
- res = store.add(data);
-
- res.onerror = function(){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '保存成功~')
- )
- }
- }
- //if 2 end
- }
-
- //索引 End
- }
-
- //if end
-
- });
- }
-
- /**
- * 通过ID删除学员信息
- */
- export const deleteStudentById = id => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName, undefined, CONST_READ.READWRITE);
- //删除指定信息
- let res = store.delete(id);
- res.onerror = function(e){
- reject(
- rJson(0, e, '操作出错了~')
- );
- }
-
- res.onsuccess = function(){
- resolve(
- rJson(1, null, '删除成功~')
- )
- }
- });
- }
-
- /**
- * 通过ID删除多条学员信息
- */
- export const deleteStudentByIds = ids => {
- return new Promise((resolve, reject) => {
- if(Array.isArray(ids)){
- //打开游标
- let {store} = openTransactionIndex(storeName, undefined, CONST_READ.READWRITE);
- //打开游标
- let cursor = store.openCursor();
-
- cursor.onerror = function(e){
- reject(
- rJson(0, e, '操作出错了~')
- );
- }
-
- cursor.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- if(ids.includes(result.key)){
- result.delete();
- }
- result.continue();
- }else{
- resolve(
- rJson(1, null, '删除成功~')
- )
- }
- }
- }else{
- reject(
- rJson(0, e, '请传入数组形式ID数据~')
- );
- }
- //end
- });
- }
api/index.js文件中新增学员相关接口,代码如下:
- import {
- loadStudentAllList,
- toggleStudent,
- getStudentInfoById,
- deleteStudentById,
- deleteStudentByIds
- } from '@/db/model/student'
-
- /**
- * 获取学员列表数据
- */
- export const getStudentList = name => {
- return loadStudentAllList(name);
- }
-
- /**
- * 通过ID获取学员信息
- */
- export const loadStudentById = id => {
- return getStudentInfoById(id);
- }
-
- /**
- * 添加 或 修改学员数据
- */
- export const toggleStudentInfo = params => {
- return toggleStudent(params);
- }
-
- /**
- * 通过ID删除指定学员信息
- */
- export const deleteStudentInfoById = id => {
- return deleteStudentById(id);
- }
-
- /**
- * 删除选中的学员信息
- */
- export const deleteStudentInfoByIds = ids => {
- return deleteStudentByIds(ids);
- }
在components/StudentDialog/index.vue中添加新增页面,html代码如下:
- <template>
- <el-dialog :title="uid!=0?'编辑':'新增'" :visible="visible" @close="closeEvent" width="420px" class="dialog-wrap">
-
- <el-form :model="form" :rules="rules" status-icon ref="ruleForm">
- <el-form-item label="学员姓名" :label-width="formLabelWidth" required prop="name">
- <el-input v-model="form.name" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item label="户籍" :label-width="formLabelWidth" required prop="registration">
- <el-input v-model="form.registration" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item label="手机号" :label-width="formLabelWidth" required prop="phone">
- <el-input v-model="form.phone" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item label="年级" :label-width="formLabelWidth" prop="gid">
- <el-select v-model="form.gid" placeholder="请选择" @change="gradeChange">
- <el-option
- v-for="item in gradeOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value">
- el-option>
- el-select>
- el-form-item>
- <el-form-item label="班级" :label-width="formLabelWidth" prop="cid">
- <el-select v-model="form.cid" placeholder="请选择">
- <el-option
- v-for="item in classOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value">
- el-option>
- el-select>
- el-form-item>
- <el-form-item label="居住地址" :label-width="formLabelWidth" required prop="address">
- <el-input v-model="form.address" autocomplete="off" size="small">el-input>
- el-form-item>
- <el-form-item label="出生日期" :label-width="formLabelWidth" required prop="birthday">
- <el-date-picker v-model="form.birthday" value-format="yyyy-MM-dd" type="date" placeholder="选择日期">el-date-picker>
- el-form-item>
- el-form>
-
- <div slot="footer" class="dialog-footer">
- <el-button size="small" @click="closeEvent">取 消el-button>
- <el-button size="small" type="primary" @click="submitForm">保 存el-button>
- div>
-
- el-dialog>
- template>
js代码如下:
- import { toggleStudentInfo, loadStudentById, gradeAllList, getClassByKey } from '@/api'
- import { formatDate } from '@/utils/utils'
- export default {
- props: {
- //用户ID
- uid: {
- type: Number,
- default: () => 0
- },
- visible: {
- type: Boolean,
- default: () => false
- }
- },
- data(){
- return {
- formLabelWidth: '80px',
- gradeOptions: [],
- classOptions: [],
- dateValue: "",
- form: {
- name: "",
- registration: "",
- phone: "",
- gid: "",
- cid: "",
- address: "",
- birthday: ""
- },
- rules: {
- name: [
- { required: true, message: '请输入学员姓名', trigger: 'blur' },
- { required: true, message: '请输入学员姓名', trigger: 'change' },
- ],
- registration: [
- { required: true, message: '请输入户籍', trigger: 'blur' },
- { required: true, message: '请输入户籍', trigger: 'change' },
- ],
- phone: [
- { required: true, message: '请输入手机号', trigger: 'blur' },
- { required: true, message: '请输入手机号', trigger: 'change' },
- { tel: true, message: '请输入手机号', trigger: 'blur' },
- { tel: true, message: '请输入手机号', trigger: 'change' },
- ],
- gid: [
- { required: true, message: '请选择年级', trigger: 'change' },
- ],
- cid: [
- { required: true, message: '请选择班级', trigger: 'change' },
- ],
- address: [
- { required: true, message: '请输入现居住地址', trigger: 'blur' },
- { required: true, message: '请输入现居住地址', trigger: 'change' },
- ],
- birthday: [
- { required: true, message: '请选择出生日期', trigger: 'blur' },
- { required: true, message: '请选择出生日期', trigger: 'change' },
- { date: true, message: '请选择出生日期', trigger: 'blur' },
- { date: true, message: '请选择出生日期', trigger: 'change' },
- ]
- }
- }
- },
- watch: {
- uid(){
- if(this.uid!=0){
- this.updateStudentInfo();
- }
- }
- },
- created() {
- this.updateGradeInfo();
- },
- methods: {
- /**
- * 获取年级信息
- */
- updateGradeInfo(){
- gradeAllList().then(res => {
- if(res.code==1){
- this.gradeOptions = res.data.map(item => {
- return {
- label: item.name,
- value: item.id
- };
- })
- }
- }).catch(e => {
- console.error(e);
- })
- },
- /**
- * 获取班级信息
- */
- updateClassInfo(){
- getClassByKey(this.form.gid).then(res => {
- if(res.code==1){
- this.classOptions = res.data.map(item => {
- return {
- label: item.name,
- value: item.id
- };
- })
- }
- // console.log('res', res);
- }).catch(e => {
- console.error(e);
- })
- },
- /**
- * 年级发生变化
- */
- gradeChange(){
- this.form.cid = "";
- this.updateClassInfo();
- },
- /**
- * 获取班级
- */
- updateStudentInfo(){
- loadStudentById(this.uid).then(res => {
- console.log(res)
- if(res.code==1){
- let data = res.data,
- tmpData = {
- name: res.data['name'],
- registration: res.data['registration'],
- phone: res.data['phone'],
- // gid: "",
- // cid: "",
- address: res.data['address'],
- birthday: res.data['birthday']
- };
-
- if(data['gid']){
- tmpData['gid'] = data.gid;
- }
- if(data['cid']){
- tmpData['cid'] = data.cid;
- }
- this.form = tmpData;
-
- if(data['gid']){
- this.updateClassInfo();
- }
- }
- // console.log(res);
- }).catch(e => {
- console.error(e);
- })
- },
- /**
- * 获取保存数据
- */
- getParams(){
- let { name, registration, phone, address, birthday, gid, cid } = this.form;
- return {
- name, registration, phone, address, birthday, gid, cid
- }
- },
- /**
- * 添加班级信息
- */
- addUserInfo(){
- let param = this.getParams();
- toggleStudentInfo(param).then(res => {
- if(res.code==1){
- this.$message.success('保存成功');
- this.$emit('saveChange', {});
- }
- // console.log('success', res)
- }).catch(e => {
- this.$message.success(e.msg);
- });
- },
- /**
- * 编辑班级信息
- */
- editUserInfo(){
- let param = this.getParams();
- param['id'] = this.uid;
- toggleStudentInfo(param).then(res => {
- if(res.code==1){
- this.$message.success('保存成功');
- this.$emit('saveChange', {});
- }
- // console.log('success', res)
- }).catch(e => {
- this.$message.success(e.msg);
- });
- },
- /**
- * 提交表单
- */
- submitForm(){
- // console.log(this.form)
- this.$refs['ruleForm'].validate((valid) => {
- if(valid){
- //新增班级
- if(this.uid==0){
- this.addUserInfo();
- }
- //编辑班级
- else{
- this.editUserInfo();
- }
- }else{
- return false;
- }
- });
- },
- /**
- * 关闭事件
- */
- closeEvent(){
- this.$refs['ruleForm'].resetFields();
- this.$emit('closeChange', {});
- },
- }
- }
界面如下:

这里需要注意的是,为新增功能时,先加载年级数据列表,这部分接口是在之前年级功能实现就已经定义了,直接调用即可;当年级数据变化选中即,通过年级ID查询到对应的班级列表数据即可,这块接口也是在api/index.js中定义过的。
当为编辑功能时,获取到详情数据需判断年级ID是否存在,如果存在则需要通过年级ID查询 出对应班级数据列表。
在pages/student/index.vue中添加列表页面,html代码如下:
- <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" placeholder="请输入学员姓名" v-model="keyword">el-input>
- el-form-item>
- <el-form-item>
- <el-button size="small" type="primary" @click="updateList">查询el-button>
- el-form-item>
- el-form>
- div>
- <div class="item right">
- <el-form :inline="true" class="demo-form-inline">
- <el-form-item>
- <el-button size="small" type="primary" @click="showAddDialog">新增el-button>
- <el-button size="small" type="info" @click="deleteSelectedStudent">删除el-button>
- el-form-item>
- el-form>
- div>
- div>
-
- <div class="table-wrap">
- <el-table
- @selection-change="selectionChange"
- :data="tableList"
- style="width: 100%">
- <el-table-column type="selection" label="选择" width="50"> el-table-column>
- <el-table-column prop="name" label="学员姓名">el-table-column>
- <el-table-column prop="registration" label="户籍">el-table-column>
- <el-table-column prop="address" label="居住地址">el-table-column>
- <el-table-column prop="classify" label="班级">el-table-column>
- <el-table-column prop="age" label="年龄" width="80">
- <template slot-scope="scope">
- <span>{{scope.row.birthday | filterAge}}span>
- template>
- el-table-column>
- <el-table-column prop="createtime" label="创建日期" width="160">el-table-column>
- <el-table-column prop="updatetime" label="更新日期" width="160">el-table-column>
- <el-table-column label="操作" width="150">
- <template slot-scope="scope">
- <el-button type="primary" size="mini" icon="el-icon-edit" circle @click="editEvent(scope.row.id)">el-button>
- <el-button type="danger" size="mini" icon="el-icon-delete" circle @click="deleteEvent(scope.row.id)">el-button>
- template>
- el-table-column>
- el-table>
- div>
-
- <StudentDialog :visible="isShowDialog" :uid="selectId" @closeChange="closeDialog" @saveChange="saveChange">StudentDialog>
- div>
js代码部分:
- import StudentDialog from '@/components/StudentDialog'
- import { getStudentList, deleteStudentInfoById, deleteStudentInfoByIds } from '@/api'
- import { formatDate } from '@/utils/utils'
-
- export default {
- data () {
- return {
- //选中ID
- selectId: 0,
- //搜索关键词
- keyword: "",
- /**
- * 是否显示弹框
- */
- isShowDialog: false,
- /**
- * 列表数据
- */
- tableList: [],
- /**
- * 选择项
- */
- multipleSelection: []
- }
- },
- filters: {
- filterAge(val){
- let current = new Date(),
- bDate = new Date(val);
- return current.getFullYear() - bDate.getFullYear();
- }
- },
- components: {
- StudentDialog
- },
- created() {
- this.updateList();
- },
- methods: {
- /**
- * 获取列表数据
- */
- updateList(){
- getStudentList(this.keyword).then(res => {
- // console.log(res);
- if(res.code==1){
- this.tableList = res.data.map(item => {
- item['createtime'] = formatDate(item.createtime);
- item['updatetime'] = formatDate(item.updatetime);
- return item;
- });
- }
- }).catch(e => {
- console.error(e);
- })
- },
- /**
- * 显示弹框事件
- */
- showAddDialog(){
- this.isShowDialog = true;
- },
- /**
- * 关闭弹框
- */
- closeDialog(){
- this.selectId = 0;
- this.isShowDialog = false;
- },
- /**
- * 保存成功
- */
- saveChange(){
- this.updateList();
- this.isShowDialog = false;
- },
- /**
- * 编辑学员信息
- * @param {Object} id
- */
- editEvent(id){
- this.selectId = id;
- this.isShowDialog = true;
- },
- /**
- * 删除学员信息
- * @param {Object} id
- */
- deleteEvent(id){
- this.$confirm('确认要删除该学员信息吗?', '提示', {
- confirmButtonText: '删除',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(res => {
- deleteStudentInfoById(id).then(() => {
- this.$message.success('删除成功!');
- this.updateList();
- }).catch(e => {
- this.$message.error(e.msg);
- })
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消删除'
- });
- });
- },
- /**
- * check 选中项项值
- * @param {Object} val
- */
- selectionChange(val){
- this.multipleSelection = val;
- },
- /**
- * 删除选中的学员信息
- */
- deleteSelectedStudent(){
- if(this.multipleSelection.length==0){
- this.$message({
- type: 'info',
- message: '请选择删除项'
- });
- return;
- }
-
- this.$confirm('确认要删除选中的学员信息吗?', '提示', {
- confirmButtonText: '删除',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(res => {
- deleteStudentInfoByIds(this.multipleSelection.map(item => item.id)).then(() => {
- this.$message.success('删除成功!');
- this.updateList();
- }).catch(e => {
- this.$message.error(e.msg);
- })
- }).catch(() => {
- this.$message({
- type: 'info',
- message: '已取消删除'
- });
- });
- },
- //end
- }
- }
界面效果如下:

这里出现同样的问题,关键班级的信息未显示出来,和班级中查询关联数据一样,以同样方式即可。
第一步:打开db\model\classify.js文件,添加getClassByIdsCursor()函数,代码如下:
- /**
- * 通过游标获取对应数据集
- */
- export const getClassByIdsCursor = ids => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //通过ID获取数据
- let cursor = store.openCursor(),
- reData = {};
-
- cursor.onerror = function(e){
- reject();
- }
-
- cursor.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- if(ids.includes(result.value.id)){
- reData[result.value.id] = result.value;
- }
- result.continue();
- }else{
- resolve(reData);
- }
- }
- //end
- });
- }
第二步:打开db\model\student.js文件,修改loadStudentAllList()函数,代码如下:
- /**
- * 获取 学员列表
- */
- export const loadStudentAllList = name => {
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //获取所有数据
- let alls = store.getAll();
-
- alls.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- alls.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- let rData = result;
- if(name){
- rData = result.filter(item => item.name.includes(name));
- }
-
- getClassByIdsCursor(rData.filter(item => item.cid).map(item => item.cid)).then(res => {
- rData = rData.map(item => {
- if('undefined'!==typeof res[item.cid]){
- item['classify'] = res[item.cid]['name'];
- }
- return item;
- })
- resolve(
- rJson(1, rData, '获取成功~')
- )
- }).catch(e => {
- reject(
- rJson(0, e, '查询出错了~')
- )
- });
-
- }else{
- reject(
- rJson(0, null, '未查询到数据~')
- )
- }
-
- }
-
- });
- }
现在列表页面效果如下:

这里我们以学员列表为例,添加分页查询功能。注意的是,其他页面列表查询已在各关键页面中使用,为了避免影响别的功能,建议新建分页查询 函数。
首先打开src/utils/utils.js文件,添加分页功能函数,代码如下:
- /**
- * 生成分页数据
- */
- export const genderPage = (data, param) => {
- //判断分页数据是否存在,否则赋值默认参数
- param = param && 'undefined'!==typeof param['page'] && 'undefined'!==typeof param['pageSize'] ? param : {
- page: 1,
- pageSize: 10
- }
- let newData = data.map(item => item),
- start = (param.page - 1) * param.pageSize,
- end = newData.length - start < param.pageSize ? newData.length : start + param.pageSize;
- return newData.slice(start, end);
- }
打开db/model/student.js,添加分页查询函数loadStudentPage(),代码如下:
- import { DBIsLoadSuccess, openTransactionIndex, CONST_READ } from '@/db'
- import { rJson, genderPage } from '@/utils/utils'
- import { getClassByIdsCursor } from './classify.js'
-
- let storeName = 'student';
-
- /**
- * 获取 学员列表 - 分页模式
- * @param name 查询关键词
- * @param param 分页参数
- */
- export const loadStudentPage = (name, param) => {
-
- return new Promise((resolve, reject) => {
- //打开游标
- let {store} = openTransactionIndex(storeName);
- //获取所有数据
- let alls = store.getAll();
-
- alls.onerror = function(e){
- reject(
- rJson(0, e, '查询出错了~')
- );
- }
-
- alls.onsuccess = function(e){
- let result = e.target.result;
- if(result){
- let rData = result;
- if(name){
- rData = result.filter(item => item.name.includes(name));
- }
- //查询班级关联数据
- getClassByIdsCursor(rData.filter(item => item.cid).map(item => item.cid)).then(res => {
- rData = rData.map(item => {
- if('undefined'!==typeof res[item.cid]){
- item['classify'] = res[item.cid]['name'];
- }
- return item;
- })
-
- //通过genderPageData函数进行分页处理
- resolve(
- rJson(1, {
- list: genderPage(rData, param),
- total: rData.length
- }, '获取成功~')
- )
- }).catch(e => {
- reject(
- rJson(0, e, '查询出错了~')
- )
- });
-
- }else{
- reject(
- rJson(0, null, '未查询到数据~')
- )
- }
- }
-
- });
- }
打开api/index.js,添加分页查询接口函数,代码如下:
- import {
- loadStudentPage
- } from '@/db/model/student'
-
- /**
- * 获取学员列表数据 - 分页模式
- */
- export const getStudentPageList = (name, param) => {
- return loadStudentPage(name, param);
- }
html部分,在列表下添加分页代码,代码如下:
- <div class="table-wrap">
- ...
-
- <el-pagination
- background
- layout="prev, pager, next"
- @current-change="currentChange"
- :current-page="page"
- :page-size="pageSize"
- :total="pageTotal">
- el-pagination>
- div>
js部分,引入getStudentPageList接口函数,在data中添加分页参数,增加分页切换事件,代码如下:
- import StudentDialog from '@/components/StudentDialog'
- import { getStudentList, getStudentPageList, deleteStudentInfoById, deleteStudentInfoByIds } from '@/api'
- import { formatDate } from '@/utils/utils'
-
- export default {
- data () {
- return {
- //...
-
- //分页参数
- page: 1,
- pageSize: 5,
- pageTotal: 0
- }
- },
- filters: {
- filterAge(val){
- let current = new Date(),
- bDate = new Date(val);
- return current.getFullYear() - bDate.getFullYear();
- }
- },
- components: {
- StudentDialog
- },
- created() {
- this.updateList();
- },
- methods: {
- /**
- * 当前页发生改变
- */
- currentChange(page){
- this.page = page;
- this.updateList();
- }
- }
由于分页查询功能中需要返回数据总量,则原来返回结果结构发生变化,所以updateList()函数需要稍微调整下,代码如下:
- methods: {
- /**
- * 获取列表数据
- */
- updateList(){
- getStudentPageList(this.keyword, {
- page: this.page,
- pageSize: this.pageSize
- }).then(res => {
- if(res.code==1){
- this.pageTotal = res.data['total'];
- this.tableList = res.data['list'].map(item => {
- item['createtime'] = formatDate(item.createtime);
- item['updatetime'] = formatDate(item.updatetime);
- return item;
- });
- }
- }).catch(e => {
- console.error(e);
- })
- },
-
- //...
- }
此时页面效果如下:

到此为止,该系统开发则已经完结了,有兴趣的朋友可以再升级和优化下。
由于近期工作原因,不是每天都能抽出时间开发,所以有些不太连贯,望见谅。此篇对增删改查也没作太多细讲,因为都差不多,大家可以拷贝代码到本地运行自行研究。