将一个 Flutter 项目转为用 ArkUI-X 框架实现(4)

Flutter → ArkUI-X 页面转换指南(4)

本部分主要介绍

  • 网络请求
  • 数据持久化/状态管理

六、网络请求

Flutter 中使用插件 dio: ^5.8.0, ArkUI-X 中使用插件 @ohos/axios": ^2.2.12

1. 添加网络权限

文件:/entry/src/main/module.json5

json 复制代码
{
  "module": {
    "name": "entry",
    ...
    // 以下是添加网络权限的具体代码
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]
 
  }
}

2. 封装网络请求

文件:/entry/src/main/ets/network/HttpManager.ets

ts 复制代码
import axios, { InternalAxiosRequestConfig, AxiosResponse, AxiosError, AxiosInstance } from '@ohos/axios';
import { promptAction } from '@kit.ArkUI';

/* ------------------  拦截器  ------------------ */

/**
 * 请求拦截器:
 */
// 请求成功
function requestSuccessHandler(config: InternalAxiosRequestConfig) {
  // 对请求数据做点什么
  const token = 'token....'
  if (token) {
    config.headers['Authorization'] = 'Bearer ' + token //设置token
  }
  return config
}

// 请求失败
function requestFailHandler(error: AxiosError) {
  // 对请求错误做些什么
  return Promise.reject(error)
}

/**
 * 响应拦截器:
 */
// 响应成功
function responseSuccessHandler(response: AxiosResponse) {
  // 响应码 200 的处理
  return response;
}

// 响应失败
function responseFailHandler(error: AxiosError) {
  // 响应码 非200 的处理
  return Promise.reject(error)
}


/* ------------------  请求管理类  ------------------ */

// 创建实例
const instance: AxiosInstance = axios.create({
  baseURL: 'http://localhost:8088/', // 请求地址
  timeout: 300000, // 响应超时时间
  headers: {
    'Content-Type': 'application/json;charset=utf-8',
    'Content-Language': 'en',
  },
});

// 添加拦截器
instance.interceptors.request.use(requestSuccessHandler, requestFailHandler);
instance.interceptors.response.use(responseSuccessHandler, responseFailHandler);

// 封装请求方法
class HttpManager {
  get<T>(url: string, params?: object): Promise<AxiosResponse<T>> {
    return instance.get<T, AxiosResponse<T>>(url, { params })
  }

  // 封装post方法
  post<T>(url: string, data?: object, config?: object): Promise<AxiosResponse<T>> {
    return instance.post<T, AxiosResponse<T>>(url, data, config)
  }

  // 封装put方法
  put<T>(url: string, data?: object, config?: object): Promise<AxiosResponse<T>> {
    return instance.put<T, AxiosResponse<T>>(url, data, config)
  }

  // 封装delete方法
  delete<T>(url: string, data?: object): Promise<AxiosResponse<T>> {
    return instance.delete<T, AxiosResponse<T>>(url, data)
  }
}

export const httpManager = new HttpManager();

七、数据持久化/状态管理

参考文章:使用 Preferences 实现数据持久化

1. 应用数据持久化 Preferences

Flutter 中使用插件 shared_preferences: ^2.5.2, ArkUI-X 中使用原生的 Preferences

  • 用户首选项(Preferences)为应用提供Key-Value键值型的轻量级数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。
  • Key 键为 string 类型,要求非空且长度不超过1024个字节。
  • 如果 Value 值为 string 类型,请使用UTF-8编码格式,可以为空。
  • 数据持久化需要在调用 preferences.put(key, value) 后调用 preferences.flush() 接口以实现数据持久化。若不调用 flush(),数据可能仅保存在内存中而不会写入持久化存储,导致应用退出后数据丢失。
封装数据持久化类 PreferencesManager
ts 复制代码
import { preferences } from '@kit.ArkData';

// 存储键名常量
export class StorageKeys {
  static readonly USER_NAME = "username";
  static readonly TOKEN = "token";
}

