Vue+ElementUi+IndexedDB完整代码、浏览器本地存储、数据库、缓存、objectStore、openCursor、getAll、delete、window、open、add、put

48 篇文章 1 订阅
21 篇文章 0 订阅


1、main文件

import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
// indexedDB数据库
import indexedDB from '@/utils/indexedDB.js';
// 功能模块文件
import functionalModule from '@/utils/index.js';

Vue.prototype.$functionalModule = functionalModule;
Vue.prototype.$indexedDB = indexedDB;
// myDB:数据库 mySurface:数据表 1:数据库版本
indexedDB.openDB('myDB', 'mySurface', 1).then((res) => {
  // 两种方式实现无处访问db实例
  // 封装文件夹时使用
  window.$db = res;
  // 页面单独请求使用
  Vue.prototype.$db = res;
});
Vue.use(ElementUI);
Vue.config.productionTip = false;

// 如果不阻塞
// 页面打开会报错
// 因为数据库实例还未完全创建
setTimeout(() => {
  new Vue({
    render: h => h(App),
  }).$mount('#app');
}, 0);

2、indexedDB文件

// 引入elementUi的Message组件
import { Message } from "element-ui";

/*
 * 打开数据库
 * @param {object} dbName 数据库的名字
 * @param {string} storeName 仓库名称/表名称
 * @param {string} version 数据库的版本
 * @return {object} 该函数会返回一个数据库实例
 */
function openDB(dbName, storeName, version = 1) {
    return new Promise((resolve, reject) => {
        //  兼容浏览器
        let indexedDB =
            window.indexedDB ||
            window.mozIndexedDB ||
            window.webkitIndexedDB ||
            window.msIndexedDB,
            db;

        // 打开数据库,若没有则会创建
        const request = indexedDB.open(dbName, version);

        // 数据库打开成功回调
        request.onsuccess = function (result) {
            // 数据库对象
            db = result.target.result;
            resolve(db);
        };

        // 数据库打开失败的回调
        request.onerror = function (result) {
            reject(result);
        };

        // 数据库有更新时候的回调
        request.onupgradeneeded = function (result) {
            // 数据库创建或升级的时候会触发
            // 数据库对象
            db = result.target.result;
            // 创建存储库/也就是数据表
            let objectStore = db.createObjectStore(storeName, {
                // 这是主键
                // 主键使用的是数据表里的id值
                keyPath: "id",
                // 实现自增
                // autoIncrement: false

                // 如果有keyPath属性
                // 定义autoIncrement属性无效
                // 当没有keyPath属性时
                // 定义autIncrement属性有效
                // 且值必须为true
                // 否则报错
            });

            // 创建索引/属性,在后面查询数据的时候可以根据索引/属性查
            // 不能缺少的索引
            objectStore.createIndex("id", "id", { unique: false });
            objectStore.createIndex("name", "name", { unique: false });
            objectStore.createIndex("age", "age", { unique: false });
        };
    });
}

/*
 * 新增数据
 * @param {string} storeName 仓库名称/表名称
 * @param {string} data 数据
 */
function addData(storeName, data) {
    return new Promise((resolve, reject) => {
        let request = window.$db
            // 事务对象 指定表格名称和操作模式("只读"或"读写")
            .transaction([storeName], "readwrite")
            // 仓库对象
            .objectStore(storeName)
            .add(data);

        request.onsuccess = function (result) {
            Message({
                message: '添加成功',
                type: 'success'
            });
            resolve(result);
        };

        request.onerror = function (result) {
            Message({
                message: '添加失败',
                type: 'error'
            });
            reject(result);
        };
    });
}

/*
 * 通过getAll读取数据
 * @param {string} storeName 仓库名称/表名称
 */
function getAll(storeName) {
    return new Promise((resolve, reject) => {
        let request = window.$db
            // 事务
            .transaction(storeName, "readwrite")
            // 仓库对象
            .objectStore(storeName)
            // 指针对象
            .getAll();

        // 游标开启成功,逐行读数据
        request.onsuccess = function (result) {
            Message({
                message: '获取成功',
                type: 'success'
            });
            resolve(result);
        };

        request.onerror = function (result) {
            Message({
                message: '获取失败',
                type: 'error'
            });
            reject(result);
        };
    });
}

/*
 * 通过游标读取数据
 * @param {string} storeName 仓库名称/表名称
 */
