階之道(23):AppStorage 應(yīng)用級(jí)狀態(tài)邊界——為啥所有頁面共享狀態(tài)頁面卸載狀態(tài)仍存在)
ArkTS 進(jìn)階之道23AppStorage 應(yīng)用級(jí)狀態(tài)邊界——為啥所有頁面共享狀態(tài)頁面卸載狀態(tài)仍存在本文是「ArkTS 進(jìn)階之道」系列第 23 篇續(xù)「ArkUI 狀態(tài)聯(lián)動(dòng)」深水區(qū)。上篇講 Observed/ObjectLink 嵌套對(duì)象觀測(cè)槽邊界State 只觀測(cè)一層嵌套對(duì)象子屬性改不刷 UI。本文講應(yīng)用級(jí)狀態(tài)邊界AppStorage 應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)——根因在所有頁面共享狀態(tài)頁面卸載狀態(tài)仍存在。能力系列篇 23 講過 AppStorage 怎么用本文講為哈 AppStorage 應(yīng)用級(jí)狀態(tài)合法 State 頁面級(jí)狀態(tài)頁面卸載就銷毀——根因在應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽。一、開篇AppStorage 不是頁面級(jí) State是應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)你寫 React 時(shí)應(yīng)用級(jí)狀態(tài)是「Context 魔法」createContext Provider 全局// React 應(yīng)用級(jí)狀態(tài)Context Provider const AppContext createContext({ count: 0 }) function App() { return AppContext.Provider value{{ count: 0 }}Page //AppContext.Provider } function Page() { const { count } useContext(AppContext) // 應(yīng)用級(jí) Context 全局 return Textcount{count}/Text } // React 應(yīng)用級(jí)狀態(tài)Context Provider全局魔法你寫鴻蒙 ArkTS 時(shí)AppStorage應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)——所有頁面共享// ArkTS AppStorage 應(yīng)用級(jí)全局狀態(tài)存儲(chǔ) AppStorage.setOrCreate(appCount, 0) // ? 初始化 AppStorage 鍵應(yīng)用級(jí)全局狀態(tài) Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ? StorageLink 雙向綁定 AppStorage 鍵 build() { Button(appCount${this.appCount}) .onClick(() { this.appCount }) // ? StorageLink 改 → AppStorage 同步 → 其他頁面同步 } } // AppStorage 應(yīng)用級(jí)全局狀態(tài)所有頁面共享頁面卸載狀態(tài)仍存在Context 魔法 vs 應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽的區(qū)別React 把應(yīng)用級(jí)狀態(tài)當(dāng) Context 魔法createContext Provider 全局ArkTS 把 AppStorage 當(dāng)「應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽」所有頁面共享頁面卸載狀態(tài)仍存在。根因不是 Context 魔法是應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽——AppStorage 應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)所有頁面共享頁面卸載狀態(tài)仍存在。二、根因AppStorage 的應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽機(jī)制鴻蒙 ArkUI 的 AppStorage 是應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽綁定——所有頁面共享頁面卸載狀態(tài)仍存在來自三重綁定機(jī)制。機(jī)制 1AppStorage 應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)——不是頁面級(jí) StateAppStorage 荬飾器應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)——所有頁面共享頁面卸載狀態(tài)仍存在// ? 初始化 AppStorage應(yīng)用級(jí)全局狀態(tài) AppStorage.setOrCreate(appCount, 0) AppStorage.setOrCreate(appTheme, #007DFF) Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ? StorageLink 雙向綁定 AppStorage 鍵 build() { Column() { Text(appCount ${this.appCount}) Button(改 appCount) .onClick(() { this.appCount }) // ? StorageLink 改 → AppStorage 同步 → 其他頁面同步 } } } // AppStorage 應(yīng)用級(jí)全局狀態(tài)所有頁面共享頁面卸載狀態(tài)仍存在不用重新初始化應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)AppStorageappCount應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)——所有頁面共享appCount頁面卸載狀態(tài)仍存在不用重新初始化。根因不是頁面級(jí) State 是應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽——AppStorage 應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)所有頁面共享頁面卸載狀態(tài)仍存在。機(jī)制 2StorageLink 雙向綁定 AppStorage 鍵——改 Storage 同步其他頁面StorageLink 荬飾器雙向綁定 AppStorage 鍵——改 StorageLink → AppStorage 同步 → 其他頁面同步Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ? StorageLink 雙向綁定 AppStorage 鍵 StorageLink(appTheme) appTheme: string #007DFF // ? StorageLink 雙向綁定 AppStorage 鍵 build() { Column() { Text(appCount ${this.appCount}).fontColor(this.appTheme) Button(改 appCount) .onClick(() { this.appCount }) // ? StorageLink 改 → AppStorage 同步 → 其他頁面同步 Button(改 appTheme紅色) .onClick(() { this.appTheme #FF4D4F }) // ? StorageLink 改 → AppStorage 同同步 } } } // StorageLink 雙向綁定 AppStorage 鍵改 → AppStorage 同步 → 其他頁面 StorageLink 同步雙向StorageLink 雙向綁定 AppStorage 鍵StorageLinkappCount荬飾器雙向綁定 AppStorage 鍵——改appCount→ AppStorage 同步 → 其他頁面StorageLink同步雙向。根因不是頁面級(jí)狀態(tài)是應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽——StorageLink 雙向綁定 AppStorage 鍵改 → AppStorage 同步 → 其他頁面同步雙向。機(jī)制 3AppStorage.set 直接改應(yīng)用級(jí)狀態(tài)——不用 StorageLink 也能改AppStorage.set直接改應(yīng)用級(jí)狀態(tài)——不用 StorageLink 也能改StorageLink 自動(dòng)同步Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ? StorageLink 雙向綁定 AppStorage 鍵 build() { Column() { Text(appCount ${this.appCount}) Button(直接改 AppStorage.set(appCount, 100)) .onClick(() { AppStorage.set(appCount, 100) // ? AppStorage.set 直接改應(yīng)用級(jí)狀態(tài) // ? StorageLink appCount 自動(dòng)同步StorageLink 綁定 AppStorage 鍵 }) } } } // AppStorage.set 直接改應(yīng)用級(jí)狀態(tài)不用 StorageLink 也能改StorageLink 自動(dòng)同步AppStorage.set 直接改應(yīng)用級(jí)狀態(tài)AppStorage.setappCount直接改應(yīng)用級(jí)狀態(tài)——不用 StorageLink 也能改StorageLinkappCount自動(dòng)同步StorageLink 綁定 AppStorage 鍵。根因不是必須用 StorageLink 是 AppStorage.set 直接改——AppStorage.set 直接改應(yīng)用級(jí)狀態(tài)StorageLink 自動(dòng)同步。機(jī)制 4AppStorage vs State 頁面級(jí)狀態(tài)邊界——應(yīng)用級(jí) vs 頁面級(jí)AppStorage應(yīng)用級(jí)全局狀態(tài)所有頁面共享頁面卸載狀態(tài)仍存在State頁面級(jí)狀態(tài)頁面卸載就銷毀——根因都是狀態(tài)存儲(chǔ)但綁的機(jī)制不同// ? AppStorage 路徑應(yīng)用級(jí)全局狀態(tài)所有頁面共享頁面卸載狀態(tài)仍存在 AppStorage.setOrCreate(appCount, 0) Entry Component struct Page1 { StorageLink(appCount) appCount: number 0 // ? StorageLink 雙向綁定 AppStorage 鍵 build() { Button(Page1 appCount${this.appCount}).onClick(() { this.appCount }) } } Entry Component struct Page2 { StorageLink(appCount) appCount: number 0 // ? Page2 也綁定同一個(gè) AppStorage 鍵 build() { Button(Page2 appCount${this.appCount}).onClick(() { this.appCount }) } } // ? AppStorage 應(yīng)用級(jí)全局狀態(tài)Page1 改 appCount → Page2 同步所有頁面共享 // ? State 路徑頁面級(jí)狀態(tài)頁面卸載就銷毀 Entry Component struct Page3 { State pageCount: number 0 // ? State 頁面級(jí)狀態(tài)頁面卸載就銷毀 build() { Button(Page3 pageCount${this.pageCount}).onClick(() { this.pageCount }) } } // ? State 頁面級(jí)狀態(tài)Page3 卸載 pageCount 銷毀不共享不持久AppStorage vs State 頁面級(jí)狀態(tài)邊界AppStorage 路徑——應(yīng)用級(jí)全局狀態(tài)所有頁面共享頁面卸載狀態(tài)仍存在推薦跨頁面狀態(tài)。State 路徑——頁面級(jí)狀態(tài)頁面卸載就銷毀單頁面狀態(tài)。根因都是狀態(tài)存儲(chǔ)但綁的機(jī)制不同——AppStorage 應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)槽所有頁面共享State 頁面級(jí)狀態(tài)頁面卸載就銷毀。三、真機(jī)配圖AppStorage 應(yīng)用級(jí)狀態(tài)邊界——所有頁面共享狀態(tài)初始態(tài)appCount0、appTheme“#007DFF” 蝔色文字均應(yīng)用級(jí)狀態(tài)初始態(tài)齊點(diǎn)調(diào)三按鈕后appCount100 被 AppStorage.set 直接改 100 覆蓋、appTheme“#FF4D4F” 紅色文字、AppStorage 應(yīng)用級(jí)狀態(tài)同步證據(jù)齊對(duì)比證據(jù)點(diǎn)改 appCount 按鈕后 appCount 同步StorageLink 雙向同步點(diǎn)改 appTheme紅色按鈕后 appTheme“#FF4D4F” 紅色文字同步點(diǎn)直接改 AppStorage.set(“appCount”, 100) 按鈕后 appCount100 被 AppStorage.set 直接改 100 覆蓋StorageLink 自動(dòng)同步。AppStorage 應(yīng)用級(jí)全局狀態(tài)——所有頁面共享頁面卸載狀態(tài)仍存在StorageLink 雙向綁定 AppStorage 鍵AppStorage.set 直接改應(yīng)用級(jí)狀態(tài) StorageID 自動(dòng)同步。四、真解法AppStorage 應(yīng)用級(jí)狀態(tài)的三個(gè)場(chǎng)景場(chǎng)景 1AppStorage 應(yīng)用級(jí)計(jì)數(shù)器90% 場(chǎng)景首選應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽AppStorage.setOrCreate(appCount, 0) Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ? StorageLink 雙向綁定 AppStorage 鍵 build() { Column() { Text(appCount ${this.appCount}) Button(改 appCount) .onClick(() { this.appCount }) // ? StorageLink 改 → AppStorage 同步 → 其他頁面同步 } } }為哈能跑AppStorage 應(yīng)用級(jí)計(jì)數(shù)器——應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽AppStorageappCount應(yīng)用級(jí)全局狀態(tài)StorageLink 雙向綁定 AppStorage 鍵改appCount→ AppStorage 同步 → 其他頁面同步雙向。首選這個(gè)90% 的場(chǎng)景應(yīng)用級(jí)跨頁面狀態(tài)用 AppStorage 應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽就夠。要寫「應(yīng)用級(jí)跨頁面狀態(tài)計(jì)數(shù)器等」時(shí)用這個(gè)——不用 State 頁面級(jí)狀態(tài)頁面卸載就銷毀AppStorage 應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽所有頁面共享。場(chǎng)景 2AppStorage 應(yīng)用級(jí)主題色應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽所有頁面共享主題AppStorage.setOrCreate(appTheme, #007DFF) Entry Component struct Index { StorageLink(appTheme) appTheme: string #007DFF // ? StorageLink 雙向綁定 AppStorage 鍵 build() { Column() { Text(appTheme ${this.appTheme}).fontColor(this.appTheme) Button(改 appTheme紅色) .onClick(() { this.appTheme #FF4D4F }) // ? StorageLink 改 → AppStorage 同步 → 其他頁面同步 } } } // AppStorage 應(yīng)用級(jí)主題色所有頁面共享 appTheme改 → AppStorage 同步 → 其他頁面同步為哈能跑AppStorage 應(yīng)用級(jí)主題色——應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽AppStorageappTheme應(yīng)用級(jí)全局狀態(tài)StorageLink 雙向綁定 AppStorage 鍵改appTheme→ AppStorage 同步 → 其他頁面同步雙向。要寫「應(yīng)用級(jí)跨頁面主題主題色等」時(shí)用這個(gè)——不用 State 頁面級(jí)狀態(tài)頁面卸載就銷毀AppStorage 應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽所有頁面共享主題。場(chǎng)景 3AppStorage.set 直接改應(yīng)用級(jí)狀態(tài)不用 StorageLink 也能改AppStorage.setOrCreate(appCount, 0) Entry Component struct Index { StorageLink(appCount) appCount: number 0 // ? StorageLink 雙向綁定 AppStorage 鍵 build() { Column() { Text(appCount ${this.appCount}) Button(直接改 AppStorage.set(appCount, 100)) .onClick(() { AppStorage.set(appCount, 100) // ? AppStorage.set 直接改應(yīng)用級(jí)狀態(tài) // ? StorageLink appCount 自動(dòng)同步StorageLink 綁定 AppStorage 鍵 }) } } } // AppStorage.set 直接改應(yīng)用級(jí)狀態(tài)不用 StorageLink 也能改StorageLink 自動(dòng)同步為哈能跑AppStorage.set 直接改應(yīng)用級(jí)狀態(tài)——應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽AppStorage.setappCount直接改應(yīng)用級(jí)狀態(tài)StorageLinkappCount自動(dòng)同步StorageLink 綁定 AppStorage 鍵。要寫「直接改應(yīng)用級(jí)狀態(tài)不用 StorageLink 也能改等」時(shí)用這個(gè)——不用 StorageLink 也能改AppStorage.set 直接改應(yīng)用級(jí)狀態(tài) StorageLink 自動(dòng)同步。五、一句話哲學(xué)AppStorage 不是頁面級(jí) State是應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)槽的所有頁面共享。ArkUI 的 AppStorage 荬飾器應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)所有頁面共享頁面卸載狀態(tài)仍存在。根因不是頁面級(jí) State 是應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽——AppStorage 應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)所有頁面共享頁面卸載狀態(tài)仍存在 StorageLink 雙向綁定 AppStorage 鍵改 → AppStorage 同步 → 其他頁面同步雙向 AppStorage.set 直接改應(yīng)用級(jí)狀態(tài)不用 StorageLink 也能改 StorageLink 自動(dòng)同步 AppStorage vs State 頁面級(jí)狀態(tài)邊界應(yīng)用級(jí) vs 頁面級(jí)。對(duì)比 React 應(yīng)用級(jí)狀態(tài) Context 魔法createContext Provider 全局ArkTS AppStorage 應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽所有頁面共享。狀態(tài)聯(lián)動(dòng)深水區(qū)串講Watch 綁 State 變觸發(fā)副作用回調(diào)槽篇 68 Link $ 語法雙向綁定跨組件同步篇 69 Provide/Consume 跨層級(jí)傳遞槽祖輩后輩同步篇 70 Observed/ObjectLink 嵌套對(duì)象觀測(cè)槽子屬性改刷 UI篇 71 AppStorage 應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽所有頁面共享篇 72State 頁面級(jí)狀態(tài)頁面卸載就銷毀——續(xù)「ArkUI 狀態(tài)聯(lián)動(dòng)」深水區(qū)講狀態(tài)聯(lián)動(dòng)深水區(qū)Watch 副作用回調(diào)槽邊界 Link $ 語法雙向綁定邊界 Provide/Consume 跨層級(jí)傳遞槽邊界 Observed/ObjectLink 嵌套對(duì)象觀測(cè)槽邊界 AppStorage 應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽邊界。系列預(yù)告下篇篇 73講 LocalStorage 頁面級(jí)狀態(tài)邊界頁面級(jí)局部狀態(tài)根因續(xù)「ArkUI 狀態(tài)聯(lián)動(dòng)」深水區(qū)。五階段哲學(xué)體系類型哲學(xué)50-52→ 作用域哲學(xué)53-55→ 狀態(tài)哲學(xué)56-59→ 瀆染哲學(xué)60-62→ 組件設(shè)計(jì)63-67→ 狀態(tài)聯(lián)動(dòng)深水區(qū)68講清 ArkTS/ArkUI 進(jìn)階哲學(xué)。能力系列回鏈能力系列篇本文進(jìn)階點(diǎn)篇 23 AppStorage 用法AppStorage 應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽邊界根因所有頁面共享頁面卸載狀態(tài)仍存在篇 13 State 基礎(chǔ)用法狀態(tài)哲學(xué)State 賦值就刷 UI 依賴追蹤篇 59 Watch 用法狀態(tài)聯(lián)動(dòng)深水區(qū)Watch 副作用回調(diào)槽 vs onClick 直接調(diào)副作用邊界真機(jī) demo 完整代碼// 篇 72 demoAppStorage 應(yīng)用級(jí)狀態(tài)邊界 // AppStorage 應(yīng)用級(jí)全局狀態(tài)所有頁面共享頁面卸載狀態(tài)仍存在 // StorageLink/StorageProp 綁定 AppStorage 鍵 // ? 初始化 AppStorage應(yīng)用級(jí)全局狀態(tài) AppStorage.setOrCreate(appCount, 0) AppStorage.setOrCreate(appTheme, #007DFF) Entry Component struct Index { // ? StorageLink 雙向綁定 AppStorage 鍵應(yīng)用級(jí)全局狀態(tài) StorageLink(appCount) appCount: number 0 StorageLink(appTheme) appTheme: string #007DFF State log: string (未操作) build() { Column({ space: 12 }) { Text(篇 72 配圖AppStorage 應(yīng)用級(jí)狀態(tài)邊界) .fontSize(16).fontWeight(FontWeight.Bold).margin({ top: 16, bottom: 4 }) Text(AppStorage 應(yīng)用級(jí)全局狀態(tài)所有頁面共享頁面卸載狀態(tài)仍存在) .fontSize(11).fontColor(#888).margin({ bottom: 8 }) // ? 應(yīng)用級(jí)狀態(tài)展示 Column({ space: 6 }) { Text(應(yīng)用級(jí)全局狀態(tài)AppStorage) .fontSize(12).fontColor(#2563eb).fontWeight(FontWeight.Bold) Text(appCount ${this.appCount}) .fontSize(15).fontWeight(FontWeight.Bold).fontColor(#2563eb) Text(appTheme ${this.appTheme}) .fontSize(13).fontColor(this.appTheme) } .width(92%).padding(10).backgroundColor(#e0f0ff).borderRadius(8) // ? 改 AppStorage 鍵StorageLink 雙向同步 Button(改 appCountStorageLink 雙向同步) .width(92%).height(40).fontSize(12) .onClick(() { this.appCount // ? StorageLink 改 → AppStorage 同步 → 其他頁面同步 this.log 改 appCount${this.appCount}AppStorage 應(yīng)用級(jí)狀態(tài) }) Button(改 appTheme紅色StorageLink 雙向同步) .width(92%).height(40).fontSize(12) .onClick(() { this.appTheme #FF4D4F // ? StorageLink 改 → AppStorage 同步 this.log 改 appTheme紅色AppStorage 應(yīng)用級(jí)狀態(tài) }) // ? 直接改 AppStorage不用 StorageLinkAppStorage.set 直接改 Button(直接改 AppStorage.set(appCount, 100)) .width(92%).height(40).fontSize(12) .onClick(() { AppStorage.set(appCount, 100) // ? AppStorage.set → StorageLink 同步 this.log 直接改 AppStorage.set appCount100StorageLink 同步 }) Text(日志${this.log}).fontSize(10).fontColor(#333).margin({ top: 4 }) } .width(100%).height(100%).alignItems(HorizontalAlign.Center) } }寫鴻蒙 ArkUI 記住AppStorage 不是頁面級(jí) State 是應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)槽的所有頁面共享——AppStorage 荬飾器應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)所有頁面共享頁面卸載狀態(tài)仍存在。根因不是頁面級(jí) State 是應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽——AppStorage 應(yīng)用級(jí)全局狀態(tài)存儲(chǔ)所有頁面共享頁面卸載狀態(tài)仍存在 StorageLink 雙向綁定 AppStorage 鍵改 → AppStorage 同步 → 其他頁面同步雙向 AppStorage.set 直接改應(yīng)用級(jí)狀態(tài)不用 StorageLink 也能改 StorageLink 自動(dòng)同步 AppStorage vs State 頁面級(jí)狀態(tài)邊界應(yīng)用級(jí) vs 頁面級(jí)。AppStorage 應(yīng)用級(jí)計(jì)數(shù)器用應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽首選90% 場(chǎng)景AppStorage 應(yīng)用級(jí)主題色用應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽所有頁面共享主題AppStorage.set 直接改應(yīng)用級(jí)狀態(tài)不用 StorageLink 也能改 StorageLink 自動(dòng)同步。應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽所有頁面共享頁面卸載狀態(tài)仍存在是 ArkUI 狀態(tài)聯(lián)動(dòng)深水區(qū)核心