/**
 * 应用数据持久化类
 */
class PreferencesManager {

  // 首选项的实例
  private dataPreferences: preferences.Preferences | null = null;
  // 管理类的单例
  private static instance: PreferencesManager;

  // 初始化:必须在应用启动时 (EntryAbility 中) 调用一次
  init(entryAbilityContext: Context) {
    // 应用数据持久化
    let options: preferences.Options = { name: 'myStore' };
    this.dataPreferences = preferences.getPreferencesSync(entryAbilityContext, options);
    console.info('Preferences initialized');
  }

  // 获取单例
  static getInstance(): PreferencesManager {
    if (!PreferencesManager.instance) {
      PreferencesManager.instance = new PreferencesManager();
    }
    return PreferencesManager.instance;
  }

  // 统一存储 (Put)
  async put(key: string, value: string | number | boolean): Promise<void> {
    if (!this.dataPreferences) throw new Error('Preferences not initialized');
    await this.dataPreferences.putSync(key, value);
    await this.dataPreferences.flush(); // 确保写入磁盘
  }

  // 统一读取 (Get)
  async get<T>(key: string, defaultValue: string | number | boolean): Promise<T> {
    if (!this.dataPreferences) return defaultValue as T;
    return (await this.dataPreferences.getSync(key, defaultValue)) as T;
  }

  // 统一删除 (Delete)
  async delete(key: string): Promise<void> {
    if (!this.dataPreferences) return;
    await this.dataPreferences.deleteSync(key);
    await this.dataPreferences.flush();
  }

}

export default PreferencesManager.getInstance();

初始化 ets/entryability/EntryAbility.ets 文件中

ts 复制代码
import PreferencesManager from '../storage/PreferencesManager';


export default class EntryAbility extends UIAbility {

onWindowStageCreate(windowStage: window.WindowStage): void {
  onWindowStageCreate(windowStage: window.WindowStage): void {     
    // Main window is created, set main page for this ability
    ...
    // 应用数据持久化
    PreferencesManager.init(this.context);
    ...
  }
}

页面中使用 ets/pages/login/LoginPage.ets

ts 复制代码
import PreferencesManager, { StorageKeys } from '../../storage/PreferencesManager';

@ComponentV2
export struct LoginPage {
  ...
  _handleLogin() {
    PreferencesManager.put(StorageKeys.USER_ACCOUNT, this.account)
    this.appPathStack.pushPathByName("Index", null);
  }
  ...
}
相关推荐
ChinaDragon3 小时前
HarmonyOS:6.0 新增和增强特性
harmonyos
贾伟康5 小时前
【句匠|01】HarmonyOS ArkTS 英语纠错页实战:把原句、修改建议和解释层级展示清楚
harmonyos·arkts·textarea·学习应用·英语纠错
淡写成灰8 小时前
「Flutter 文件保存太难了?」一个插件打通 7 大平台,我把方案开源了 🎉
flutter·harmonyos
坚果的博客13 小时前
Flutter 三方库 phone_state 的 OpenHarmony 适配实战
flutter
大雷神13 小时前
HarmonyOS ArkGraphics 2D 自定义字体实操:注册字体并验证中文回退
pytorch·华为·harmonyos
Nayana14 小时前
《Web 到 HarmonyOS》-- 第一课:前端经验哪些能带走
vue.js·harmonyos
大雷神15 小时前
HarmonyOS ArkGraphics 2D 复杂文本排版实操:用 ParagraphBuilder 做资讯阅读卡片
华为·harmonyos
大雷神15 小时前
HarmonyOS ArkGraphics 2D NativeImage 实操:获取 NativeWindow 与 SurfaceId
华为·harmonyos
小玮看世界15 小时前
当“教用户配置系统“成为产品的遮羞布:从鸿蒙拦截栈与小红书联系机制看科技公司的“驯化式创新“
科技·华为·harmonyos
梦想不只是梦与想16 小时前
鸿蒙 应用类型:企业应用
华为·harmonyos·企业应用