function cursorGetData(storeName) {
    return new Promise((resolve, reject) => {
        let list = [],
            request = window.$db
                // 事务
                .transaction(storeName, "readwrite")
                // 仓库对象
                .objectStore(storeName)
                // 指针对象
                .openCursor();

        // 游标开启成功,逐行读数据
        request.onsuccess = function (result) {
            let cursor = result.target.result;
            if (cursor) {
                // 必须要检查
                list.push(cursor.value);
                // 遍历了存储对象中的所有内容
                cursor.continue();
            } else {
                Message({
                    message: '获取成功',
                    type: 'success'
                });
                resolve(list);
            }
        };

        request.onerror = function (result) {
            Message({
                message: '获取失败',
                type: 'error'
            });
            reject(result);
        };
    });
}

/*
 * 通过索引和游标查询记录/全值搜索
 * @param {string} storeName 仓库名称/表名称
 * @param {string} indexName 索引名/属性名
 * @param {string} indexValue 索引值/属性值
 */
function fullValueSearch(storeName, indexName, indexValue) {
    return new Promise((resolve, reject) => {
        let list = [],
            // 仓库对象
            request = window.$db
                .transaction(storeName, "readwrite")
                .objectStore(storeName)
                // 索引对象
                .index(indexName)
                // 指针对象
                .openCursor(IDBKeyRange.only(indexValue));

        request.onsuccess = function (result) {
            let cursor = result.target.result;
            if (cursor) {
                // 必须要检查
                list.push(cursor.value);
                // 遍历了存储对象中的所有内容
                cursor.continue();
            } else {
                Message({
                    message: '搜索成功',
                    type: 'success'
                });
                resolve(list);
            }
        };

        request.onerror = function (result) {
            Message({
                message: '搜索失败',
                type: 'error'
            });
            reject(result);
        };
    });
}

/*
 * 通过getAll实现模糊查找/查询/搜索/分页
 * @param {string} storeName 仓库名称/表名称
 * @param {string} searchName 搜索的字段/属性
 * @param {string} searchValue 搜索的值
 * @param {string} page 当前页数
 * @param {string} pageSize 每页大小
 */
function vagueLookup(storeName, searchName, searchValue, page, pageSize) {
    return new Promise((resolve, reject) => {
        let list = [],
            total = 0,
            len = 0,
            request = window.$db
                // 事务
                .transaction(storeName, "readwrite")
                // 仓库对象
                .objectStore(storeName)
                // 指针对象
                .getAll();

        request.onsuccess = function (result) {
            let res = result.target.result;
            Message({
                message: '查询成功',
                type: 'success'
            });
            // 倒序b-a
            res = res.sort((a, b) => new Date(b.updateDate) - new Date(a.updateDate));
            // 总数
            total = res.length;

            // 搜索
            if (searchValue != '') {
                res.forEach(item => { if (item[searchName].indexOf(searchValue) !== -1) list.push(item); });
            } else {
                // 正常请求数据
                list = res;
            }

            // 每页大小
            // 如果大小大于数组长度
            // 就使用数组长度
            len = list.length > pageSize ? pageSize : list.length;
            // 第几页
            page = page == 1 ? 0 : (page - 1) * pageSize;

            resolve({
                total,
                list: list.splice(page, len)
            });
        };

        request.onerror = function (result) {
            Message({
                message: '查询失败',
                type: 'error'
            });
            reject(result);
        };
    });
}

/*
 * 更新数据
 * @param {string} storeName 仓库名称/表名称
 * @param {object} data 数据
 */
function updateDB(storeName, data) {
    return new Promise((resolve, reject) => {
        let request = window.$db
            // 事务对象
            .transaction([storeName], "readwrite")
            // 仓库对象
            .objectStore(storeName)
            .put(data);

        request.onsuccess = function (result) {
            Message({
                message: '更新成功',
                type: 'success'
            });
            resolve(result);
        };

        request.onerror = function (result) {
            Message({
                message: '更新失败',
                type: 'error'
            });
            reject(result);
        };
    });
}

/*
 * 通过主键删除数据
 * @param {string} storeName 仓库名称/表名称
 * @param {object} id 主键值
 */
function deleteDB(storeName, id) {
    return new Promise((resolve, reject) => {
        let request = window.$db
            .transaction([storeName], "readwrite")
            .objectStore(storeName)
            .delete(id);

        request.onsuccess = function (result) {
            Message({
                message: '删除成功',
                type: 'success'
            });
            resolve(result);
        };

        request.onerror = function (result) {
            Message({
                message: '删除失败',
                type: 'error'
            });
            reject(result);
        };
    });
}

let indexedDB = {
    deleteDB,
    updateDB,
    vagueLookup,
    fullValueSearch,
    cursorGetData,
    getAll,
    addData,
    openDB,
};

export default indexedDB;

3、使用

3.1、查/删

