直接跳到内容

本地存储

介绍

本地存储模块用于保存 Token、账号密码等简单数据。它采用数据源接口和数据源实现的结构,底层调用 util 里的存储工具类。

设计思路

  • 本地存储只负责读写简单数据,不直接给业务层使用。
  • 上层通过 data 模块的 StoreRepository 访问存储数据。
  • 具体实现依赖 PreferencesUtil,统一走 Preferences 本地存储。

数据源接口示例

文件位置:core/datastore/src/main/ets/datasource/token/TokenStoreDataSource.ets

ts
/**
 * @file Token 本地存储数据源接口
 */
export interface TokenStoreDataSource {
  /**
   * 保存 Token
   * @param {string} token Token
   * @returns {Promise<void>} Promise<void>
   */
  setToken(token: string): Promise<void>;

  /**
   * 读取 Token
   * @returns {Promise<string>} Token,默认空字符串
   */
  getToken(): Promise<string>;

  /**
   * 清除 Token
   * @returns {Promise<void>} Promise<void>
   */
  clearToken(): Promise<void>;
}

数据源实现示例

文件位置:core/datastore/src/main/ets/datasource/token/TokenStoreDataSourceImpl.ets

ts
import common from "@ohos.app.ability.common";
import preferences from "@ohos.data.preferences";
import { ContextUtil, PreferencesUtil } from "util";
import { TokenStoreDataSource } from "./TokenStoreDataSource";

/**
 * @file Token 本地存储数据源实现,基于 Preferences 封装
 */
export class TokenStoreDataSourceImpl implements TokenStoreDataSource {
  /**
   * Preferences 工具实例
   */
  private prefs: PreferencesUtil;
  /**
   * Preferences 文件名,用于存储 Token
   */
  private static readonly PREFS_NAME: string = "token_store";
  /**
   * Token 键名
   */
  private static readonly KEY_TOKEN: string = "token";

  /**
   * 构造函数
   * @param {common.Context} [context] UIAbility 上下文
   */
  constructor(context?: common.Context) {
    const resolvedContext: common.Context = context ?? ContextUtil.getUIAbilityCtx();
    this.prefs = new PreferencesUtil(resolvedContext, TokenStoreDataSourceImpl.PREFS_NAME);
  }

  /**
   * 保存 Token
   * @param {string} token Token
   * @returns {Promise<void>} Promise<void>
   */
  async setToken(token: string): Promise<void> {
    await this.prefs.set(TokenStoreDataSourceImpl.KEY_TOKEN, token);
  }

  /**
   * 读取 Token(默认返回空字符串)
   * @returns {Promise<string>} Token
   */
  async getToken(): Promise<string> {
    const value: preferences.ValueType = await this.prefs.get(TokenStoreDataSourceImpl.KEY_TOKEN, "");
    return typeof value === "string" ? value : "";
  }

  /**
   * 清除 Token
   * @returns {Promise<void>} Promise<void>
   */
  async clearToken(): Promise<void> {
    await this.prefs.remove(TokenStoreDataSourceImpl.KEY_TOKEN);
  }
}

ViewModel 使用示例

文件位置:feature/demo/src/main/ets/viewmodel/LocalStorageViewModel.ets

下面截取常用写法,展示如何通过仓库读写本地存储。

ts
import { BaseViewModel } from "base";
import { AccountStoreRepository } from "data";

/**
 * @file 本地存储示例页 ViewModel
 */
@ObservedV2
export default class LocalStorageViewModel extends BaseViewModel {
  /**
   * 本地存储仓库
   */
  private repository: AccountStoreRepository = new AccountStoreRepository();

  /**
   * 保存账号
   * @returns {Promise<void>} Promise<void>
   */
  async saveAccount(): Promise<void> {
    const account: string = this.accountInput.trim();
    if (!account) {
      return;
    }
    await this.repository.saveAccount(account);
  }

  /**
   * 读取账号
   * @returns {Promise<void>} Promise<void>
   */
  async loadAccount(): Promise<void> {
    this.storedAccount = await this.repository.loadAccount();
  }
}

与数据层的关系

  • 本地存储模块不直接给业务层使用。
  • 业务通过 TokenStoreRepositoryAccountStoreRepository 等仓库访问数据。
  • Repository 统一对外提供业务语义方法,保持依赖收敛。

如何新增本地存储

  1. core/datastore/src/main/ets/datasource/ 下新增一个与业务一致的文件夹。
  2. 编写数据源接口与实现,内部使用 PreferencesUtil
  3. core/datastore/Index.ets 中补充导出。
  4. 在 data 层新增对应的 StoreRepository。
  5. core/data/Index.ets 中补充导出。