arkTS:使用ArkUI实现用户信息的持久化管理与自动填充(PersistentStorage)

news2024/12/23 13:22:07

arkUI:使用ArkUI实现用户信息的持久化管理与自动填充(PersistentStorage)

  • 1 主要内容说明
  • 2 例子
    • 2.1 登录页
      • 2.1.1登陆页的相关说明
        • 2.1.1.1 持久化存储的初始化
        • 2.1.1.2 输入框
        • 2.1.1.3 记住密码选项
        • 2.1.1.4 登录按钮的逻辑
        • 2.1.1.5 注册跳转
      • 2.1.2 源码1 (登录页--文件:`Page_PersistentStorage_Case_Login.etsf`)
    • 2.2 注册页
      • 2.2.1 注册页的相关说明
        • 2.2.1.1 功能
        • 2.2.1.2 持久化存储
        • 2.2.1.3 关键交互
      • 2.2.2 源码2(注册页--文件:`Page_PersistentStorage_Case_Register`)
    • 2.3 登陆成功的页面
      • 2.3.1 登陆成功页面的相关说明
        • 2.3.1.1 功能
        • 2.3.1.2 持久化存储
        • 2.3.1.3 关键交互
      • 2.3.2 源码3(登陆成功的页面--文件:`Page_PersistentStorage_Case_Main`)
    • 2.4 源码1,2,3组成的项目的运行效果
      • 2.4.1 效果视频
      • 2.4.2 效果截图
        • 2.4.2.1 使用模拟器打开 登陆页,默认情况
        • 2.4.2.2 点击 注册账号
        • 2.4.2.3 进入账号注册页
        • 2.4.2.4 注册内容
        • 2.4.2.5 点击 返回 回到 登陆页
        • 2.4.2.6 账号和密码无误后登陆成功
        • 2.4.2.7 文件路径关系截图
  • 3.结语
  • 4.定位日期

1 主要内容说明

PersistentStorage 是 ArkUI 提供的一种持久化存储解决方案,用于在应用程序中保存数据,并支持跨会话的数据管理和状态保持。通过 PersistentStorage,开发者可以轻松实现数据的本地存储,以满足诸如用户设置、登录信息、会话状态等需要长期保存数据的场景。

持久化存储 通过 PersistentStorage API 实现,将用户的账号、密码以及其他设置数据(如是否记住密码)保存到本地存储中,以便在应用重新启动或用户退出后,能够自动加载和恢复之前的状态。这样,用户无需每次登录时重新输入账号密码,特别是在“记住密码”功能启用时,系统会自动填充账号和密码,提供更流畅的用户体验。

在注册页面中,持久化存储用于保存用户输入的账号和密码信息,将它们存储在一个数组中。登录页面则通过从持久化存储读取这些信息,验证用户输入的账号密码是否匹配,并根据验证结果进行相应的操作。当用户勾选了“记住密码”选项时,账号和密码会被持续保存,以便下次直接登录。此外,登录页面还会根据用户的选择决定是否修改已存储的密码信息。

2 例子

这个项目通过三部分代码展示了一个简单的用户管理流程:注册、登录以及登录成功后的展示。核心技术围绕 ArkUI 和 持久化存储(PersistentStorage)展开,实现了用户信息的持久化保存与加载。

  • 注册页面 --------- 实现了用户信息的输入、存储与显示,并将用户的账号和密码保存到本地持久化存储中,保证用户数据的长期保存。

  • 登录页面 --------- 则提供了账号密码输入和验证功能,并支持“记住密码”功能,通过持久化存储保存用户的登录状态。

  • 登录成功页面 --------- 通过展示简单的欢迎信息,确认用户的登录成功,体现了项目的流畅用户体验。

这个项目是一个基础的示例,适合用于学习 ArkUI 的持久化存储操作、组件化开发以及用户交互设计的基础应用。

2.1 登录页

2.1.1登陆页的相关说明

登录页面 (Page_PersistentStorage_Case_Login)

2.1.1.1 持久化存储的初始化

使用 PersistentStorage.persistProp 方法初始化持久化存储数据,包括默认的账号、密码、记住密码设置等。

2.1.1.2 输入框

账号和密码的输入框中,分别处理了默认填充已保存账号和密码的逻辑,只有在选中“记住密码”且允许修改时,才会显示保存的数据。

