状态管理
什么是状态
在ofa.js中,状态是指组件或页面模块自身的 data 属性。这个状态只能在当前组件上使用,用于存储和管理该组件的内部数据。
当有多个组件或页面需要共享同一份数据时,传统的做法是通过事件传递或 props 层层传递,这种方式在复杂应用中会导致代码难以维护。因此需要状态管理——通过定义一个共享的状态对象,让多个组件或页面模块都可以访问和修改这份数据,从而实现状态的共享。
提示:状态管理适用于需要跨组件、跨页面共享数据的场景,如用户信息、购物车、主题配置、全局配置等。
生成状态对象
通过 $.stanz({}) 来创建一个响应式的状态对象。这个方法接收一个普通对象作为初始数据,返回一个响应式的状态代理。
基本用法(全局状态)
// 应用首页地址
export const home = "./list.html";
// 页面切换动画配置
export const pageAnime = {
current: {
opacity: 1,
transform: "translate(0, 0)",
},
next: {
opacity: 0,
transform: "translate(30px, 0)",
},
previous: {
opacity: 0,
transform: "translate(-30px, 0)",
},
};
export const contacts = $.stanz({
list: [{
id: 10010,
name: "皮特",
info: "每一天都是新的开始,阳光总在风雨后。",
},{
id: 10020,
name: "迈克",
info: "生活就像海洋,只有意志坚强的人才能到达彼岸。",
},{
id: 10030,
name: "约翰",
info: "成功的秘诀在于坚持自己的梦想,永不放弃。",
}]
});
// await fetch("/list.api").then(e=>e.json()).then(list=>data.list = list)
通讯录
-
Name: {{$data.name}}
状态对象的特性
1. 响应式更新
$.stanz() 创建的状态对象是响应式的。当状态数据发生变化时,所有引用该数据的组件都会自动更新。
const store = $.stanz({ count: 0 });
// 在组件中
export default {
data: {
store: {},
},
proto: {
increment() {
store.count++; // 所有引用了 store.count 的组件都会自动更新
},
},
attached() {
// 直接引用状态对象的属性
this.store = store;
},
detached() {
this.store = {}; // 组件销毁时,清空挂载的状态数据
},
};
2. 深度响应式
状态对象支持深度响应式,嵌套对象和数组的变化也会被监听。
const store = $.stanz({
user: {
name: "张三",
settings: {
theme: "dark",
},
},
list: [],
});
// 修改嵌套属性也会触发更新
store.user.name = "李四";
store.user.settings.theme = "light";
store.list.push({ id: 1, title: "新任务" });
最佳实践
1. 在组件 attached 阶段挂载状态
推荐在组件的 attached 生命周期中挂载共享状态:
export default {
data: {
list: [],
},
attached() {
// 将共享状态挂载到组件的 data 上
this.list = data.list;
},
detached() {
// 组件销毁时,清空挂载的状态数据,防止内存泄漏
this.list = [];
},
};
2. 合理管理状态作用域
状态的作用域取决于定义位置和导出方式:
独立 JS 文件中 export 导出的状态:全局状态,整个应用都可以访问和修改,通过 import 或 load 导入后使用。
// user-store.js
export const userStore = $.stanz({ user: null, theme: "light" });
页面或组件模块内部定义的状态:模块状态,仅在该模块内部使用。
<template component>
...
<script>
const localStore = $.stanz({ total: 0 });
export default async () => {
return {
data: {
localStore: {}
},
attached() {
this.localStore = localStore;
},
detached() {
// 组件销毁时,清空挂载的状态数据
this.localStore = {};
}
};
};
</script>
</template>
模块内状态管理
{{$index}} -
{{val}} - {{cartStore.total}}
注意事项
-
状态清理:在组件的
detached生命周期中,及时清理对状态数据的引用,避免内存泄漏。 -
避免循环依赖:状态对象之间不要形成循环引用,这可能导致响应式系统出现问题。
-
大型数据结构:对于大型数据结构,考虑使用计算属性或分片管理,避免不必要的性能开销。
-
状态一致性:在异步操作中注意状态的一致性,可以使用事务或批量更新来保证数据的完整性。