indexdDB和命名空间

本文介绍了命名空间在Vue.js的Vuex中的应用,如何解决命名冲突,以及IndexedDB中的索引和数据库、仓库的概念,包括索引名称、属性名称和创建数据库的方法。
摘要由CSDN通过智能技术生成

1、命名空间

命名空间的作用就是将不同的模块按照命名空间分类、隔离,以便更好地组织和管理代码。实际上,命名空间就是将 Vuex store 中的模块对象再次封装,每个模块都有自己的命名空间,在模块内部定义的 state、mutation、action 和 getter 都会注册到模块内部,可以通过带命名空间的形式来访问。

通过引入命名空间,可以解决在多人协作开发时出现的 state 命名冲突等问题,避免了在同一个 Vuex store 中不同模块命名相同的问题,同时还能提高代码的可读性、可维护性和可扩展性。

实际上,命名空间本质上就是一种封装机制,它可以有效地将大的模块拆分为更小的子模块,并提供了更细粒度的权限控制,使得团队成员之间可以更加灵活地分配任务、协作开发。命名空间的引入,不仅可以用于 Vue.js 的 Vuex,也可以用于其他编程领域,例如 JavaScript 的命名空间、Java 的包等等。

总之,命名空间是一种非常有价值和实用的编程概念,它可以提高代码的可读性、可维护性和可扩展性,是多人协作开发中必不可少的工具之一。

调用命名空间时,它的名字与在定义模块时指定的名字一一对应。当在定义 Vuex 模块时,需要在模块对象中设置 namespaced 属性为 true,这样就会为这个模块开启命名空间。然后,在调用 Vuex actions、mutations、getters、state 等方法时,需要将模块的命名空间作为前缀来使用。

2、命名空间可以由用户自定义命名

命名空间的名字通常是由开发人员自己定义的,用来区分不同的模块。在 Vue.js 的 Vuex 中,需要在定义模块时,设置 namespaced 属性为 true,表示为该模块开启命名空间。然后,在调用该模块中的 actions、mutations、getters 和 state 时,需要使用模块名作为命名空间的前缀。

例如,在 Vuex store 中定义一个名为 user 的模块,并设置了命名空间:

const store = new Vuex.Store({
  modules: {
    user: {
      namespaced: true, // 开启命名空间
      state: {
        name: 'Tom'
      },
      mutations: {
        setName (state, payload) {
          state.name = payload
        },
        // 处理其他 mutation
      },
      actions: {
        updateName ({ commit }, payload) {
          commit('setName', payload)
        },
        // 处理其他 action
      },
    },
    // 定义其他模块
  },
})

在调用该模块中的 mutation 时,需要在 mutation 的名字前添加该模块的命名空间 user,例如:

store.commit('user/setName', 'Jerry')

 actions、mutations、getters 和 state 时,使用模块名作为命名空间的前缀。这样能有效地避免不同模块内部命名相同的冲突问题,提高代码的可维护性和可读性。

3、indexDB的索引

在IndexedDB中,索引名称和属性名称都是对数据存储和检索过程中很重要的概念。下面我将详细解释一下这两个概念的含义和用法:

  1. 索引名称

索引名称是指为对象存储空间中的一个属性(或多个属性)创建的索引名称。通过为属性创建索引,我们可以在查询、排序、过滤和更新数据时提高检索效率。对象存储空间中可以创建多个索引,每个索引都有唯一的名称。

例如,我们可以为一个存储用户信息的对象存储空间创建一个名为 "user-store" 的对象存储空间。然后为其创建一个名为 "username" 的索引,这将使得我们可以更快地根据用户名来查询数据记录:

let userIndex = userObjectStore.createIndex("username", "username", {unique: true});

属性名称是指对象存储空间中每个数据记录的各个属性名字。在通过IndexedDB存储和查询数据时,我们需要通过属性名称访问和操作数据记录。例如,如果我们在一个存储用户信息的对象存储空间中创建了一个名为 "username" 的属性,那么我们可以使用它来查询某个用户的信息:

let transaction = db.transaction("user-store", "readwrite");
let userObjectStore = transaction.objectStore("user-store");
let index = userObjectStore.index("username");

let request = index.get("John Doe");

request.onsuccess = function(event) {
  // 在这里处理查询结果
};

三个索引

在创建组合索引时,连接索引属性的名称不是固定写法。在示例中,我们使用的是 "usernameAndEmail" 作为组合索引的名称,其中的 "And" 是我们自己定义的名称,并不是必须的。

要创建连接三个属性的组合索引,可以给组合索引一个任意的名称,例如 "usernameEmailCity",然后在创建索引时指定所需的属性。比如:

let store = db.createObjectStore("user", {keyPath: "id"});
store.createIndex("usernameEmailCity", ["username", "email", "city"]);

这样创建的组合索引 "usernameEmailCity" 就连接了三个属性。在进行查询时,可以像之前使用 "usernameAndEmail" 索引一样使用 "usernameEmailCity" 索引,例如:

