当前位置: 首页 > news >正文

南京优化网站建设万网商标查询

南京优化网站建设,万网商标查询,腾讯云市场 wordpress,二手商品网站制作目录 1、概述 2、StorageProp 2.1、观察变化和行为表现 3、StorageLink 3.1、观察变化和行为表现 4、从应用逻辑使用AppStorage和LocalStorage 5、从UI内部使用AppStorage和LocalStorage 6、不建议借助StorageLink的双向同步机制实现事件通知 6.1、推荐的事件通知方式…

目录

1、概述

2、@StorageProp

2.1、观察变化和行为表现 

3.1、观察变化和行为表现

4、从应用逻辑使用AppStorage和LocalStorage

5、从UI内部使用AppStorage和LocalStorage

6、不建议借助@StorageLink的双向同步机制实现事件通知

6.1、推荐的事件通知方式


        AppStorage是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。和AppStorage不同的是,LocalStorage是页面级的,通常应用于页面内的数据共享。而AppStorage是应用级的全局状态共享,还相当于整个应用的“中枢”,持久化数据PersistentStorage和环境变量Environment都是通过和AppStorage中转,才可以和UI交互。

        本文介绍AppStorage使用场景和相关的装饰器:@StorageProp和@StorageLink。

1、概述

        AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorage将在应用运行过程保留其属性。属性通过唯一的键字符串值访问。

        AppStorage可以和UI组件同步,且可以在应用业务逻辑中被访问。

        AppStorage中的属性可以被双向同步,数据可以是存在于本地或远程设备上,并具有不同的功能,比如数据持久化(详见PersistentStorage)。这些数据是通过业务逻辑中实现,与UI解耦,如果希望这些数据在UI中使用,需要用到@StorageProp和@StorageLink。

2、@StorageProp

        在上文中已经提到,如果要建立AppStorage和自定义组件的联系,需要使用@StorageProp和@StorageLink装饰器。使用@StorageProp(key)/@StorageLink(key)装饰组件内的变量,key标识了AppStorage的属性。

        当自定义组件初始化的时候,@StorageProp(key)/@StorageLink(key)装饰的变量会通过给定的key,绑定在AppStorage对应的属性,完成初始化。本地初始化是必要的,因为无法保证AppStorage一定存在给定的key,这取决于应用逻辑,是否在组件初始化之前在AppStorage实例中存入对应的属性。

        @StorageProp(key)是和AppStorage中key对应的属性建立单向数据同步,我们允许本地改变的发生,但是对于@StorageProp,本地的修改永远不会同步回AppStorage中,相反,如果AppStorage给定key的属性发生改变,改变会被同步给@StorageProp,并覆盖掉本地的修改。

  • 从AppStorage的对应属性到组件的状态变量。

    组件本地的修改是允许的,但是AppStorage中给定的属性一旦发生变化,将覆盖本地的修改。

  • 被装饰的变量的初始值必须指定,如果AppStorage实例中不存在属性,则作为初始化默认值,并存入AppStorage中。

  • @StorageProp不支持从父节点初始化,只能AppStorage中key对应的属性初始化,如果没有对应key的话,将使用本地默认值初始化

2.1、观察变化和行为表现 

观察变化

  • 当装饰的数据类型为boolean、string、number类型时,可以观察到数值的变化。
  • 当装饰的数据类型为class或者Object时,可以观察到赋值和属性赋值的变化,即Object.keys(observedObject)返回的所有属性。
  • 当装饰的对象是array时,可以观察到数组添加、删除、更新数组单元的变化。

框架行为

  • 当@StorageProp(key)装饰的数值改变被观察到时,修改不会被同步回AppStorage对应属性键值key的属性中。
  • 当前@StorageProp(key)单向绑定的数据会被修改,即仅限于当前组件的私有成员变量改变,其他的绑定该key的数据不会同步改变。
  • 当@StorageProp(key)装饰的数据本身是状态变量,它的改变虽然不会同步回AppStorage中,但是会引起所属的自定义组件的重新渲染。
  • 当AppStorage中key对应的属性发生改变时,会同步给所有@StorageProp(key)装饰的数据,@StorageProp(key)本地的修改将被覆盖。

        @StorageLink(key)是和AppStorage中key对应的属性建立双向数据同步:

  1. 本地修改发生,该修改会被写回AppStorage中;
  2. AppStorage中的修改发生后,该修改会被同步到所有绑定AppStorage对应key的属性上,包括单向(@StorageProp和通过Prop创建的单向绑定变量)、双向(@StorageLink和通过Link创建的双向绑定变量)变量和其他实例(比如PersistentStorage)。
  • @StorageLink装饰的变量是双向同步的,从AppStorage的对应属性到自定义组件,从自定义组件到AppStorage对应属性。
  • @StorageLink被装饰变量的初始值必须指定,如果AppStorage实例中不存在属性,则作为初始化默认值,并存入AppStorage中。
3.1、观察变化和行为表现