2.1.1.3 记住密码选项

用户可以选择是否记住密码。选中时,将状态保存到持久化存储,并且根据是否记住密码决定是否允许修改密码。

2.1.1.4 登录按钮的逻辑

点击登录按钮时,首先会从存储中获取已注册的用户信息,验证账号密码是否匹配。如果匹配,则跳转到主页面,并保存账号和密码;否则提示错误信息。

2.1.1.5 注册跳转

如果用户没有账号,可以点击“注册账号”跳转到注册页面进行注册。

2.1.2 源码1 (登录页–文件:Page_PersistentStorage_Case_Login.etsf

/**
 * 登录页面
 */
import { User_Message } from './Page_PersistentStorage_Case_Register'
import { promptAction } from '@kit.ArkUI'

// 初始化持久化存储数据
// 初始化用户信息数组,包含一个默认账号和密码
PersistentStorage.persistProp("userMessageArr", [{ userAccount: "测试账号", userPassword: "测试密码" } as User_Message]);

// 初始化保存的登录账号和密码,用于记住功能
PersistentStorage.persistProp("userAccountRemember", "临时保存账号"); // 默认保存的账号
PersistentStorage.persistProp("userPasswordRemember", "passwordRemember"); // 默认保存的密码

// 初始化是否记住密码的状态
PersistentStorage.persistProp("isRememberPassword", false); // 默认不记住密码

// 初始化是否允许修改记住密码状态的标志
PersistentStorage.persistProp("isChangeRemember", false); // 默认不可改变记住密码的状态

@Entry
@Component
struct Page_PersistentStorage_Case_Login {
  // 用户输入的账号
  @State userAccount: string = "";

  // 用户输入的密码
  @State userPassword: string = "";

  // 持久化存储:成功登录后保存的账号
  @StorageLink("userAccountRemember")
  userAccountRemember: string = "userAccount--测试账号";

  // 持久化存储:成功登录后保存的密码
  @StorageLink("userPasswordRemember")
  userPasswordRemember: string = "password";

  // 持久化存储:是否记住密码
  @StorageLink("isRememberPassword")
  isRememberPassword: boolean = false;

  // 持久化存储:是否允许修改记住密码状态
  @StorageLink("isChangeRemember")
  isChangeRemember: boolean = false;

  build() {
    Column({ space: 10 }) {
      // 显示登录页面的标题
      Text("登录")
        .fontSize(30)
        .fontWeight(800);

      // 账号输入框
      Row() {
        Text("账号:");
        // 仅当允许修改记住密码状态且选中记住密码时,使用存储的账号,否则使用用户输入的账号
        TextInput({ placeholder: "请输入账号", text: (this.isChangeRemember && this.isRememberPassword) ? this.userAccountRemember : this.userAccount })
          .layoutWeight(1)
          .onChange((value) => {
            this.userAccount = value; // 更新用户输入的账号
          });
      }

      // 密码输入框
      Row() {
        Text("密码:");
        // 仅当允许修改记住密码状态且选中记住密码时,使用存储的密码,否则使用用户输入的密码
        TextInput({ placeholder: "请输入密码", text: (this.isChangeRemember && this.isRememberPassword) ? this.userPasswordRemember : this.userPassword })
          .layoutWeight(1)
          .type(InputType.Password) // 设置密码类型
          .onChange((value) => {
            this.userPassword = value; // 更新用户输入的密码
            console.log("输入的密码:" + this.userPasswordRemember);
          });
      }

      // 功能选项行,包含注册和记住密码的选项
      Row() {
        Blank();

        // 点击跳转到注册页面
        Text("注册账号")
          .onClick(() => {
            this.getUIContext()
              .getRouter()
              .pushUrl({ url: "pages/Page_PersistentStorage/Case/Page_PersistentStorage_Case_Register" });
          });

        Blank();

        // 显示记住密码的选项
        Text("记住密码");
        Checkbox()
          .shape(CheckBoxShape.ROUNDED_SQUARE) // 设置为方形复选框
          .select(this.isRememberPassword) // 当前是否选中
          .onChange((value: boolean) => {
            this.isRememberPassword = value; // 更新是否记住密码的选中状态
            AppStorage.setOrCreate("isRememberPassword", this.isRememberPassword); // 更新到持久化存储
            console.log("密码是否选中:" + this.isRememberPassword);

            // 如果取消选择记住密码,禁止修改记住密码状态
            this.isChangeRemember = false;
            AppStorage.setOrCreate("isChangeRemember", this.isChangeRemember);

            console.log("可改变状态--复选框:" + this.isChangeRemember);
          });

        Blank();
      }
      .width("100%");

      // 登录按钮
      Button("登录")
        .width("50%")
        .onClick(() => {
          // 从持久化存储中获取用户信息数组
          let userMessageArr: User_Message[] = AppStorage.get("userMessageArr") as [];
          console.log("登录页数组信息:" + JSON.stringify(userMessageArr));

          // 初始化过滤后的用户信息数组
          let personageAccount: User_Message[] = [{ userAccount: "测试账号", userPassword: "测试密码" }];

          // 过滤用户信息数组,查找匹配的账号
          personageAccount = userMessageArr.filter((item, vale) => {
            if (item.userAccount == this.userAccount) {
              return item; // 返回匹配的账号信息
            } else {
              return;
            }
          });

          console.log("筛选过后的内容:" + JSON.stringify(personageAccount));

          // 根据过滤结果判断登录是否成功
          if (personageAccount.length > 0) {
            // 如果密码正确,登录成功
            if (personageAccount[0].userPassword == this.userPassword) {
              // 跳转到主页面
              this.getUIContext()
                .getRouter()
                .pushUrl({ url: "pages/Page_PersistentStorage/Case/Page_PersistentStorage_Case_Main" });

              // 登录成功后将账号和密码保存到持久化存储
              AppStorage.setOrCreate("userAccountRemember", this.userAccount);
              AppStorage.setOrCreate("userPasswordRemember", this.userPassword);
              console.log("保存的账号:" + this.userAccount);
              console.log("保存的密码:" + this.userPassword);

              // 允许修改记住密码状态
              this.isChangeRemember = true;
              AppStorage.setOrCreate("isChangeRemember", this.isChangeRemember);
              console.log("可改变状态--登录:" + this.isChangeRemember);

            } else {
              // 密码错误时,弹出提示
              promptAction.showToast({ message: "输入的密码错误!" });
            }
          } else {
            // 如果账号未注册,弹出提示
            promptAction.showToast({ message: "账号未注册,可点击注册注册账号!" });
          }
        });
    }
    .height('100%')
    .width('100%')
    .padding({ left: 10, right: 10 });
  }
}

2.2 注册页

2.2.1 注册页的相关说明

注册页面 (Page_PersistentStorage_Case_Register)

2.2.1.1 功能

用户通过该页面进行注册,输入账号和密码后,用户信息会被保存到持久化存储中(userMessageArr)。注册成功后,用户的信息(账号和密码)会在页面上显示,并提示注册成功。

2.2.1.2 持久化存储

使用 PersistentStorage.persistProp() 初始化并保存用户信息数组 userMessageArr,存储用户注册时填写的账号和密码。

2.2.1.3 关键交互

用户输入账号和密码,点击“注册”按钮后,信息被保存到存储中,并展示成功信息。

2.2.2 源码2(注册页–文件:Page_PersistentStorage_Case_Register

/**
 * 注册页面
 */
// 定义用户信息类 User_Message,包含账号和密码属性
export interface User_Message {
  userAccount: string; // 用户账号
  userPassword: string; // 用户密码
}

// 初始化持久化存储,创建一个空的用户信息数组
PersistentStorage.persistProp("userMessageArr", []);

@Entry
@Component
struct Page_PersistentStorage_Case_Register {
  @State isRegister: boolean = false; // 是否完成注册状态
  @State userAccount: string = ""; // 输入的账号
  @State userPassword: string = ""; // 输入的密码

  build() {
    Column() {
      // 页面顶部的标题
      Column({ space: 10 }) {
        Text("注册")
          .fontSize(30)
          .fontWeight(800);

        // 账号输入框
        Row() {
          Text("账号:");
          TextInput({ placeholder: "请输入账号", text: $$this.userAccount })
            .layoutWeight(1); // 设置输入框占据行的剩余空间
        }

        // 密码输入框
        Row() {
          Text("密码:");
          TextInput({ placeholder: "请输入密码", text: $$this.userPassword })
            .layoutWeight(1) // 设置输入框占据行的剩余空间
            .type(InputType.Password); // 设置输入框类型为密码
        }

        // 操作按钮
        Row() {
          // 注册按钮
          Button("注册")
            .width("40%")
            .onClick(() => {
              this.isRegister = true; // 标记注册成功

              // 从存储中获取当前用户信息数组
              let userMessageArr: User_Message[] = AppStorage.get("userMessageArr") as [];

              // 创建一个新用户对象,包含输入的账号和密码
              let newUserMessagePersonage = {
                userAccount: this.userAccount,
                userPassword: this.userPassword,
              } as User_Message;

              // 将新用户信息添加到用户信息数组中
              userMessageArr.push(newUserMessagePersonage);

              // 将更新后的用户信息数组保存到持久化存储
              AppStorage.setOrCreate("userMessageArr", userMessageArr);

              console.log(
                JSON.stringify("人员信息数组内容:" + JSON.stringify(userMessageArr))
              );
            });

          // 返回按钮
          Button("返回")
            .width("40%")
            .onClick(() => {
              // 返回到上一个页面
              this.getUIContext().getRouter().back();
              this.isRegister = false; // 重置注册状态
            });
        }
        .width("100%")
        .justifyContent(FlexAlign.SpaceEvenly); // 按钮水平均匀分布

        // 注册完成后显示注册信息
        if (this.isRegister) {
          Column({ space: 10 }) {
            Text("注册完成,信息如下:")
              .fontSize(20)
              .fontWeight(800);

            // 显示注册成功的账号和密码
            Text("账号:" + this.userAccount);
            Text("密码:" + this.userPassword);
          }
          .width("100%")
          .alignItems(HorizontalAlign.Start) // 左对齐
          .margin({ top: 50 }); // 设置顶部间距
        }
      }
      .height("100%")
      .width("100%");
    }
    .height("100%")
    .width("100%")
    .padding({ left: 10, right: 10 }); // 设置页面左右内边距
  }
}

2.3 登陆成功的页面

2.3.1 登陆成功页面的相关说明

登录成功页面 (Page_PersistentStorage_Case_Main)

2.3.1.1 功能

展示用户登录成功的欢迎信息,简单地提示“登陆成功,欢迎使用!”。

2.3.1.2 持久化存储

该页面主要是显示登录成功后的提示信息,不涉及持久化存储的操作。

2.3.1.3 关键交互

没有复杂的交互,主要通过状态显示登录成功的信息

2.3.2 源码3(登陆成功的页面–文件:Page_PersistentStorage_Case_Main

/**
 * 用于显示登陆成功的页面
 * 展示简单的欢迎信息,提示用户登陆成功。
 */

@Entry
@Component
struct Page_PersistentStorage_Case_Main {
  // 欢迎信息
  @State message: string = '登陆成功,欢迎使用!';

  build() {
    // 使用 RelativeContainer 布局,使欢迎信息居中显示
    RelativeContainer() {
      // 显示欢迎信息的文本
      Text(this.message)
        .id('Page_PersistentStorage_Case_MainHelloWorld') // 为组件指定唯一 ID,方便调试或样式绑定
        .fontSize(50) // 设置字体大小
        .fontWeight(FontWeight.Bold) // 设置字体加粗
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center }, // 垂直居中
          middle: { anchor: '__container__', align: HorizontalAlign.Center }, // 水平居中
        });
    }
    .height('100%') // 设置容器高度为全屏
    .width('100%'); // 设置容器宽度为全屏
  }
}