let transaction = db.transaction("user");
let userStore = transaction.objectStore("user");
let index = userStore.index("usernameEmailCity");
let request = index.get(["john", "john@example.com", "New York"]);

request.onsuccess = function(event) {
  let user = event.target.result;
  if (user) {
    console.log(user);
  } else {
    console.log("No match found");
  }
};

4、数据库的创建

/**
 * 打开数据库
 * @param {object} dbName 数据库的名字
 * @param {string} storeName 仓库名称
 * @param {string} version 数据库的版本
 * @param {string} priKey 主键
 * @param {Object} index 索引
 * @return {object} 该函数会返回一个数据库实例
 */
export const openDB = function openDB(dbName, version = 1, storeName, priKey, index=[]) {
  //  兼容浏览器
  let indexedDB =
    window.indexedDB ||
    window.mozIndexedDB ||
    window.webkitIndexedDB ||
    window.msIndexedDB;
  let db;
  // 打开数据库,若没有则会创建
  const request = indexedDB.open(dbName, version);
  // 数据库打开成功回调
  request.onsuccess = function (event) {
    db = event.target.result; // 数据库对象
    console.log("数据库打开成功111",db);
    resolve(db);
  };
  // 数据库打开失败的回调
  request.onerror = function (event) {
    console.log("数据库打开报错",event);
  };
  // 数据库有更新时候的回调
  if (storeName !== undefined) {
    request.onupgradeneeded = function (event) {
      // 数据库创建或升级的时候会触发
      console.log("创建成功!");
      db = event.target.result; // 数据库对象
      let objectStore;
      // 创建存储库
      objectStore = db.createObjectStore(storeName, {
        keyPath: priKey, // 这是主键
        autoIncrement: true // 实现自增
      });
      // 创建索引,在后面查询数据的时候可以根据索引查
      // 首先创建主键对应的索引
      objectStore.createIndex(priKey, priKey, {unique: true});
      for (let i = 0; i < index.length; i++) {
        // 然后创建主要索引
        objectStore.createIndex(index[i], index[i], {unique: false});
      }
    };
  }
});

在此回调函数中,将 event.target.result 赋值给变量 db,表示获得了打开的数据库实例对象。最后,将该实例对象作为异步回调中的参数传入 resolve 中,以便其他模块可异步获取该实例对象。

若打开数据库失败,则会调用 request.onerror 回调函数,会将错误信息打印输出到控制台。

若需要在打开或创建数据库时,指定需要创建的数据仓库名称(storeName),则需设置 request.onupgradeneeded 回调函数。该回调函数会在数据库创建或升级时触发。

在该函数中,首先判断是否需要创建数据仓库,若需要,则设置 request.onupgradeneeded 回调函数。在该回调函数中,获取打开或创建的数据库实例对象,接着根据需要,创建存储库(即数据仓库)db.createObjectStore,并设置主键和自增属性。最后,根据 index 中的定义创建索引对象。这些操作会在创建数据库或升级数据库版本时执行。

在最后,该函数通过 Promise 实例,将打开或创建的数据库实例对象返回给调用方。因此,使用该函数时,需要使用 then 方法或 async/await 等方式异步获取该实例对象,并使用该实例对象进行 IndexedDB 操作。

5、数据库名和仓库

数据仓库(Database)是指 IndexedDB 中的一个数据容器,用于存储和管理多个对象存储空间(ObjectStore),相当于关系型数据库中的数据库(Database),而对象存储空间则相当于其中的数据表(Table)。每个数据仓库都有一个唯一名称,并包含多个对象存储空间,每个对象存储空间又包含若干记录(Record)。

数据库名称和仓库名称是 IndexedDB 中的两个不同概念,其区别如下:

  • 数据库名称:是指整个 IndexedDB 数据库的名称,表示要创建或打开的数据库的名称,用于标识数据存储容器的唯一名称。
  • 仓库名称:是指数据库中的对象存储空间的名称,表示为数据存储容器中的若干对象存储空间命名,用于存储和管理数据,每个对象存储空间都有自己的名称和一组可选的索引。

因此,一个 IndexedDB 数据库中可以包含多个不同名称的对象存储空间,这些对象存储空间可以有相同或不同的结构,用于存储和管理不同类型的数据。在同一个 IndexedDB 数据库中,可以存在多个仓库,且仓库名称可以相同。

需要注意的是,虽然同一浏览器中的不同 IndexedDB 数据库的名称可以相同,但它们实际上是不同的数据库,存储的数据也是独立的。这是因为 IndexedDB 数据库的唯一标识符是由数据库名称、版本号和安全来源三个部分组成的。如果数据库名称和版本号一致,但安全来源不同,仍然会构成不同的数据库。因此,在实际使用中,建议不要使用相同的数据库名称,以避免混淆和错误。

  • 20
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值