階之道(26):@LocalStorageLink/@LocalStorageProp 頁(yè)面級(jí)狀態(tài)綁定邊界——為啥雙向綁定 vs 單向只讀)
ArkTS 進(jìn)階之道26LocalStorageLink/LocalStorageProp 頁(yè)面級(jí)狀態(tài)綁定邊界——為啥雙向綁定 vs 單向只讀本文是「ArkTS 進(jìn)階之道」系列第 26 篇續(xù)「ArkUI 狀態(tài)聯(lián)動(dòng)」深水區(qū)。上篇講 StorageLink/StorageProp 應(yīng)用級(jí)狀態(tài)綁定邊界雙向綁定 vs 單向只讀。本文講頁(yè)面級(jí)狀態(tài)綁定邊界LocalStorageLink 雙向綁定 vs LocalStorageProp 單向只讀——根因在頁(yè)面級(jí)雙向綁定槽 vs 單向只讀槽。能力系列篇 26 講過(guò) LocalStorageLink/LocalStorageProp 怎么用本文講為哈 LocalStorageLink 雙向綁定合法 LocalStorageProp 單向只讀組件不能改——根因在頁(yè)面級(jí)雙向綁定槽 vs 單向只讀槽。一、開篇LocalStorageLink 不是單向只讀是雙向綁定 LocalStorage 鍵你寫 React 時(shí)頁(yè)面級(jí)狀態(tài)綁定是「useState 魔法」組件卸載 state 銷毀// React 頁(yè)面級(jí)狀態(tài)綁定useState組件卸載 state 銷毀 function Comp() { const [count, setCount] useState(0) // 頁(yè)面級(jí) state 雙向 return button onClick{() setCount(count 1)}count{count}/button } // React 頁(yè)面級(jí)狀態(tài)綁定useState 雙向組件卸載 state 銷毀不跨頁(yè)面共享你寫鴻蒙 ArkTS 時(shí)LocalStorageLink雙向綁定 LocalStorage 鍵——組件改互同步// ArkTS LocalStorageLink 雙向綁定 LocalStorage 鍵 interface LocalState { localCount: number } const localStorage new LocalStorage({ localCount: 0 } as LocalState) Component struct LinkComp { LocalStorageLink(localCount) localCount: number 0 // ? LocalStorageLink 雙向綁定改互同步 build() { Button(localCount${this.localCount}) .onClick(() { this.localCount }) // ? 組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步 } } // LocalStorageLink 雙向綁定 LocalStorage 鍵組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步雙向useState 魔法 vs 頁(yè)面級(jí)雙向綁定槽的區(qū)別React 把頁(yè)面級(jí)狀態(tài)綁定當(dāng) useState 魔法組件卸載 state 銷毀ArkTS 把 LocalStorageLink 當(dāng)「頁(yè)面級(jí)雙向綁定槽」組件改互同步。根因不是 useState 魔法是頁(yè)面級(jí)雙向綁定槽——LocalStorageLink 雙向綁定 LocalStorage 鍵組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步雙向。二、根因LocalStorageLink/LocalStorageProp 的頁(yè)面級(jí)雙向綁定槽 vs 單向只讀槽機(jī)制鴻蒙 ArkUI 的 LocalStorageLink/LocalStorageProp 是頁(yè)面級(jí)狀態(tài)綁定槽——LocalStorageLink 雙向綁定槽LocalStorageProp 單向只讀槽來(lái)自三重綁定機(jī)制。機(jī)制 1LocalStorageLink 雙向綁定 LocalStorage 鍵——組件改互同步LocalStorageLink 荬飾器雙向綁定 LocalStorage 鍵——組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步雙向interface LocalState { localCount: number } const localStorage new LocalStorage({ localCount: 0 } as LocalState) Component struct LinkComp { LocalStorageLink(localCount) localCount: number 0 // ? LocalStorageLink 雙向綁定改互同步 build() { Column() { Text(localCount ${this.localCount}) Button(改 localCount) .onClick(() { this.localCount }) // ? 組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步 } } } // LocalStorageLink 雙向綁定 LocalStorage 鍵組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步雙向LocalStorageLink 雙向綁定 LocalStorage 鍵LocalStorageLinklocalCount荬飾器雙向綁定 LocalStorage 鍵——組件改localCount→ LocalStorage 同步 → 同頁(yè)面其他組件同步雙向。根因不是單向只讀是頁(yè)面級(jí)雙向綁定槽——LocalStorageLink 雙向綁定 LocalStorage 鍵組件改互同步雙向。機(jī)制 2LocalStorageProp 單向只讀綁定——LocalStorage 改組件同步組件不能改LocalStorageProp 荬飾器單向只讀綁定——LocalStorage 改 → 組件同步組件改只改本地副本不回傳interface LocalState { localCount: number } const localStorage new LocalStorage({ localCount: 0 } as LocalState) Component struct PropComp { LocalStorageProp(localCount) localCount: number 0 // ? LocalStorageProp 單向只讀組件不能改 build() { Column() { Text(localCount ${this.localCount}只讀組件不能改) Button(試改 localCount) .onClick(() { // ? LocalStorageProp 只讀改只改組件本地副本不回傳 LocalStorage單向只讀 this.localCount // ? 只改本地副本LocalStorage 不同步其他組件不同步 }) } } } // LocalStorageProp 單向只讀綁定LocalStorage 改 → 組件同步組件改只改本地副本不回傳LocalStorageProp 單向只讀綁定LocalStorageProplocalCount荬飾器單向只讀綁定——LocalStorage 改localCount→ 組件同步組件改localCount只改本地副本不回傳 LocalStorage。根因不是雙向同步是頁(yè)面級(jí)單向只讀槽——LocalStorageProp 單向只讀綁定LocalStorage 改組件同步組件改不回傳。機(jī)制 3LocalStorageLink vs LocalStorageProp 邊界——雙向綁定 vs 單向只讀LocalStorageLink雙向綁定組件改互同步LocalStorageProp單向只讀LocalStorage 改組件同步組件改不回傳——根因都是綁定 LocalStorage 鍵但綁的機(jī)制不同interface LocalState { localCount: number } const localStorage new LocalStorage({ localCount: 0 } as LocalState) // ? LocalStorageLink 路徑雙向綁定組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步雙向 Component struct LinkComp { LocalStorageLink(localCount) localCount: number 0 // ? LocalStorageLink 雙向綁定 build() { Button(LinkComp ${this.localCount}) .onClick(() { this.localCount }) // ? 組件改 → LocalStorage 同步 → 其他組件同步 } } // ? LocalStorageProp 路徑單向只讀LocalStorage 改 → 組件同步組件改不回傳 Component struct PropComp { LocalStorageProp(localCount) localCount: number 0 // ? LocalStorageProp 單向只讀 build() { Button(PropComp ${this.localCount}) .onClick(() { this.localCount }) // ? 改只改本地副本LocalStorage 不同步 } } // LocalStorageLink vs LocalStorageProp 邊界雙向綁定改互同步vs 單向只讀組件改不回傳LocalStorageLink vs LocalStorageProp 邊界LocalStorageLink 路徑——雙向綁定組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步雙向推薦組件要改用。LocalStorageProp 路徑——單向只讀LocalStorage 改 → 組件同步組件改只改本地副本不回傳推薦組件只讀用。根因都是綁定 LocalStorage 鍵但綁的機(jī)制不同——LocalStorageLink 頁(yè)面級(jí)雙向綁定槽改互同步LocalStorageProp 頁(yè)面級(jí)單向只讀槽組件改不回傳。機(jī)制 4LocalStorageLink/LocalStorageProp vs StorageLink/StorageProp 邊界——頁(yè)面級(jí) vs 應(yīng)用級(jí)LocalStorageLink/LocalStorageProp頁(yè)面級(jí)綁定LocalStorage 頁(yè)面卸載就銷毀StorageLink/StorageProp應(yīng)用級(jí)綁定AppStorage 所有頁(yè)面共享——根因都是綁定狀態(tài)存儲(chǔ)但綁的作用域不同// ? LocalStorageLink/LocalStorageProp 路徑頁(yè)面級(jí)綁定LocalStorage 頁(yè)面卸載就銷毀 const localStorage new LocalStorage({ localCount: 0 } as LocalState) Component struct LocalLinkComp { LocalStorageLink(localCount) localCount: number 0 // ? 頁(yè)面級(jí)雙向綁定頁(yè)面卸載就銷毀 build() { Button(頁(yè)面級(jí) ${this.localCount}).onClick(() { this.localCount }) } } // ? 頁(yè)面級(jí)綁定同頁(yè)面多組件共享頁(yè)面卸載就銷毀單頁(yè)面用 LocalStorage // ? StorageLink/StorageProp 路徑應(yīng)用級(jí)綁定AppStorage 所有頁(yè)面共享 AppStorage.setOrCreate(appCount, 0) Entry Component struct AppLinkComp { StorageLink(appCount) appCount: number 0 // ? 應(yīng)用級(jí)雙向綁定所有頁(yè)面共享 build() { Button(應(yīng)用級(jí) ${this.appCount}).onClick(() { this.appCount }) } } // ? 應(yīng)用級(jí)綁定所有頁(yè)面共享頁(yè)面卸載狀態(tài)仍存在跨頁(yè)面用 AppStorageLocalStorageLink/LocalStorageProp vs StorageLink/StorageProp 邊界LocalStorageLink/LocalStorageProp 路徑——頁(yè)面級(jí)綁定LocalStorage 頁(yè)面卸載就銷毀單頁(yè)面用。StorageLink/StorageProp 路徑——應(yīng)用級(jí)綁定AppStorage 所有頁(yè)面共享跨頁(yè)面用。根因都是綁定狀態(tài)存儲(chǔ)但綁的作用域不同——LocalStorageLink/LocalStorageProp 頁(yè)面級(jí)綁定槽頁(yè)面卸載就銷毀StorageLink/StorageProp 應(yīng)用級(jí)綁定槽跨頁(yè)面共享。三、真機(jī)配圖LocalStorageLink/LocalStorageProp 頁(yè)面級(jí)狀態(tài)綁定邊界——雙向 vs 只讀初始態(tài)LinkComp localCount0 葝色雙向、PropComp localCount0 橙色只讀均綁定邊界初始態(tài)齊點(diǎn)調(diào)三按鈕后LinkComp localCount88 葝色被 LocalStorage.set 直接改 88 覆蓋、PropComp localCount88 橙色只讀同步、LocalStorageLink 雙向 vs LocalStorageProp 只讀邊界證據(jù)齊對(duì)比證據(jù)點(diǎn) LinkComp 改 localCount 后 LocalStorage 同步LocalStorageLink 雙向點(diǎn) PropComp 試改 localCount 后只改本地副本不回傳LocalStorageProp 只讀點(diǎn)直接改 LocalStorage.set(“l(fā)ocalCount”, 88) 后 LinkComp PropComp 都同步 88LocalStorage 是源。LocalStorageLink 雙向綁定 vs LocalStorageProp 單向只讀——LocalStorageLink 綁定 LocalStorage 鍵改互同步雙向LocalStorageProp 綁定 LocalStorage 鍵只讀組件改不回傳。四、真解法LocalStorageLink/LocalStorageProp 頁(yè)面級(jí)狀態(tài)綁定的三個(gè)場(chǎng)景場(chǎng)景 1LocalStorageLink 雙向綁定計(jì)數(shù)器90% 場(chǎng)景首選組件要改用雙向interface LocalState { localCount: number } const localStorage new LocalStorage({ localCount: 0 } as LocalState) Component struct LinkComp { LocalStorageLink(localCount) localCount: number 0 // ? LocalStorageLink 雙向綁定改互同步 build() { Column() { Text(localCount ${this.localCount}) Button(改 localCount) .onClick(() { this.localCount }) // ? 組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步 } } }為哈能跑LocalStorageLink 雙向綁定計(jì)數(shù)器——頁(yè)面級(jí)雙向綁定槽LocalStorageLinklocalCount雙向綁定 LocalStorage 鍵組件改localCount→ LocalStorage 同步 → 同頁(yè)面其他組件同步雙向。首選這個(gè)90% 的場(chǎng)景組件要改頁(yè)面級(jí)狀態(tài)用 LocalStorageLink 雙向綁定槽就夠。要寫「組件改頁(yè)面級(jí)狀態(tài)計(jì)數(shù)器等」時(shí)用這個(gè)——不用 LocalStorageProp 單向只讀組件改不回傳LocalStorageLink 雙向綁定改互同步。場(chǎng)景 2LocalStorageProp 單向只讀綁定展示組件只讀用單向LocalStorage 改組件同步interface LocalState { localCount: number } const localStorage new LocalStorage({ localCount: 0 } as LocalState) Component struct PropComp { LocalStorageProp(localCount) localCount: number 0 // ? LocalStorageProp 單向只讀組件不能改 build() { Text(localCount ${this.localCount}只讀展示組件不能改) // ? LocalStorage 改 → 組件同步只讀展示 } } // LocalStorageProp 單向只讀綁定展示LocalStorage 改 → 組件同步只讀展示組件不能改為哈能跑LocalStorageProp 單向只讀綁定展示——頁(yè)面級(jí)單向只讀槽LocalStorageProplocalCount單向只讀綁定 LocalStorage 鍵LocalStorage 改localCount→ 組件同步只讀展示組件不能改。要寫「組件只讀展示頁(yè)面級(jí)狀態(tài)只讀展示等」時(shí)用這個(gè)——不用 LocalStorageLink 雙向綁定組件改會(huì)回傳LocalStorageProp 單向只讀組件不能改。場(chǎng)景 3LocalStorageLink LocalStorageProp 混用改組件用雙向只讀組件用單向只讀interface LocalState { localCount: number } const localStorage new LocalStorage({ localCount: 0 } as LocalState) // ? 改組件用 LocalStorageLink 雙向綁定組件改 → LocalStorage 同步 Component struct EditComp { LocalStorageLink(localCount) localCount: number 0 // ? LocalStorageLink 雙向綁定改互同步 build() { TextInput({ text: ${this.localCount}, placeholder: 輸入值 }) .onChange((value: string) { this.localCount parseInt(value) || 0 }) // ? 改 → LocalStorage 同步 } } // ? 只讀組件用 LocalStorageProp 單向只讀LocalStorage 改 → 組件同步只讀展示 Component struct ShowComp { LocalStorageProp(localCount) localCount: number 0 // ? LocalStorageProp 單向只讀組件不能改 build() { Text(只讀展示 localCount ${this.localCount}) // ? LocalStorage 改 → 組件同步只讀展示 } } // LocalStorageLink LocalStorageProp 混用改組件用 LocalStorageLink 雙向只讀組件用 LocalStorageProp 單向只讀為哈能跑LocalStorageLink LocalStorageProp 混用——改組件用 LocalStorageLink 雙向綁定組件改 → LocalStorage 同步只讀組件用 LocalStorageProp 單向只讀LocalStorage 改 → 組件同步只讀展示。要寫「改組件 只讀組件混用編輯 展示等」時(shí)用這個(gè)——改組件用 LocalStorageLink 雙向只讀組件用 LocalStorageProp 單向只讀。五、一句話哲學(xué)LocalStorageLink 不是單向只讀是雙向綁定 LocalStorage 鍵的改互同步LocalStorageProp 是單向只讀的組件不能改。ArkUI 的 LocalStorageLink 荬飾器雙向綁定 LocalStorage 鍵組件改互同步雙向。根因不是單向只讀是頁(yè)面級(jí)雙向綁定槽——LocalStorageLink 雙向綁定 LocalStorage 鍵組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步雙向 LocalStorageProp 單向只讀綁定LocalStorage 改 → 組件同步組件改只改本地副本不回傳 LocalStorageLink vs LocalStorageProp 邊界雙向綁定 vs 單向只讀 LocalStorageLink/LocalStorageProp vs StorageLink/StorageProp 邊界頁(yè)面級(jí) vs 應(yīng)用級(jí)。對(duì)比 React 頁(yè)面級(jí)狀態(tài)綁定 useState 魔法組件卸載 state 銷毀ArkTS LocalStorageLink 頁(yè)面級(jí)雙向綁定槽改互同步。狀態(tài)聯(lián)動(dòng)深水區(qū)串講Watch 綁 State 變觸發(fā)副作用回調(diào)槽篇 68 Link $ 語(yǔ)法雙向綁定跨組件同步篇 69 Provide/Consume 跨層級(jí)傳遞槽祖輩后輩同步篇 70 Observed/ObjectLink 嵌套對(duì)象觀測(cè)槽子屬性改刷 UI篇 71 AppStorage 應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽所有頁(yè)面共享篇 72 LocalStorage 頁(yè)面級(jí)狀態(tài)存儲(chǔ)槽同頁(yè)面多組件共享篇 73 StorageLink/StorageProp 應(yīng)用級(jí)狀態(tài)綁定邊界雙向 vs 只讀篇 74 LocalStorageLink/LocalStorageProp 頁(yè)面級(jí)狀態(tài)綁定邊界雙向 vs 只讀篇 75LocalStorageLink 雙向綁定 vs LocalStorageProp 單向只讀——續(xù)「ArkUI 狀態(tài)聯(lián)動(dòng)」深水區(qū)講狀態(tài)聯(lián)動(dòng)深水區(qū)Watch 咼作用回調(diào)槽邊界 Link $ 語(yǔ)法雙向綁定邊界 Provide/Consume 跨層級(jí)傳遞槽邊界 Observed/ObjectLink 嵌套對(duì)象觀測(cè)槽邊界 AppStorage 應(yīng)用級(jí)狀態(tài)存儲(chǔ)槽邊界 LocalStorage 頁(yè)面級(jí)狀態(tài)存儲(chǔ)槽邊界 StorageLink/StorageProp 應(yīng)用級(jí)狀態(tài)綁定邊界 LocalStorageLink/LocalStorageProp 頁(yè)面級(jí)狀態(tài)綁定邊界。系列預(yù)告下篇篇 76講狀態(tài)管理裝飾器全景邊界V1/V2 雙軌根因續(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)篇 26 LocalStorageLink/LocalStorageProp 用法LocalStorageLink/LocalStorageProp 頁(yè)面級(jí)狀態(tài)綁定邊界根因雙向綁定 vs 單向只讀篇 24 LocalStorage 用法頁(yè)面級(jí)狀態(tài)存儲(chǔ)槽邊界同頁(yè)面多組件共享頁(yè)面卸載就銷毀篇 59 Watch 用法狀態(tài)聯(lián)動(dòng)深水區(qū)Watch 呇作用回調(diào)槽 vs onClick 直接調(diào)副作用邊界真機(jī) demo 完整代碼// 篇 75 demoLocalStorageLink/LocalStorageProp 頁(yè)面級(jí)狀態(tài)綁定邊界 // LocalStorageLink 雙向綁定 LocalStorage 鍵改互同步vs LocalStorageProp 單向只讀組件不能改 interface LocalState { localCount: number; localTheme: string } const localStorage new LocalStorage({ localCount: 0, localTheme: #52C41A } as LocalState) // ? LocalStorageLink 雙向綁定組件改互同步組件改 → LocalStorage 同步LocalStorage 改 → 組件同步 Component struct LinkComp { LocalStorageLink(localCount) localCount: number 0 // ? LocalStorageLink 雙向綁定 build() { Column({ space: 6 }) { Text(組件 LinkCompLocalStorageLink 雙向綁定) .fontSize(11).fontColor(#2563eb).fontWeight(FontWeight.Bold) Text(localCount ${this.localCount}).fontSize(13).fontColor(#2563eb) Button(LinkComp 改 localCountLocalStorageLink 雙向組件改 → LocalStorage 同步) .width(92%).height(36).fontSize(10) .onClick(() { this.localCount }) // ? 組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步 } .width(92%).padding(8).backgroundColor(#e0f0ff).borderRadius(6) } } // ? LocalStorageProp 單向只讀綁定組件LocalStorage 改 → 組件同步組件不能改只讀 Component struct PropComp { LocalStorageProp(localCount) localCount: number 0 // ? LocalStorageProp 單向只讀 build() { Column({ space: 6 }) { Text(組件 PropCompLocalStorageProp 單向只讀) .fontSize(11).fontColor(#ff6600).fontWeight(FontWeight.Bold) Text(localCount ${this.localCount}只讀組件不能改).fontSize(13).fontColor(#ff6600) Button(PropComp 試改 localCountLocalStorageProp 只讀改不回傳 LocalStorage) .width(92%).height(36).fontSize(10) .onClick(() { // ? LocalStorageProp 只讀改只改組件本地副本不回傳 LocalStorage單向只讀 this.localCount // ? 只改本地副本LocalStorage 不同步其他組件不同步 }) } .width(92%).padding(8).backgroundColor(#fff0e0).borderRadius(6) } } Entry Component struct Index { State log: string (未操作) build() { Column({ space: 12 }) { Text(篇 75 配圖LocalStorageLink/LocalStorageProp 頁(yè)面級(jí)狀態(tài)綁定邊界) .fontSize(16).fontWeight(FontWeight.Bold).margin({ top: 16, bottom: 4 }) Text(LocalStorageLink 雙向綁定改互同步vs LocalStorageProp 單向只讀組件不能改) .fontSize(10).fontColor(#888).margin({ bottom: 8 }) LinkComp() PropComp() // ? 直接改 LocalStorageLocalStorageLink 同步LocalStorageProp 也同步 Button(直接改 LocalStorage.set(localCount, 88)) .width(92%).height(40).fontSize(12) .onClick(() { localStorage.set(localCount, 88) // ? LocalStorage 改 → LocalStorageLink LocalStorageProp 同步 this.log LocalStorage.set localCount88LocalStorageLink LocalStorageProp 都同步 }) Text(日志${this.log}).fontSize(10).fontColor(#333).margin({ top: 4 }) } .width(100%).height(100%).alignItems(HorizontalAlign.Center) } }寫鴻蒙 ArkUI 記住LocalStorageLink 不是單向只讀是雙向綁定 LocalStorage 鍵的改互同步——LocalStorageLink 荬飾器雙向綁定 LocalStorage 鍵組件改互同步雙向。根因不是單向只讀是頁(yè)面級(jí)雙向綁定槽——LocalStorageLink 雙向綁定 LocalStorage 鍵組件改 → LocalStorage 同步 → 同頁(yè)面其他組件同步雙向 LocalStorageProp 單向只讀綁定LocalStorage 改 → 組件同步組件改只改本地副本不回傳 LocalStorageLink vs LocalStorageProp 邊界雙向綁定 vs 單向只讀 LocalStorageLink/LocalStorageProp vs StorageLink/StorageProp 邊界頁(yè)面級(jí) vs 應(yīng)用級(jí)。LocalStorageLink 雙向綁定計(jì)數(shù)器用頁(yè)面級(jí)雙向綁定槽首選90% 場(chǎng)景LocalStorageProp 單向只讀綁定展示用頁(yè)面級(jí)單向只讀槽組件不能改LocalStorageLink LocalStorageProp 混用改組件用 LocalStorageLink 雙向只讀組件用 LocalStorageProp 單向只讀。頁(yè)面級(jí)雙向綁定 vs 單向只讀是 ArkUI 狀態(tài)聯(lián)動(dòng)深水區(qū)核心