LocalStorage的使用

56 阅读4分钟

LocalStorage 是页面级的UI状态存储,通过 @Entry 装饰器接收的参数可以在页面内共享同一个 LocalStorage 实例。 LocalStorage 也可以在 UIAbility 内,页面间共享状态。

1.LocalStorage在页面中的使用

1.1. 一个页面不同组件使用

  • 创建 LocalStorage 实例:
    • const storage = new LocalStorage({ key: value })
    • 设置给@Entry的参数: @Entry(storage)
  • 单向 @LocalStorageProp('user') 类似于@Prop,不能进行修改数据
  • 双向 @LocalStorageLink('user') 类似于@Link,全局均可变
import { router } from '@kit.ArkUI'

export class UserInfo {
  name: string = ''
  age: number = 0
}

let userData: Record<string, UserInfo> = {
  'user': {
    name: 'jack',
    age: 18
  }
}

export const storage = new LocalStorage(userData)

@Entry(storage)
@Component
struct Index {
  @LocalStorageProp('user')
  user: UserInfo = {
    name: 'rose',
    age: 18
  }

  build() {
    Column({ space: 15 }) {
      Text('我是首页:')
        .fontSize(40)
      Text('name:' + this.user.name)
        .fontSize(40)
      Text('age:' + this.user.age)
        .fontSize(40)
      Button('去页面 2')
        .onClick(() => {
          router.pushUrl({ 
            url: 'pages/Index2' 
          })
        })

      Divider()
      ChildA()
      Divider()
      ChildB()
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

@Component
struct ChildA {
  @LocalStorageLink('user')
  user: UserInfo = {
    name: '',
    age: 0
  }

  build() {
    Column() {
      Text('我是子组件A')
        .fontSize(30)
      Text(this.user.name)
        .onClick(() => {
          this.user.name += '!'
        })
    }
    .backgroundColor(Color.Orange)
    .width('100%')

  }
}

@Component
struct ChildB {
  @LocalStorageLink('user')
  user: UserInfo = {
    name: '',
    age: 0
  }

  build() {
    Column() {
      Text('我是子组件B')
        .fontSize(30)
      Text(this.user.age.toString())
        .onClick(() => {
          this.user.age++
        })
    }
    .backgroundColor(Color.Blue)
    .width('100%')

  }
}

1.2.两个页面使用同一个LocalStorage

步骤:

  1. 页面 A 中导出 LocalStorage
  2. 其他需要使用的页面 导入 并使用 LocalStorage 即可

页面A:

import { router } from '@kit.ArkUI'

export class UserInfo {
  name: string = ''
  age: number = 0
}

let userData: Record<string, UserInfo> = {
  'user': {
    name: 'jack',
    age: 18
  }
}

export const storage = new LocalStorage(userData)

@Entry(storage)
@Component
struct Index {
  @LocalStorageProp('user')
  user: UserInfo = {
    name: 'rose',
    age: 18
  }

  build() {
    Column({ space: 15 }) {
      Text('我是首页:')
        .fontSize(40)
      Text('name:' + this.user.name)
        .fontSize(40)
      Text('age:' + this.user.age)
        .fontSize(40)
      Button('去页面 2')
        .onClick(() => {
          router.pushUrl({ url: 'pages/Index2' })
        })

      Divider()
      ChildA()
      Divider()
      ChildB()
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

@Component
struct ChildA {
  @LocalStorageLink('user')
  user: UserInfo = {
    name: '',
    age: 0
  }

  build() {
    Column() {
      Text('我是子组件A')
        .fontSize(30)
      Text(this.user.name)
        .onClick(() => {
          this.user.name += '!'
        })
    }
    .backgroundColor(Color.Orange)
    .width('100%')

  }
}

@Component
struct ChildB {
  @LocalStorageLink('user')
  user: UserInfo = {
    name: '',
    age: 0
  }

  build() {
    Column() {
      Text('我是子组件B')
        .fontSize(30)
      Text(this.user.age.toString())
        .onClick(() => {
          this.user.age++
        })
    }
    .backgroundColor(Color.Blue)
    .width('100%')

  }
}

页面B:

import { storage, UserInfo } from './Index';

@Entry(storage)
@Component
struct Index2 {
  @LocalStorageLink('user')
  user: UserInfo = {
    name: 'rose',
    age: 18
  }

  build() {
    Row() {
      Column() {
        Text('我是页面 2:')
          .fontSize(40)
        Text(JSON.stringify(this.user))
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            this.user.name = '罗伯特'
            this.user.age = 99
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

2.LocalStorage在逻辑中的使用

2.1.运用逻辑中使用

如果要在运用逻辑中使用,那么就可以使用以下方法:

//1.创建数据
const data: Record<string, number> = { 'age': 20 }


//2.创建storage,将创建好的data数据传给它
const storage = new LocalStorage(data)

@Entry
@Component
struct Index {
  build() {
    Column({space:10}) {
      Button('逻辑  Prop读取数据')
        .onClick(() => {
          //3.获取数据,准备读取,然后将它赋值给新的变量,这里需要注意一下这个创建新变量时的写法,要写明类型,不然报错
          const newData: SubscribedAbstractProperty<number> = storage.prop('age')
          //4.使用规定的方式来读取数据     prop只能读取,不能进行修改
          const age = newData.get()
          AlertDialog.show({ message: JSON.stringify(age,null,2) })
        })

      Button('逻辑   Link修改数据')
        .onClick(() => {
          //3.获取数据,准备读取,然后将它赋值给新的变量,这里需要注意一下这个创建新变量时的写法,要写明类型,不然报错
          const newData1: SubscribedAbstractProperty<number> = storage.link('age')

          //使用规定的方式进行修改数据,调用set方法       link是一个双向的  可以修改数据
          const age1 = newData1.set(100)
          AlertDialog.show({ message: JSON.stringify(age1,null,2) })

        })

    }.backgroundColor(Color.Pink)
    .width('100%')
    .height('100%')
  }
}

3.在UIAbility中共享某个localStorage

步骤:

  • 可以在loadContent过程中直接传入创建的LocalStorage
  • 页面中通过 const storage = LocalStorage.GetShared() 得到实例
  • 通过 @Entry(storage) 传入页面,后续的使用和之前没有区别

3.1.LocalStorage跨UIAbility共享_页面A

import { storage, UserInfo } from '../data/data'
import { BusinessError } from '@kit.BasicServicesKit'
import { common, Want } from '@kit.AbilityKit'


@Entry(storage)
@Component
struct Index {
  @LocalStorageLink("user")
  user: UserInfo = {
    name: "",
    age: 100
  }

  build() {
    Column() {
      Text(`年龄 ${this.user.age}`)
        .onClick(() => this.user.age++)
        .fontSize(40)

      Button("跨 UIAbility 传递数据")
        .onClick(() => {
          //   启动新的 UIAbility
          //   不是需要背诵, 一大段代码 官网cv, 按需去修改
          let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
          // context为调用方UIAbility的UIAbilityContext;
          let want: Want = {
            deviceId: '', // deviceId为空表示本设备

            //这个工程文件的bundleName
            bundleName: "com.example.uiability_12",
            abilityName: 'EEE',

          };
          context.startAbility(want).then(() => {
            //  then 跳转成功
            console.log("启动成功了 跳转成功了")
          }).catch((err: BusinessError) => {
            //   跳转失败 err 包含着我们错误信息
            console.log("出错", err.message, err.code)

          })
        })
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

注意:中途一定在程序入口里面添加你创建的LocalStorage的变量名称

image.png

3.2.LocalStorage跨UIAbility共享_页面B

// 引入 其他传递过来 UIAbility
import { UserInfo } from '../data/data';


//LocalStorage 跨UIAbility 共享    这是在跨跨UIAbility然后引用data数据的全新LocalStorage写法
const storage = LocalStorage.getShared()

@Entry(storage)
@Component
struct Storage {
  @LocalStorageLink("user")
  user: UserInfo = {
    name: '',
    age: 0
  }

  build() {
    RelativeContainer() {
      Text(this.user.age.toString())
        .id('StorageHelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
  }
}

说明:在页面B中,调用@LocalStorageLink("user")后续的步骤跟页面A一样使用,可以相互进行修改数据;同时需要使用LocalStorage.GetShared() 获取,然后通过@Entry(storage) 设置即可