2.4 源码1,2,3组成的项目的运行效果

2.4.1 效果视频

使用ArkUI实现用户信息的持久化管理与自动填充

2.4.2 效果截图

2.4.2.1 使用模拟器打开 登陆页,默认情况
  • 默认情况
    在这里插入图片描述
2.4.2.2 点击 注册账号
  • 点击 注册账号
    在这里插入图片描述
2.4.2.3 进入账号注册页
  • 进入账号注册页
    在这里插入图片描述
2.4.2.4 注册内容
  • 注册内容,完毕后点击返回可回到登陆页
    在这里插入图片描述
2.4.2.5 点击 返回 回到 登陆页
  • 点击 返回 回到 登陆页
    在这里插入图片描述
2.4.2.6 账号和密码无误后登陆成功
  • 账号和密码无误后登陆成功
    在这里插入图片描述
2.4.2.7 文件路径关系截图

在这里插入图片描述

3.结语

本文只是根据persistentStorage的内容,举一个例子,以巩固所学。实际开发中,本文对账号和密码的保存方式并不适用,且账号密码容易泄露,不满足密码本身的保密需求。

persistentStorage仅为轻量级储存方式,主要用于保存程序操作过后的进度状态,对于大量的数据内容,还是推荐使用数据库进行储存。

持久化PersistentStorage的相关的内容,华为官方的指南地址:PersistentStorage:持久化存储UI状态