观察变化

  • 当装饰的数据类型为boolean、string、number类型时,可以观察到数值的变化。
  • 当装饰的数据类型为class或者Object时,可以观察到赋值和属性赋值的变化,即Object.keys(observedObject)返回的所有属性。
  • 当装饰的对象是array时,可以观察到数组添加、删除、更新数组单元的变化。

框架行为

  1. 当@StorageLink(key)装饰的数值改变被观察到时,修改将被同步回AppStorage对应属性键值key的属性中。
  2. AppStorage中属性键值key对应的数据一旦改变,属性键值key绑定的所有的数据(包括双向@StorageLink和单向@StorageProp)都将同步修改;
  3. 当@StorageLink(key)装饰的数据本身是状态变量,它的改变不仅仅会同步回AppStorage中,还会引起所属的自定义组件的重新渲染。

4、从应用逻辑使用AppStorage和LocalStorage

        AppStorage是单例,它的所有API都是静态的,使用方法类似于LocalStorage对应的非静态方法。

AppStorage.SetOrCreate('PropA', 47);let storage: LocalStorage = new LocalStorage({ 'PropA': 17 });
let propA: number = AppStorage.Get('PropA') // propA in AppStorage == 47, propA in LocalStorage == 17
var link1: SubscribedAbstractProperty<number> = AppStorage.Link('PropA'); // link1.get() == 47
var link2: SubscribedAbstractProperty<number> = AppStorage.Link('PropA'); // link2.get() == 47
var prop: SubscribedAbstractProperty<number> = AppStorage.Prop('PropA'); // prop.get() == 47link1.set(48); // two-way sync: link1.get() == link2.get() == prop.get() == 48
prop.set(1); // one-way sync: prop.get() == 1; but link1.get() == link2.get() == 48
link1.set(49); // two-way sync: link1.get() == link2.get() == prop.get() == 49storage.get('PropA') // == 17 
storage.set('PropA', 101);
storage.get('PropA') // == 101AppStorage.Get('PropA') // == 49
link1.get() // == 49
link2.get() // == 49
prop.get() // == 49

5、从UI内部使用AppStorage和LocalStorage

        @StorageLink变量装饰器与AppStorage配合使用,正如@LocalStorageLink与LocalStorage配合使用一样。此装饰器使用AppStorage中的属性创建双向数据同步。

AppStorage.SetOrCreate('PropA', 47);
let appStorage = new LocalStorage({ 'PropA': 48 });/*** 从UI内部使用AppStorage和LocalStorage*/
@Entry(appStorage)
@Component
struct AppStorageDemo1Page {@StorageLink('PropA') storeLink: number = 1;@LocalStorageLink('PropA') localStoreLink: number = 1;build() {Column({ space: 20 }) {Text(`From AppStorage ${this.storeLink}`).onClick(() => this.storeLink += 1)Text(`From LocalStorage ${this.localStoreLink}`).onClick(() => {this.localStoreLink += 1;})}.margin({top: 48})}
}

        运行结果如下:

6、不建议借助@StorageLink的双向同步机制实现事件通知

        不建议开发者使用@StorageLink和AppStorage的双向同步的机制来实现事件通知,AppStorage是和UI相关的数据存储,改变会带来UI的刷新,相对于一般的事件通知,UI刷新的成本较大。

        TapImage中的点击事件,会触发AppStorage中tapIndex对应属性的改变。因为@StorageLink是双向同步,修改会同步回AppStorage中,所以,所有绑定AppStorage的tapIndex自定义组件都会被通知UI刷新。UI刷新带来的成本是巨大的,因此不建议开发者使用此方式来实现基本的事件通知功能。


class ViewData {title: string;uri: Resource;color: Color = Color.Black;constructor(title: string, uri: Resource) {this.title = title;this.uri = uri}
}/*** 事件通知的反例* 不建议借助@StorageLink的双向同步机制实现事件通知*/
@Entry
@Component
struct AppStorageDemo2Page {dataList: Array<ViewData> = [new ViewData('flower', $r('app.media.icon')),new ViewData('OMG', $r('app.media.icon')),new ViewData('OMG', $r('app.media.icon'))]scroller: Scroller = new Scroller()build() {Column() {Grid(this.scroller) {ForEach(this.dataList, (item: ViewData, index?: number) => {GridItem() {TapImage({uri: item.uri,index: index})}.aspectRatio(1)}, (item: ViewData, index?: number) => {return JSON.stringify(item) + index;})}.columnsTemplate('1fr 1fr')}}
}/*** TapImage中的点击事件,会触发AppStorage中tapIndex对应属性的改变。* 因为@StorageLink是双向同步,修改会同步回AppStorage中,所以,* 所有绑定AppStorage的tapIndex自定义组件都会被通知UI刷新。* UI刷新带来的成本是巨大的,因此不建议开发者使用此方式来实现基本的事件通知功能。*/
@Component
export struct TapImage {@StorageLink('tapIndex') @Watch('onTapIndexChange') tapIndex: number = -1;@State tapColor: Color = Color.Black;private index: number = 0;private uri: Resource = {id: 0,type: 0,moduleName: "",bundleName: ""};// 判断是否被选中onTapIndexChange() {if (this.tapIndex >= 0 && this.index === this.tapIndex) {console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, red`)this.tapColor = Color.Red;} else {console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, black`)this.tapColor = Color.Black;}}build() {Column() {Image(this.uri).objectFit(ImageFit.Cover).onClick(() => {this.tapIndex = this.index;}).border({ width: 5, style: BorderStyle.Dotted, color: this.tapColor })}}
}
6.1、推荐的事件通知方式

        可以使用emit订阅某个事件并接收事件回调,可以减少开销,增强代码的可读性。


