current position:Home>Blazor and Vue contrast study (advanced 2.2.5) : the persistence of state management (3), LocalStorage and with IndexedDB

Blazor and Vue contrast study (advanced 2.2.5) : the persistence of state management (3), LocalStorage and with IndexedDB

2022-11-24 18:32:10functionMC

PS1:点击查看Blazor中C#和JS互操作

PS2:Vue中,可以直接使用LocalStorage和IndexedDB对象,The cases in this chapter are mainly based onBlazor的使用为主

 

一、Storage对象

1、The browser's built-in key-value store.locallStorageIn theory, it is permanently saved in the browser(除非主动清除),而SessionStorage只在当前会话中有效,Tab or browser closed,自动清除.遵守同源限制(按协议、Domain name and port isolation),of the same siteStorage,大小限制为5M,Key-value supportJSON格式.常用API如下所示(SessionStorage和LocalStorage用法一样): 

//①存储和更新数据
//存储名字为name值为lily的变量
localStorage.setItem("name","lily");
//可以用点(.)操作符,及[]的方式进行数据存储
localStorage.name = "lily";  


//②读取数据
//Read the specified key data
localStorage.getItem("name");
var name = localStorage.name;
//Read the first piece of data
localStorage.key(0);
//遍历localStorage
for(var i=0; i<localStorage.length;i++){
    ......
}

 
//③删除数据
localStorage.removeItem("name");
localStorage.name = "";  


//④Clear all data
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对象

IndexedDBIt is a non-relational database built into the browser,以键值对的方式保存数据,Theoretically the size from250M起,是WebApply the preferred local database,相当于手机APP端的SQLite.支持异步、事务、索引,Field values ​​support binary storage,如ArrayBuffer和Blob对象,和Storage一样,遵守同源限制.IndexedDB的使用,比Storage复杂,We choose the main points to study.

1、IndexedDB的常用内置对象,包括:

  • 数据库:IDBDatabase
  • 对象仓库:IDBObjectStore,相当于数据表
  • 索引: IDBIndex
  • 事务: IDBTransaction
  • 操作请求:IDBRequest
  • 指针: IDBCursor
  • 主键集合:IDBKeyRange

 

2、常用方法

(1)新建、Open or upgrade a database 

//If not, create a new databaseTestDB,且版本号为1
//如果已有数据库TestDB,And the version number is the same,则打开数据库
//如果已有数据库TestDB,But the version numbers are inconsistent,Then upgrade the database and open it
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)创建表、自增键、索引,Shut down or drop the database

//Create table inrequest.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});
    }
}

//After the data table is generally created,可以创建索引
//Note that indexes are for key valuesValueto build,每条记录的Value都是JSON
objectStore.createIndex("name", "name", { unique: true });

 

(3)Shut down or drop the database

db.close();
window.indexedDB.deleteDatabase("book");

 

(4)CRUD操作

//新增操作==================================
//注意:Key值(主键)自增,inserted into the recordid,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); //Pass the primary key
   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) { 
    //Can also be opened on the index objectStore.index("id").openCursor()
        var cursor = event.target.result;
        if (cursor) {
            console.log(cursor)
            cursor.continue();
        } else {
            console.log('没有更多数据了!');
        }
    }
}
//When opening the cursor, parameters can also be passed to determine the data range and cursor direction
objectStore.openCursor(1) //Open the primary key as 1
objectStore.openCursor(IDBKeyRange.bound(1, 10, false, true))//1到10
objectStore.openCursor(null, "prev")//Cursor direction forward,还有next
//Data can be updated or deleted directly through the cursor
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('Data clearing succeeded');
  };
}

 

 

3、在Blazor中使用IndexedDB:使用IndexedDBThere are really not many scenes,Like temporarily saving form data,使用LocalStorage就足够,Key-value is also supportedJSON格式数据,而且C#调用JS,对象和JSONMay be converted automatically.数据量大的,You should also directly use the scheme of separating the front and back ends,So the following example is simpleBlazor中使用IndexedDB的方法.Pay special attention to the asynchronous instructions in the examples!!! 

//=======================================
//步骤一:在wwwroot/js文件夹下,创建MyIndexedDB.js文件



//=======================================
//步骤二:引入MyIndexedDB.js,案例使用Server模式在_Host.cshtml文件下
<script src="_framework/blazor.server.js"></script>
<script src="~/js/MyIndexedDB.js"></script>



//=======================================
//步骤三:在MyIndexedDB.jsDefine the required methods in 
//The following example only demonstrates creating a data table and adding data
//注意IndexedDB的API均是异步执行,This is a big pit

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("数据库打开成功");
        //这里使用IndexedDBOne of the giant pits,IndexedDBThe methods are all asynchronous,So it should be executed in the callback that opens the database connectionCRUD操作
        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);
    }
}

 

copyright notice
author[functionMC],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/328/202211241829204700.html

Random recommended