由于笔者的能力有限,创作的内容有所不足在所难免,也敬请读者包涵和指出,万分感谢!

4.定位日期

文字内容基本添加完成,待效果显示视频和截图;
2024-12-1;
1:44;

时间过得好快,没想到弄到凌晨了,调整了登录页的一些内容;
代码调试完成,待视频审核通过;
2024-12-1;
3:58;

2024-12-1;
10:18;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2252478.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于SpringBoot+Vue的美妆购物网站

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…

【SpringBoot+Vue】x-admin管理系统跟做

技术栈 前端技术说明Vue前端框架Vuex全局状态管理框架ElementUI前端UI框架Axios前端HTTP框架vue-element-admin项目脚手架 后端技术说明SpringBoot容器MVC框架MyBatisORM框架MyBatis-plusMyBatis增强工具Redis非关系型数据库 数据库准备 SET NAMES utf8mb4; SET FOREIGN_KE…

【Docker】Docker配置远程访问

配置Docker的远程访问,你需要按照以下步骤进行操作: 1. 在Docker宿主机上配置Docker守护进程监听TCP端口 Docker守护进程默认只监听UNIX套接字,要实现远程访问,需要修改配置以监听TCP端口。 ‌方法一:修改Docker服务…

LeetCode hot100(自用背诵、部分题目、非最优解)

