多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

ArkTS 进阶之道(29):Environment 环境变量状态边界——为啥设备环境查询只读不可写单向链根因

ArkTS 进阶之道(29):Environment 环境变量状态边界——为啥设备环境查询只读不可写单向链根因 本文是「ArkTS 进阶之道」系列第 29 篇续「ArkUI 状态联动」深水区。上篇讲持久化状态边界PersistentStorage 持久化 AppStorage 键到磁盘跨启动状态。本文讲环境变量状态边界Environment 设备环境查询只读不可写——根因在 Environment → AppStorage → Component 单向链。能力系列篇 29 讲过 Environment 怎么用本文讲为哈 Environment 设备环境查询只读不可写应用不可写入——根因在设备环境查询单向链。一、开篇Environment 不是应用级 AppStorage是设备环境查询只读单向链你写 React 时设备环境查询是「window matchMedia 魔法」window.matchMedia 读取系统深浅色// React 设备环境查询window matchMedia 魔法读取系统深浅色functionuseColorMode(){const[colorMode,setColorMode]useStatelight|dark(light)useEffect((){constmqwindow.matchMedia((prefers-color-scheme: dark))// 从系统读深浅色setColorMode(mq.matches?dark:light)consthandler(e:MediaQueryListEvent)setColorMode(e.matches?dark:light)mq.addEventListener(change,handler)// 系统改 → 同步return()mq.removeEventListener(change,handler)},[])returncolorMode}// React 设备环境查询window matchMedia 魔法系统改同步应用不可改系统你写鸿蒙 ArkTS 时Environment设备环境查询只读单向链——Environment → AppStorage → Component// ArkTS Environment 设备环境查询只读单向链Environment.envProp(colorMode,ColorMode.LIGHT)// ✅ 设备色彩模式存入 AppStorage只读EntryComponentstruct Index{StorageProp(colorMode)colorMode:ColorModeColorMode.LIGHT// ✅ StorageProp 单向绑定只读不回写build(){Text(colorMode ${this.colorModeColorMode.LIGHT?LIGHT(浅色):DARK(深色)})}}// Environment 设备环境查询只读单向链Environment → AppStorage → Component应用不可写入window matchMedia 魔法 vs 设备环境查询单向链的区别React 把设备环境查询当 window matchMedia 魔法读取系统深浅色ArkTS 把 Environment 当「设备环境查询单向链」Environment → AppStorage → Component。根因不是 window matchMedia 魔法是设备环境查询单向链——Environment 设备环境查询只读不可写Environment → AppStorage → Component 单向链。二、根因Environment 的设备环境查询单向链机制鸿蒙 ArkUI 的 Environment 是设备环境查询单向链绑定——Environment → AppStorage → Component 单向链来自三重绑定机制。机制 1Environment 设备环境查询只读——不是应用可写状态Environment 荬饰器设备环境查询只读——应用不可写入只能查询// ✅ Environment 设备环境查询只读不可写Environment.envProp(languageCode,en)// ✅ 设备语言码存入 AppStorage只读Environment.envProp(colorMode,ColorMode.LIGHT)// ✅ 设备色彩模式只读Environment.envProp(fontScale,1.0)// ✅ 设备字体缩放只读Environment.envProp(layoutDirection,LayoutDirection.LTR)// ✅ 设备布局方向只读Environment.envProp(accessibilityEnabled,false)// ✅ 设备无障碍是否启用只读// ⚠ Environment 所有属性不可变应用不可写入只能查询// ⚠ Environment 内置参数languageCode / colorMode / fontScale / fontWeightScale / layoutDirection / accessibilityEnabledwindow matchMedia 魔法 vs 设备环境查询只读的区别React 把设备环境查询当 window matchMedia 魔法读取系统深浅色ArkTS 把 Environment 当「设备环境查询只读」应用不可写入只能查询。根因不是 window matchMedia 魔法是设备环境查询只读——Environment 设备环境查询只读不可写Environment → AppStorage → Component 单向链。机制 2StorageProp 单向绑定环境变量——只读不回写 AppStorageStorageProp 荬饰器单向绑定环境变量——Environment → AppStorage → Component只读不回写// ✅ StorageProp 单向绑定环境变量Environment → AppStorage → ComponentEnvironment.envProp(languageCode,en)// ✅ 设备语言码存入 AppStorageEntryComponentstruct Index{StorageProp(languageCode)languageCode:stringen// ✅ StorageProp 单向绑定只读不回写StorageProp(colorMode)colorMode:ColorModeColorMode.LIGHT// ✅ StorageProp 单向绑定StorageProp(fontScale)fontScale:number1.0// ✅ StorageProp 单向绑定StorageProp(layoutDirection)layoutDirection:LayoutDirectionLayoutDirection.LTR// ✅ StorageProp 单向绑定StorageProp(accessibilityEnabled)accessibilityEnabled:booleanfalse// ✅ StorageProp 单向绑定build(){Column({space:10}){Text(languageCode ${this.languageCode})// ✅ 显示设备语言码如 zhText(colorMode ${this.colorModeColorMode.LIGHT?LIGHT(浅色):DARK(深色)})// ✅ 显示设备色彩模式Text(fontScale ${this.fontScale})// ✅ 显示设备字体缩放Text(layoutDirection ${this.layoutDirectionLayoutDirection.LTR?LTR(从左到右):RTL(从右到左)})// ✅ 显示设备布局方向Text(accessibilityEnabled ${this.accessibilityEnabled})// ✅ 显示设备无障碍是否启用}}}// StorageProp 单向绑定环境变量Environment → AppStorage → Component只读不回写StorageLink 双向绑定 vs StorageProp 单向绑定的区别StorageLink 双向绑定改 → AppStorage 同步 → Component 同步StorageProp 单向绑定AppStorage 改 → Component 同步Component 改不同步回 AppStorage。Environment 设备环境查询用 StorageProp 单向绑定只读不回写因为应用对环境变量参数不可写只能在 Environment 中查询。机制 3AppStorage.set 改环境变量——Environment 设备环境不受影响AppStorage.set 改环境变量——Environment 设备环境不受影响// ⚠ AppStorage.set 改 languageCode但 Environment 不受影响设备环境只读AppStorage.set(languageCode,fr)// ⚠ AppStorage 改 languageCodefr// Environment 设备语言码仍为原值如 zh不受 AppStorage.set 影响// ⚠ StorageProp 本地改不回写 AppStoragethis.languageCodefr// ⚠ StorageProp 本地改 languageCodefr不回写 AppStorage// AppStorage 中 languageCode 仍为 Environment 设备语言码如 zhAppStorage.set 改环境变量 vs Environment 设备环境只读的区别AppStorage.set 改环境变量AppStorage 中 languageCode 改为 frEnvironment 设备环境只读Environment 设备语言码仍为原值如 zh不受 AppStorage.set 影响。根因不是 AppStorage.set 改环境变量是 Environment 设备环境只读——Environment 设备环境查询只读不可写AppStorage.set 改 AppStorage 中的环境变量副本不影响 Environment 设备环境真实值。三、真机配图Environment 环境变量状态边界——设备环境查询只读真机配图展示 Environment 设备环境查询只读单向链设备环境查询区Environment 只读languageCode如 zh/ colorModeLIGHT 浅色/ fontScale1.0/ layoutDirectionLTR 从左到右/ accessibilityEnabledfalse所有属性不可变应用不可写入只能查询应用级状态对比区AppStorage 可读写AppStorage.setOrCreate(“appTheme”, “dark”) 可改vs Environment colorMode 设备只读不可改验证按钮区改 languageCode “fr”StorageProp 本地改不回写/ 直接改 AppStorage.set(“languageCode”, “fr”)Environment 设备环境不受影响/ 查 AppStorage.get(“languageCode”) 当前值四、真解法Environment 设备环境查询的三个场景场景 1Environment 设备环境查询90% 场景首选深浅色/多语言/字体缩放Environment 设备环境查询用 StorageProp 单向绑定深浅色/多语言/字体缩放// ✅ 场景 1Environment 设备环境查询深浅色/多语言/字体缩放Environment.envProp(colorMode,ColorMode.LIGHT)// ✅ 设备色彩模式深浅色Environment.envProp(languageCode,en)// ✅ 设备语言码多语言Environment.envProp(fontScale,1.0)// ✅ 设备字体缩放无障碍EntryComponentstruct Index{StorageProp(colorMode)colorMode:ColorModeColorMode.LIGHT// ✅ StorageProp 单向绑定StorageProp(languageCode)languageCode:stringen// ✅ StorageProp 单向绑定StorageProp(fontScale)fontScale:number1.0// ✅ StorageProp 单向绑定build(){Column({space:8}){// ✅ 深浅色根据设备 colorMode 切换主题Text(深浅色主题).fontColor(this.colorModeColorMode.DARK?#fff:#000)// ✅ 多语言根据设备 languageCode 切换文案Text(this.languageCodezh?你好:Hello!)// ✅ 字体缩放根据设备 fontScale 调整字号Text(fontScale${this.fontScale}).fontSize(16*this.fontScale)}}}// Environment 设备环境查询深浅色/多语言/字体缩放StorageProp 单向绑定只读不回写场景 2Environment 应用逻辑使用从 AppStorage 获取环境变量Environment 应用逻辑使用从 AppStorage 获取单向绑定环境变量// ✅ 场景 2Environment 应用逻辑使用从 AppStorage 获取环境变量Environment.envProp(languageCode,en)// ✅ 设备语言码存入 AppStorage// ✅ 从 AppStorage 获取单向绑定的 languageCode 变量constlang:SubscribedAbstractPropertystringAppStorage.propstring(languageCode)if(lang.get()zh){console.info(你好)// ✅ 设备语言码为 zh输出「你好」}else{console.info(Hello!)// ✅ 设备语言码非 zh输出「Hello!」}// Environment 应用逻辑使用AppStorage.prop 获取单向绑定环境变量根据值做逻辑判断场景 3Environment vs AppStorage vs PersistentStorage 作用域边界设备环境查询 vs 应用级 vs 跨启动Environment vs AppStorage vs PersistentStorage 作用域边界// ✅ 场景 3Environment vs AppStorage vs PersistentStorage 作用域边界// Environment 设备环境查询只读不可写Environment.envProp(colorMode, ColorMode.LIGHT)Environment.envProp(colorMode,ColorMode.LIGHT)// ✅ 设备色彩模式只读不可写// AppStorage 应用级状态可读写不跨启动AppStorage.setOrCreate(appTheme, dark)AppStorage.setOrCreate(appTheme,dark)// ✅ 应用级状态可读写不跨启动// PersistentStorage 持久化状态可读写跨启动PersistentStorage.persistProp(persistTheme, dark)AppStorage.setOrCreate(persistTheme,dark)PersistentStorage.persistProp(persistTheme,dark)// ✅ 持久化状态可读写跨启动// ✅ 作用域边界// Environment 设备环境查询只读深浅色/多语言/字体缩放系统改同步应用不可改系统// AppStorage 应用级状态可读写不跨启动应用全局状态页面卸载状态仍存在不跨启动// PersistentStorage 持久化状态可读写跨启动用户偏好/登录状态应用重启后状态仍存在跨启动Environment vs AppStorage vs PersistentStorage 作用域边界的区别Environment 设备环境查询只读不可写深浅色/多语言/字体缩放系统改同步应用不可改系统AppStorage 应用级状态可读写不跨启动应用全局状态页面卸载状态仍存在不跨启动PersistentStorage 持久化状态可读写跨启动用户偏好/登录状态应用重启后状态仍存在跨启动。根因不是应用级 AppStorage 是设备环境查询只读——Environment 设备环境查询只读不可写Environment → AppStorage → Component 单向链。五、一句话哲学写鸿蒙 ArkUI 记住Environment 不是应用级 AppStorage 是设备环境查询只读单向链——Environment 荬饰器设备环境查询只读不可写Environment → AppStorage → Component 单向链。根因不是应用级 AppStorage 是设备环境查询只读——Environment 设备环境查询只读不可写应用不可写入只能查询 StorageProp 单向绑定环境变量只读不回写 AppStorage AppStorage.set 改环境变量Environment 设备环境不受影响 Environment vs AppStorage vs PersistentStorage 作用域边界设备环境查询只读 vs 应用级可读写不跨启动 vs 跨启动可读写。Environment 设备环境查询用 StorageProp 单向绑定首选90% 场景Environment 应用逻辑使用从 AppStorage 获取单向绑定环境变量Environment vs AppStorage vs PersistentStorage 作用域边界选对存储槽设备环境查询只读用 Environment应用级可读写不跨启动用 AppStorage跨启动可读写用 PersistentStorage。设备环境查询只读不可写单向链是 ArkUI 状态联动深水区核心
返回列表