第4章 数据与存储

4.1 本地存储方式

HarmonyOS 提供了多种数据存储方式,适合不同场景:

1. Preferences(轻量级键值对存储)

  • 类似于 Android 的 SharedPreferences
  • 适合存储 用户配置、登录状态 等小数据

📌 示例:

bash 复制代码
import dataPreferences from '@ohos.data.preferences';

async function saveData() {
  let preferences = await dataPreferences.getPreferences("user_prefs");
  await preferences.put("username", "eric");
  await preferences.flush();
}

async function readData() {
  let preferences = await dataPreferences.getPreferences("user_prefs");
  let username = await preferences.get("username", "未登录");
  console.log("用户名:", username);
}

2. 文件存储

  • 用于存储大文本、JSON、缓存文件。

📌 示例:

bash 复制代码
import fs from '@ohos.file.fs';

// 写文件
async function writeFile() {
  let file = await fs.open("/data/storage/el2/base/files/test.txt", fs.OpenMode.CREATE | fs.OpenMode.WRITE);
  await fs.write(file.fd, "Hello HarmonyOS!");
  fs.close(file.fd);
}

// 读文件
async function readFile() {
  let file = await fs.open("/data/storage/el2/base/files/test.txt", fs.OpenMode.READ);
  let buf = new ArrayBuffer(1024);
  let bytes = await fs.read(file.fd, buf);
  let text = String.fromCharCode.apply(null, new Uint8Array(buf, 0, bytes.bytesRead));
  console.log("读取内容:", text);
  fs.close(file.fd);
}

3. 数据库存储(SQLite)

  • 适合存储结构化数据(用户表、商品表)。

📌 示例:

bash 复制代码
import relationalStore from '@ohos.data.relationalStore';

let STORE_CONFIG = { name: "user.db", securityLevel: relationalStore.SecurityLevel.S1 };
let STORE;

// 打开数据库
relationalStore.getRdbStore(getContext(this), STORE_CONFIG, 1, (err, store) => {
  STORE = store;
  STORE.executeSql("CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)");
});

// 插入数据
function insertUser(name: string, age: number) {
  STORE.executeSql(`INSERT INTO user (name, age) VALUES (?, ?)`, [name, age]);
}

// 查询数据
function queryUsers() {
  STORE.querySql("SELECT * FROM user", [], (err, resultSet) => {
    while (resultSet.goToNextRow()) {
      console.log("用户:", resultSet.getString(1), "年龄:", resultSet.getLong(2));
    }
    resultSet.close();
  });
}

4.2 数据绑定与驱动 UI

鸿蒙 UI 采用响应式设计,结合 @State 可以让 UI 自动更新。

📌 示例:

bash 复制代码
@Entry
@Component
struct UserInfo {
  @State username: string = "未登录"

  async aboutToAppear() {
    let preferences = await dataPreferences.getPreferences("user_prefs");
    this.username = await preferences.get("username", "未登录");
  }

  build() {
    Column({ space: 20 }) {
      Text(`当前用户:${this.username}`)
    }
  }
}

4.3 网络请求

鸿蒙提供 HttpRequest 模块,用于接口调用。

📌 示例:

bash 复制代码
import http from '@ohos.net.http';

function fetchWeather() {
  let httpRequest = http.createHttp();

  httpRequest.request(
    "https://api.open-meteo.com/v1/forecast?latitude=35&longitude=139&current_weather=true",
    { method: http.RequestMethod.GET },
    (err, data) => {
      if (!err && data.responseCode === 200) {
        let result = JSON.parse(data.result);
        console.log("当前气温:", result.current_weather.temperature);
      } else {
        console.error("请求失败", err);
      }
    }
  );
}

4.4 JSON解析

鸿蒙使用标准 JS/TS 的 JSON.parse()JSON.stringify()

📌 示例:

bash 复制代码
let jsonStr = '{"name":"Eric","age":35}';
let obj = JSON.parse(jsonStr);
console.log(obj.name); // Eric

let newStr = JSON.stringify({ title: "HarmonyOS", version: 4 });
console.log(newStr);   // {"title":"HarmonyOS","version":4}

4.5 实操:创建一个天气查询应用

功能需求

  • 用户输入城市名
  • 点击"查询天气"
  • 通过网络请求获取天气 API
  • 显示结果

代码:index.ets

bash 复制代码
import http from '@ohos.net.http';

@Entry
@Component
struct WeatherApp {
  @State city: string = ""
  @State weather: string = "暂无数据"

  queryWeather() {
    let httpRequest = http.createHttp();
    httpRequest.request(
      `https://api.open-meteo.com/v1/forecast?latitude=39.9&longitude=116.4&current_weather=true`,
      { method: http.RequestMethod.GET },
      (err, data) => {
        if (!err && data.responseCode === 200) {
          let result = JSON.parse(data.result);
          this.weather = `温度:${result.current_weather.temperature}°C`
        } else {
          this.weather = "查询失败"
        }
      }
    );
  }

  build() {
    Column({ space: 20, alignItems: HorizontalAlign.Center }) {
      TextInput({ placeholder: "请输入城市名(示例:北京)" })
        .width(250)
        .onChange((value: string) => {
          this.city = value
        })

      Button("查询天气")
        .onClick(() => {
          this.queryWeather()
        })
        .backgroundColor("#007DFF")
        .fontColor(Color.White)
        .width(200)
        .height(40)

      Text(this.weather)
        .fontSize(20)
        .margin(20)
    }
    .width("100%")
    .height("100%")
    .backgroundColor("#F5F5F5")
  }
}

运行效果

  • 输入城市名 → 点击按钮 → 显示实时温度
  • 默认接口返回北京坐标的天气,可替换 API 支持更多城市

✅ 到这里,你已经掌握了:

  • 轻量级存储(Preferences)
  • 文件存储 & SQLite 数据库
  • 状态绑定与数据驱动 UI
  • 网络请求与 JSON 解析
  • 实战:天气查询应用
相关推荐
菠萝+冰1 小时前
在 React 中,父子组件之间的通信(传参和传方法)
前端·javascript·react.js
庚云1 小时前
一套代码如何同时适配移动端和pc端
前端
Jinuss1 小时前
Vue3源码reactivity响应式篇Reflect和Proxy详解
前端·vue3
海天胜景1 小时前
vue3 el-select 默认选中第一个
前端·javascript·vue.js
小小怪下士_---_1 小时前
uniapp开发微信小程序自定义导航栏
前端·vue.js·微信小程序·小程序·uni-app
前端W1 小时前
腾讯地图组件使用说明文档
前端
页面魔术1 小时前
无虚拟dom怎么又流行起来了?
前端·javascript·vue.js
胡gh1 小时前
如何聊懒加载,只说个懒可不行
前端·react.js·面试
Double__King2 小时前
巧用 CSS 伪元素,让背景图自适应保持比例
前端