PS1:点击查看Blazor中C#和JS互操作
PS2:Vue中,可以直接使用LocalStorage和IndexedDB对象,本章节案例主要以Blazor的使用为主
一、Storage对象
1、浏览器内置的键值对存储。locallStorage理论上永久保存在浏览器中(除非主动清除),而SessionStorage只在当前会话中有效,标签页或浏览器关闭,自动清除。遵守同源限制(按协议、域名和端口隔离),同一站点的Storage,大小限制为5M,键值支持JSON格式。常用API如下所示(SessionStorage和LocalStorage用法一样):
//①存储和更新数据 //存储名字为name值为lily的变量 localStorage.setItem("name","lily"); //可以用点(.)操作符,及[]的方式进行数据存储 localStorage.name = "lily"; //②读取数据 //读取指定键数据 localStorage.getItem("name"); var name = localStorage.name; //读取第一条数据 localStorage.key(0); //遍历localStorage for(var i=0; i<localStorage.length;i++){ ...... } //③删除数据 localStorage.removeItem("name"); localStorage.name = ""; //④全部清除数据 localStorage.clear();
2、在Blazor中使用Storage
//C#中调用JS的步骤: //①注入IJSRuntime,inject IJSRuntime JS //②无返回值,调用JS.InvokeVoidAsync("JS函数名",参数1,参数2...) //③有返回值,调用JS.InvokeAsync<T>("JS函数名",参数1,参数2...) //localStorage.setItem等,是JS内置函数,定义在window对象下,可以直接调用,不需要在JS文件中定义 @page "/" @inject IJSRuntime JS <h1>来自LocalStorage,键名为"name"的值:@name</h1> <button @onclick="@(()=>SetLocalStorage("name","functionMC"))">设置localStorage值</button> <button @onclick="@(()=>GetLocalStorage("name"))">读取localStorage值</button> @code{ private string? name; private async Task SetLocalStorage(string key,string value) { await JS.InvokeVoidAsync("localStorage.setItem", key, value); } private async Task GetLocalStorage(string key) { name = await JS.InvokeAsync<string>("localStorage.getItem", key); } }
二、IndexedDB对象
IndexedDB是浏览器内置的非关系型数据库,以键值对的方式保存数据,理论上大小从250M起,是Web应用首推的本地数据库,相当于手机APP端的SQLite。支持异步、事务、索引,字段值支持二进制储存,如ArrayBuffer和Blob对象,和Storage一样,遵守同源限制。IndexedDB的使用,比Storage复杂,我们择其要点进行学习。
1、IndexedDB的常用内置对象,包括:
- 数据库:IDBDatabase
- 对象仓库:IDBObjectStore,相当于数据表
- 索引: IDBIndex
- 事务: IDBTransaction
- 操作请求:IDBRequest
- 指针: IDBCursor
- 主键集合:IDBKeyRange
2、常用方法
(1)新建、打开或升级数据库
//如果没有则新建数据库TestDB,且版本号为1 //如果已有数据库TestDB,且版本号一致,则打开数据库 //如果已有数据库TestDB,但版本号不一致,则升级数据库并打开 var request = window.indexedDB.open("TestDB", 1); request.onerror = function(event) { console.log('数据库打开报错'); } var db; request.onsuccess = function(event) { db = request.result; console.log('数据库打开成功'); } request.onupgradeneeded = function(event) { db = event.target.result; console.log("数据库升级成功"); }
(2)创建表、自增键、索引,关闭或删除数据库
//创建表在request.onupgradeneeded方法中进行 //创建数据表book,主键(keyPath)为id request.onupgradeneeded = function(event) { db = event.target.result; var objectStore; if (!db.objectStoreNames.contains("book")) { objectStore = db.createObjectStore("book", {keyPath: "id"}); } } //创建数据表book,并使用自增主键 request.onupgradeneeded = function(event) { db = event.target.result; var objectStore; if (!db.objectStoreNames.contains("book")) { objectStore = db.createObjectStore("book", {autoIncrement: true}); } } //一般创建数据表后,可以创建索引 //注意索引是针对键值Value来建的,每条记录的Value都是JSON objectStore.createIndex("name", "name", { unique: true });
(3)关闭或删除数据库
db.close(); window.indexedDB.deleteDatabase("book");
(4)CRUD操作
//新增操作================================== //注意:Key值(主键)自增,插入记录中的id,name都是Value的JSON成员 function add(book) { var request = db.transaction(["book"], "readwrite") //新建事务,readonly(默认)/readwrite/versionchange .objectStore("book") //拿到IDBObjectStore 对象 .add({ // 插入记录 id: book.id, name: book.name }); request.onsuccess = function(event) { console.log("数据写入成功"); } request.onerror = function(event) { console.log("数据写入失败"); } request.onabort = function(event) { console.log("事务回滚"); } } //读取数据================================== //读取一条 function read() { var transaction = db.transaction(["book"]); var objectStore = transaction.objectStore("book"); var request = objectStore.get(1); //传主键 request.onerror = function(event) { console.log("事务失败"); }; request.onsuccess = function( event) { if (request.result) { console.log(request.result) } else { console.log("未获得数据记录"); } }; } //读取所有数据,需要使用游标 function readAll() { var objectStore = db.transaction(["book"]).objectStore("book"); objectStore.openCursor().onsuccess = function(event) { //也可以在索引上打开 objectStore.index("id").openCursor() var cursor = event.target.result; if (cursor) { console.log(cursor) cursor.continue(); } else { console.log('没有更多数据了!'); } } } //打开游标时也可以传参确定数据范围和游标方向 objectStore.openCursor(1) //打开主键为1 objectStore.openCursor(IDBKeyRange.bound(1, 10, false, true))//1到10 objectStore.openCursor(null, "prev")//游标方向往前,还有next //可以直接通过游标更新或删除数据 cursor.update(updatedBook)//更新 cursor.delete()//删除 //更新数据================================== function update() { var request = db.transaction(['book'],'readwrite').objectStore('book').put({ id: 1, name: '书剑恩仇录2', }); request.onsuccess = function(event) { console.log('数据更新成功'); } request.onerror = function(event) { console.log('数据更新失败'); } } //删除数据================================== function remove() { var request = db.transaction(["book"], "readwrite") .objectStore('book') .delete(1); request.onsuccess = function (event) { console.log("数据删除成功"); }; } //清空数据 function clear() { var request = db.transaction(["book"], "readwrite") .objectStore("book") .clear(); request.onsuccess = function (event) { console.log('数据清除成功'); }; }
3、在Blazor中使用IndexedDB:使用IndexedDB的场景确实不多,像临时保存表单数据,使用LocalStorage就足够,键值也是支持JSON格式数据,而且C#调用JS,对象和JSON可能自动转换。数据量大的,也应该直接使用前后端分离的方案,所以下例简单说一下Blazor中使用IndexedDB的方法。特别注意案例中的异步说明!!!
//======================================= //步骤一:在wwwroot/js文件夹下,创建MyIndexedDB.js文件 //======================================= //步骤二:引入MyIndexedDB.js,案例使用Server模式在_Host.cshtml文件下 <script src="_framework/blazor.server.js"></script> <script src="~/js/MyIndexedDB.js"></script> //======================================= //步骤三:在MyIndexedDB.js中定义需要的方法 //下例仅演示创建数据表和增加数据 //注意IndexedDB的API均是异步执行,这是很大的一个坑 var MyIndexedDB = MyIndexedDB || {}; //创建数据表 MyIndexedDB.CreatObjectStore = function (dbName, version, objectStoreName) { //打开数据库 var request = window.indexedDB.open(dbName, version); request.onerror = function (event) { console.log("数据库打开报错"); } var db; request.onsuccess = function (event) { db = request.result; console.log("数据库打开成功"); } //创建数据表 request.onupgradeneeded = function (event) { db = event.target.result; console.log("数据库升级成功"); if (!db.objectStoreNames.contains(objectStoreName)) { objectStore = db.createObjectStore(objectStoreName, { autoIncrement: true }); } } } //添加数据 MyIndexedDB.AddBook = function (dbName, version, objectStoreName, object) { //打开数据库 var db; var request = window.indexedDB.open(dbName, version); request.onerror = function (event) { console.log("数据库打开报错"); } request.onsuccess = function (event) { db = request.result; console.log("数据库打开成功"); //这里使用IndexedDB的巨坑之一,IndexedDB的方法均是异步,所以要在打开数据库连接的回调里执行CRUD操作 var trans = db.transaction(objectStoreName, "readwrite"); var objectStore = trans.objectStore(objectStoreName); var resultAdd = objectStore.add(object); resultAdd.onsuccess = function (event) { console.log("数据写入成功"); } resultAdd.onerror = function (event) { console.log("数据写入失败"); } resultAdd.onabort = function (event) { console.log("事务回滚"); } } } //======================================= //步骤四:Blazor中调用 @page "/" @inject IJSRuntime JS <button @onclick="@(()=>CreatObjectStore("TestDB",1,"Books"))">创建数据表Books</button> <button @onclick="@(()=>AddBook("TestDB",1,"Books",new Book { Id = 1, Name = "无名" }))">添加一本书</button> @code{ //创建数据表 private async Task CreatObjectStore(string dbName, int version, string objectStoreName) { await JS.InvokeVoidAsync("MyIndexedDB.CreatObjectStore", dbName, version, objectStoreName); } //新增数据 private async Task AddBook(string dbName, int version, string objectStoreName,Book book) { await JS.InvokeVoidAsync("MyIndexedDB.AddBook", dbName, version, objectStoreName, book); } }
标签:IndexedDB,function,Vue,console,进阶,db,request,book,event From: https://www.cnblogs.com/functionMC/p/16892254.html