- indexDB就是浏览器内置的前端数据库,跟localStorage等一样可进行存储,不过indexDB可以存储250~300MB,当然又优点也会有缺点,选择适合项目的就可以,下面简单的介绍下如何使用
- 连接数据库
const data = reactive({
db: null,
storeName: 'test', //当前的数据库名
version: 1, //版本号
obj: {
name: 4,
id: 4,
age: 66,
list: [1, 2, 3]
}
})
function init(data) {
const request = (window.indexedDB || window.webkitIndexedDB).open(data.storeName, data
.version)
request.onsuccess = e => {
console.log('数据库打开成功', e.target.result);
data.db = e.target.result
}
request.onerror = e => {
console.log('数据库启动报错', e);
throw Error('数据库报错啦:' + e.target.result)
}
//数据库创建或者升级的时候都会触发
request.onupgradeneeded = e => {
data.db = e.target.result
let objectStore = null
if (!data.db.objectStoreNames.contains(data.storeName)) {
//在数据库中创建表group,设置主键为id,属性中必须要有id的字段
objectStore = data.db.createObjectStore(data.storeName, {
keyPath: 'id'
})
//创建索引indexName指向表中的name字段且设为唯一值,不能重复,属性中可以没有name属性,但是id必须要有
objectStore.createIndex('indexName', 'name', {
unique: true
}) // 创建索引 可以让你搜索任意字段
}
}
}
上面的代码中使用了id作为主键,在添加的属性中必须要有id这个字段,storeName是数据库的名字,可以有多个数据库
添加数据
//添加数据
const addData = (db, storeName, obj) => {
//readwrite 读写操作的权限
const request = db.transaction([storeName], 'readwrite').objectStore(storeName).add(obj)
request.onsuccess = e => {
console.log('写入成功', e.target.result);
//这里可以做一些操作,添加第一次之后数据还是相同的就要进行阻止或者清空,否则报错
//readyState为done是添加完毕
}
request.onerror = e => {
console.log('写入失败:', e);
throw Error('写入失败:' + e.target.result)
}
}
这里是使用vue进行练习的,如果你的添加数据使用的是响应式的,那么就需要转为原始的数据才可以添加成功,reactive转为toRaw
- 获取数据
// 获取某一条数据
const getData = (db, storeName, key) => {
// transaction 第二个参数不写,默认是只读,key是当前属性的id值
const request = db.transaction([storeName]).objectStore(storeName).get(key)
request.onsuccess = e => {
console.log('读取成功', e.target.result);
}
request.onerror = e => {
console.log('读取失败:', e);
throw Error('读取失败:' + e.target.result)
}
}
- 获取当前数据库下当前表下的全部数据
const getAllData = (db, storeName) => {
// transaction 第二个参数不写,默认是只读
const request = db.transaction([storeName]).objectStore(storeName).getAll()
request.onsuccess = e => {
console.log('读取全部成功', e.target.result);
}
request.onerror = e => {
console.log('读取全部失败:', e);
throw Error('读取全部失败:' + e.target.result)
}
}
- 通过索引值进行查询数据
// 通过索引name获取数据
const getNameData = (db, storeName, name) => {
// transaction 第二个参数不写,默认是只读
const request = db.transaction([storeName]).objectStore(storeName).index('indexName').get(name)
request.onsuccess = e => {
console.log('读取索引成功', e.target.result);
}
request.onerror = e => {
console.log('读取索引失败:', e);
throw Error('读取索引失败:' + e.target.result)
}
}
- 更新某一条数据
// 更新某一条数据
const upData = (db, storeName, data) => {
// data 是当前的某一条数据更新的对象
const request = db.transaction([storeName], 'readwrite').objectStore(storeName).put(data)
request.onsuccess = e => { //readyState为done是更新完毕,或者result会返回当前的id值可进行判断
console.log(e.target.result, e.target);
console.log('更新成功', e.target.result);
}
request.onerror = e => {
console.log('更新失败:', e);
throw Error('更新失败:' + e.target.result)
}
}
- 删除某一条数据
// 删除某一条数据
const deleteData = (db, storeName, key) => {
const request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(key); //key---id值
request.onsuccess = e => { //readyState为done是更新完毕
console.log(e.target.result, e.target);
console.log('删除成功', e.target.result);
}
request.onerror = e => {
console.log('删除失败:', e);
throw Error('删除失败:' + e.target.result)
}
}
- 遍历当前表下的所有数据,第二个方法可做分页的操作
// 使用指针遍历所有值使用id
const fORData = (db, storeName) => {
const request = db.transaction([storeName], 'readwrite').objectStore(storeName)
request.openCursor().onsuccess = e => { //readyState为done是更新完毕
var cursor = event.target.result;
if (cursor) {
console.log("当前的id值: " + cursor.key + " 和age值 " + cursor.value.age);
cursor.continue();
} else {
console.log("结束遍历");
}
}
request.onerror = e => {
console.log('遍历所有值失败:', e);
throw Error('遍历所有值失败:' + e.target.result)
}
}
// 使用指针遍历所有值,使用name索引
const fORData1 = (db, storeName) => {
const objectStore = db.transaction([storeName]).objectStore(storeName)
var index = objectStore.index("indexName");
const range = IDBKeyRange.bound(1, 10); //遍历id从1到10的数据
index.openCursor(range).onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
console.log("当前的name值: " + cursor.key + " 和age值 " + cursor.value.id);
cursor.continue();
} else {
console.log("结束遍历");
}
};
index.openCursor(range).onerror = e => {
console.log('遍历所有值失败:', e);
throw Error('遍历所有值失败:' + e.target.result)
}
}
- 最后整体的代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<button @click="startDB">启动数据库</button>
<button @click="addBase">添加数据</button>
<button @click="getBase">读取数据</button>
<button @click="getNameBase">读取索引数据</button>
<button @click="getAllBase">读取全部数据</button>
<button @click="upBase">更新数据</button>
<button @click="deleteBase">删除数据</button>
<button @click="forBase">指针遍历</button>
</div>
</body>
</html>
<script>
const {
createApp,
reactive,
toRefs,
toRaw
} = Vue
createApp({
setup() {
const data = reactive({
db: null,
storeName: 'test', //当前的数据库名
version: 1, //版本号
obj: {
name: 44,
id: 44,
age: 66,
list: [1, 2, 3]
}
})
// 启动数据库
const startDB = () => {
init(data)
}
//添加数据
const addBase = () => {
//使用reactive会将数据变为响应式,添加会报错,将响应式数据转为原始对象(不是响应式的就可以存储)
addData(data.db, data.storeName, toRaw(data.obj))
}
// 获取数据
const getBase = () => {
getData(data.db, data.storeName, 7) //根据id进行读取
}
// 更新某一项
const upBase = () => {
upData(data.db, data.storeName, {
id: 6,
age: 222,
list: 333
}) //根据id进行读取
}
// 删除某一项
const deleteBase = () => {
deleteData(data.db, data.storeName, 5) //根据id进行读取
}
// 读取全部的数据
const getAllBase = () => {
getAllData(data.db, data.storeName)
}
// 读取索引的数据
const getNameBase = () => {
getNameData(data.db, data.storeName, 6)
}
const forBase = () => {
fORData(data.db, data.storeName) //遍历有id值
fORData1(data.db, data.storeName) //遍历通过name索引
}
return {
startDB,
addBase,
getBase,
upBase,
deleteBase,
getAllBase,
getNameBase,
forBase,
...toRefs(data)
}
}
}).mount('#app')
function init(data) {
const request = (window.indexedDB || window.webkitIndexedDB).open(data.storeName, data
.version)
request.onsuccess = e => {
console.log('数据库打开成功', e.target.result);
data.db = e.target.result
}
request.onerror = e => {
console.log('数据库启动报错', e);
throw Error('数据库报错啦:' + e.target.result)
}
//数据库创建或者升级的时候都会触发
request.onupgradeneeded = e => {
data.db = e.target.result
let objectStore = null
if (!data.db.objectStoreNames.contains(data.storeName)) {
//在数据库中创建表group,设置主键为id,属性中必须要有id的字段
objectStore = data.db.createObjectStore(data.storeName, {
keyPath: 'id'
})
//创建索引indexName指向表中的name字段且设为唯一值,不能重复,属性中可以没有name属性,但是id必须要有
objectStore.createIndex('indexName', 'name', {
unique: true
}) // 创建索引 可以让你搜索任意字段
}
}
}
//添加数据
const addData = (db, storeName, obj) => {
//读写操作
const request = db.transaction([storeName], 'readwrite').objectStore(storeName).add(obj)
request.onsuccess = e => {
console.log('写入成功', e.target.result);
}
request.onerror = e => {
console.log('写入失败:', e);
throw Error('写入失败:' + e.target.result)
}
}
// 获取数据
const getData = (db, storeName, key) => {
// transaction 第二个参数不写,默认是只读
const request = db.transaction([storeName]).objectStore(storeName).get(key)
request.onsuccess = e => {
console.log('读取成功', e.target.result);
}
request.onerror = e => {
console.log('读取失败:', e);
throw Error('读取失败:' + e.target.result)
}
}
// 通过索引name获取数据
const getNameData = (db, storeName, name) => {
// transaction 第二个参数不写,默认是只读
const request = db.transaction([storeName]).objectStore(storeName).index('indexName').get(name)
request.onsuccess = e => {
console.log('读取索引成功', e.target.result);
}
request.onerror = e => {
console.log('读取索引失败:', e);
throw Error('读取索引失败:' + e.target.result)
}
}
// 获取数据
const getAllData = (db, storeName) => {
// transaction 第二个参数不写,默认是只读
const request = db.transaction([storeName]).objectStore(storeName).getAll()
request.onsuccess = e => {
console.log('读取全部成功', e.target.result);
}
request.onerror = e => {
console.log('读取全部失败:', e);
throw Error('读取全部失败:' + e.target.result)
}
}
// 更新某一条数据
const upData = (db, storeName, data) => {
const request = db.transaction([storeName], 'readwrite').objectStore(storeName).put(data)
request.onsuccess = e => { //readyState为done是更新完毕,或者result会返回当前的id值可进行判断
console.log(e.target.result, e.target);
console.log('更新成功', e.target.result);
}
request.onerror = e => {
console.log('更新失败:', e);
throw Error('更新失败:' + e.target.result)
}
}
// 删除某一条数据
const deleteData = (db, storeName, key) => {
const request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(key); //key---id值
request.onsuccess = e => { //readyState为done是更新完毕
console.log(e.target.result, e.target);
console.log('删除成功', e.target.result);
}
request.onerror = e => {
console.log('删除失败:', e);
throw Error('删除失败:' + e.target.result)
}
}
// 使用指针遍历所有值使用id
const fORData = (db, storeName) => {
const request = db.transaction([storeName], 'readwrite').objectStore(storeName)
request.openCursor().onsuccess = e => { //readyState为done是更新完毕
var cursor = event.target.result;
if (cursor) {
console.log("当前的id值: " + cursor.key + " 和age值 " + cursor.value.age);
cursor.continue();
} else {
console.log("结束遍历");
}
}
request.onerror = e => {
console.log('遍历所有值失败:', e);
throw Error('遍历所有值失败:' + e.target.result)
}
}
// 使用指针遍历所有值,使用name索引
const fORData1 = (db, storeName) => {
const objectStore = db.transaction([storeName]).objectStore(storeName)
var index = objectStore.index("indexName");
const range = IDBKeyRange.bound(1, 10); //遍历id从1到10的数据
index.openCursor(range).onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
console.log("当前的name值: " + cursor.key + " 和age值 " + cursor.value.id);
cursor.continue();
} else {
console.log("结束遍历");
}
};
index.openCursor(range).onerror = e => {
console.log('遍历所有值失败:', e);
throw Error('遍历所有值失败:' + e.target.result)
}
}
</script>
- 代码中的onsuccess和onerror函数可以封装一个公共的或者你有更好的方式