点击题目可以跳转到LeetCode 哈希 两数之和 public int[] twoSum(int[] nums, int target) {int lengthnums.length;int[] ans new int[2];for (int i 0; i <length-1 ; i) {for (int j i1; j < length; j) {if(nums[i]nums[j]target){ans[0]i;ans[1]j;}}}return an…

Android -- 简易音乐播放器

Android – 简易音乐播放器 播放器功能&#xff1a;* 1. 播放模式&#xff1a;单曲、列表循环、列表随机&#xff1b;* 2. 后台播放&#xff08;单例模式&#xff09;&#xff1b;* 3. 多位置同步状态回调&#xff1b;处理模块&#xff1a;* 1. 提取文件信息&#xff1a;音频文…

基础Web安全|SQL注入

基础Web安全 URI Uniform Resource Identifier&#xff0c;统一资源标识符&#xff0c;用来唯一的标识一个资源。 URL Uniform Resource Locator&#xff0c;统一资源定位器&#xff0c;一种具体的URI&#xff0c;可以标识一个资源&#xff0c;并且指明了如何定位这个资源…

ESG研究报告白皮书与ESG治理报告合集(2020-2023年)

一.资料范围&#xff1a;&#xff08;1&#xff09;ESG白皮书及指南;&#xff08;2&#xff09;ESG研究报告,&#xff08;3&#xff09;ESG治理报告分析&#xff08;4&#xff09;上市公司ESG报告&#xff08;知名企业&#xff09; 二、资料用途&#xff1a;可以分析研究企业E…

WPF指示灯的实现方式

WPF指示灯的实现方式 样式 XAML <Button x:Name"Btn1" Width"25" Height"25" Grid.Row"0" Grid.Column"1" Margin"10 5 5 5 "><Button.Template><ControlTemplate TargetType"Button"…

初识QT第一天

思维导图 利用Qt尝试做出原神登陆界面 import sys from PyQt6.QtGui import QIcon, QPixmap, QMovie from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QLineEdit# 封装原神窗口类 class Genshin(QWidget):# 构造函数def __init__(self):# 初始化父类…

【Linux】线程池设计 + 策略模式

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 线程池 1-1 ⽇志与策略模式1-2 线程池设计1-3 线程安全的单例模式1-3-1 什么是单例模式1-3-2 单例模式的特点1-3-3 饿汉实现⽅式和懒汉实现⽅式1-3-4 饿汉…

vim插件管理器vim-plug替代vim-bundle

文章目录 vim-plug与vim-bundle对比vim-plug安装vim-plug管理安装插件相关文章 vim-plug与vim-bundle对比 vim-plug 和 vim-bundle 都是 Vim 的插件管理器&#xff0c;但它们有一些关键的区别。以下是两者的主要对比&#xff1a; 易用性和简洁性 vim-plug: 易用性: vim-plug …

107.【C语言】数据结构之二叉树求总节点和第K层节点的个数

目录 1.求二叉树总的节点的个数 1.容易想到的方法 代码 缺陷 思考:能否在TreeSize函数内定义静态变量解决size的问题呢? 其他写法 运行结果 2.最好的方法:分而治之 代码 运行结果 2.求二叉树第K层节点的个数 错误代码 运行结果 修正 运行结果 其他写法 1.求二…

【代码随想录day48】【C++复健】739. 每日温度;496.下一个更大元素 I;503.下一个更大元素II

739. 每日温度 一顿操作猛如虎&#xff0c;一看击败5%。一眼顶针&#xff0c;鉴定为在存栈的时候把值和下标一起存了&#xff0c;所以导致了问题。 class Solution { public:vector<int> dailyTemperatures(vector<int>& temperatures) {stack<vector<…

vscode + conda + qt联合开发

安装vscode 安装conda 清华大学开源软件镜像(Anaconda下载)_清华大学镜像-CSDN博客 conda create新建一个环境&#xff0c;激活这个环境&#xff0c;然后安装pyside6 pip install pyside6 -i https://pypi.tuna.tsinghua.edu.cn/simple 安装成功后输入 pip list查看是否安装…

第十一篇 绘图matplotlib.pyplot的使用

文章目录 摘要安装方法入门案例使用plt绘图使用ax绘图plt.figure参数plot参数案例一 绘制红色实心的点状图案例二 绘制红色的破折线图案例三 绘制两条线颜色总结设置标题、轴名称、图例使用plt实现绘图使用ax实现绘图legend()中loc设置刻度plt自定义刻度ax自定义刻度plt.title …

Unity-Particle System属性介绍(一)基本属性

什么是ParticleSystem 粒子系统是Unity中用于模拟大量粒子的行为的组件。每个粒子都有一个生命周期&#xff0c;包括出生、运动、颜色变化、大小变化和死亡等。粒子系统可以用来创建烟雾、火焰、水、雨、雪、尘埃、闪电和其他各种视觉效果。 开始 在项目文件下创建一个Vfx文件…

计算机的错误计算(一百七十二)

摘要 探讨 MATLAB 对于算式 的计算误差。 例1. 在 MATLAB 中计算 的值。 直接贴图吧&#xff1a; 这样&#xff0c;MATLAB 的输出中只有3位正确数字&#xff0c;有效数字的错误率为 (16-3)/16 81.25% . 因为16位的正确输出为 0.2971242332737277e-18&#xff08;ISReals…

Flink四大基石之CheckPoint(检查点) 的使用详解

目录 一、Checkpoint 剖析 State 与 Checkpoint 概念区分 设置 Checkpoint 实战 执行代码所需的服务与遇到的问题 二、重启策略解读 重启策略意义 代码示例与效果展示 三、SavePoint 与 Checkpoint 异同 操作步骤详解 四、总结 在大数据流式处理领域&#xff0c;Ap…

S4 UPA of AA :新资产会计概览

通用并行会计&#xff08;Universal Parallel Accounting&#xff09;可以支持每个独立的分类账与其他模块集成&#xff0c;UPA主要是为了支持平行评估、多货币类型、财务合并、多准则财务报告的复杂业务需求 在ML层面UPA允许根据不同的分类账规则对物料进行评估&#xff0c;并…

Vue3学习宝典

1.ref函数调用的方式生成响应式数据&#xff0c;可以传复杂和简单数据类型 <script setup> // reactive接收一个对象类型的数据 import { reactive } from vue;// ref用函数调用的方式生成响应式数据&#xff0c;可以传复杂和简单数据类型 import { ref } from vue // 简…