methods: {
	// 清空搜索框
	inputSearch(event) {
		if (!event) this.getData();
	},
	
	// 搜索
	async clickSearc() {
		if (!this.searchName.replace(/\s*/g, "")) return this.$message.warning("请输入内容");
		
		// 通过getAll实现模糊查找/查询/搜索/分页
		this.getData();
		
		// 通过索引和游标查询记录/全值搜索
		// this.dataList = await this.$indexedDB.fullValueSearch(
		//   "mySurface",
		//   "name",
		//   searchName
		// );
		
		this.total = this.dataList.length;
	},
	
	// 删除
	clickDelete(row) {
		this.$confirm("此操作将永久删除该数据, 是否继续?", "删除数据", {
			confirmButtonText: "确定",
			cancelButtonText: "取消",
			type: "warning",
		})
		.then(() => {
			this.$indexedDB.deleteDB("mySurface", row.id);
			this.getData();
		})
		.catch(() => {
			this.$message({
				type: "info",
				message: "已取消删除",
			});
		});
	},
	
	// 获取数据
	async getData() {
		// 通过getAll实现模糊查找/查询/搜索/分页
		let { total, list } = await this.$indexedDB.vagueLookup(
			"mySurface",
			"name",
			this.searchName,
			this.currentPage,
			this.pageSize
		);
		this.dataList = list;
		this.total = total;
		
		// ---------------------------------
		// 通过游标读取数据(可以分页)
		// let res = await this.$indexedDB.cursorGetData("mySurface");
		// this.dataList = res;
		
		// ---------------------------------
		// 通过getAll读取数据(不能分页)
		// let {
		//   target: { result },
		// } = await this.$indexedDB.getAll("mySurface");
		// this.dataList = result;
	},
},

3.2、增/改

methods: {
	// 添加数据
	submitForm(formName) {
		this.$refs[formName].validate((valid) => {
			if (valid) {
				let { id, name, age, politicalOutlook, createDate, updateDate } = this.ruleForm,
					timeDateFormat = this.$functionalModule.timeDateFormat(),
					obj = { id, name, age, politicalOutlook, createDate, updateDate, };
		
				if (this.panelStatus == 0) {
					obj.id = new Date().getTime();
					obj.createDate = timeDateFormat;
					obj.updateDate = timeDateFormat;
					this.$indexedDB.addData("mySurface", obj);
				} else {
					obj.updateDate = timeDateFormat;
					this.$indexedDB.updateDB("mySurface", obj);
				}
		
				this.$emit("closes");
				this.ruleForm = {
					name: null,
					age: null,
					politicalOutlook: 1,
				};
				this.$refs[formName].resetFields();
				this.dialogFormVisible = false;
			} else {
				console.log("error submit!!");
				return false;
			}
		});
	},
	
	// 重置
	resetForm(formName) {
		this.$refs[formName].resetFields();
	},
}

4、完整代码

gitee(码云)develop分支 idexedDB文件夹


5、关于IndexedDB的详细介绍

1、CSDN-IndexedDB浏览器本地存储、缓存、数据库、介绍

以下是使用VueElementUI、MyBatis和SpringBoot实现MD5加密的完整代码前端代码(使用VueElementUI): ```html <template> <el-form ref="form" :model="loginForm" label-width="80px"> <el-form-item label="用户名" prop="username"> <el-input v-model="loginForm.username"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input type="password" v-model="loginForm.password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="login">登录</el-button> </el-form-item> </el-form> </template> <script> export default { data() { return { loginForm: { username: '', password: '' } } }, methods: { login() { this.$axios.post('/login', { username: this.loginForm.username, password: this.md5(this.loginForm.password) }).then(response => { console.log(response.data) }).catch(error => { console.log(error) }) }, md5(str) { // 请在这里添加MD5加密算法的实现代码 } } } </script> ``` 后端代码(使用MyBatis和SpringBoot): ```java @RestController public class LoginController { @Autowired private UserService userService; @PostMapping("/login") public Response login(@RequestBody LoginForm loginForm) { User user = userService.getUserByUsername(loginForm.getUsername()); if (user == null) { return Response.error("用户不存在"); } if (!user.getPassword().equals(loginForm.getPassword())) { return Response.error("密码错误"); } return Response.success("登录成功"); } } @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User getUserByUsername(String username) { return userMapper.selectByUsername(username); } } @Mapper public interface UserMapper { @Select("SELECT * FROM user WHERE username = #{username}") User selectByUsername(@Param("username") String username); } public interface UserService { User getUserByUsername(String username); } public class User { private Long id; private String username; private String password; // 省略getter和setter方法 } ``` 请注意,以上代码只是示例代码,实际项目中需要根据具体需求进行修改和优化。另外,MD5加密算法的实现代码需要根据具体语言和库进行选择和编写。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值