import emitter from '@ohos.events.emitter';let Demo3NextID: number = 0;class Demo2ViewData {title: string;uri: Resource;color: Color = Color.Black;id: number;constructor(title: string, uri: Resource) {this.title = title;this.uri = urithis.id = Demo3NextID++;}
}/*** 基于事件的方式触发UI更新(推荐)*/
@Entry
@Component
struct AppStorageDemo3Page {dataList: Array<Demo2ViewData> = [new Demo2ViewData('flower', $r('app.media.icon')),new Demo2ViewData('OMG', $r('app.media.icon')),new Demo2ViewData('OMG', $r('app.media.icon'))]scroller: Scroller = new Scroller()private preIndex: number = -1build() {Column() {Grid(this.scroller) {ForEach(this.dataList, (item: Demo2ViewData) => {GridItem() {Demo2TapImage({uri: item.uri,index: item.id})}.aspectRatio(1).onClick(() => {if (this.preIndex === item.id) {return}let innerEvent: emitter.InnerEvent = { eventId: item.id }// 选中态:黑变红let eventData: emitter.EventData = {data: {"colorTag": 1}}emitter.emit(innerEvent, eventData)if (this.preIndex != -1) {console.info(`preIndex: ${this.preIndex}, index: ${item.id}, black`)let innerEvent: emitter.InnerEvent = { eventId: this.preIndex }// 取消选中态:红变黑let eventData: emitter.EventData = {data: {"colorTag": 0}}emitter.emit(innerEvent, eventData)}this.preIndex = item.id})}, (item: Demo2ViewData) => JSON.stringify(item))}.columnsTemplate('1fr 1fr')}}
}@Componentstruct Demo2TapImage {@State tapColor: Color = Color.Black;private index: number = 0;private uri: Resource = {id: 0,type: 0,moduleName: "",bundleName: ""};onTapIndexChange(colorTag: emitter.EventData) {if (colorTag.data != null) {this.tapColor = colorTag.data.colorTag ? Color.Red : Color.Black}}aboutToAppear() {//定义事件IDlet innerEvent: emitter.InnerEvent = { eventId: this.index }//注册事件emitter.on(innerEvent, data => {this.onTapIndexChange(data)})}build() {Column() {Image(this.uri).objectFit(ImageFit.Cover).border({ width: 5, style: BorderStyle.Dotted, color: this.tapColor })}}
}

        运行结果如下:

        当用户点击其中一个图标时会展示不同颜色的边框,同时取消上一个选择的图标的红色边框 ,该推荐demo使用基于事件的通知方式触发事件通知,减少UI刷新通知的方式所带来的性能开销。

http://www.hkea.cn/news/297592/

相关文章:

  • 新闻头条最新消息今日头条站长之家seo综合
  • app与网站宁波seo网络推广渠道介绍
  • 国外学做咖啡的网站百度高级搜索网址
  • 建网站开源代码游戏推广怎么找玩家
  • 莱州哪里有做网站的浙江网站建设平台
  • ps网站设计与制作免费推广seo
  • 网站查询功能怎么做关键词搜索量怎么查
  • 付费网站推广网站优化包括哪些内容
  • 在日本做色情网站广州seo外包
  • 最棒的网站建设考研最靠谱的培训机构
  • 广州建设企业网站黑河seo
  • 招商网站建设性价比高seo排名优化的
  • 产品网站怎么做的长沙正规关键词优化价格从优
  • 怎样查询江西省城乡建设厅网站杭州seo网
  • 网站建设空间是指什么软件网站优化最为重要的内容是
  • 做美工要开通什么网站的会员呢新网站友链
  • 网站集约化建设推进情况推广app赚钱
  • 番禺大石做网站域名污染查询网站
  • 长沙市在建工程项目免费seo快速排名工具
  • 南宁定制网站制作电话图片外链生成工具
  • 哪些网站做的海报比较高大上百度客服电话是多少
  • 菏泽网站建设电话常州seo外包
  • 做木皮的网站裂变营销五种模式十六种方法
  • 精美 企业网站模板微信软文推广怎么做
  • 怎么建立一个网站里面可以查询资料百度权重域名
  • 网站建设顺序镇江交叉口优化
  • 低价企业网站搭建软文新闻发布网站
  • 创造与魔法官方网站做自己喜欢的事seo视频
  • 淘宝联盟推广网站怎么做吉安seo招聘
  • 工程招聘网站如何免费制作自己的网站