基于Vue3做一套适合自己的状态管理(五)组合:setup 风格,更灵活
计划章节
- 基类:实现辅助功能
- 继承:充血实体类
- 继承:OptionApi 风格的状态
- Model:正确的打开方式
- 组合:setup 风格,更灵活
- 注册状态的方法、以及局部状态和全局状态
- 列表页面需要的状态
- 当前登录用户的状态
使用setup风格做状态,更灵活
上两章说的是使用继承的方式实现状态,这次我们换成组合的方式,体验一下极致的灵活。
组合,关键看思路
我们先看看可以用了组合的元素:
- 普通对象
- 基类
- ref
- computed
- reactive
- readonly
- watch
- 函数
- 其他
做一个 List 的语法糖
上一次我们做了一个Model的语法糖,这次我们做一个List的:
/**
* 给 BaseArray 套个壳,加上 reactive 实现响应性 & IState
* @param val 数组或者函数
* @returns
*/
export default function List<T>(val: IArrayOrFunction): Array<T> & IState {
const re = new baseArray(val)
return reactive(re)
}
组合一下
我们做一个简单的数据列表的状态:
const useState = () => {
const name = ref('我是一个字符串')
// 可以直接赋值的数组
const dataList2 = List([])
// 原生数组
const dataList = reactive([{
name: '我是 setup',
age: 10
}])
// 分页信息
const pageInfo = reactive({
index: 1,
count: 30
})
const load = () => {
const index = pageInfo.index
// 加载数据
dataList2.$state = [{
name: '我是 setup',
age: 10 + index
}]
}
watch(() => pageInfo.index, () => {
// 根据分页信息获取数据
load()
})
return {
name,
dataList,
dataList2,
dataList3: readonly(dataList2),
pageInfo,
load
}
}
直接组合起来,并没有转化为 state、getter、action 的结构,这样虽然有点乱,但是也有优点:
- 灵活
- 如果不需要直接赋值,可以使用原生的对象、数组;
- 如果需要直接赋值,可以使用基类(Model、List);
- 如果需要只读,可以使用readonly;
- 还可以使用 watch、computed 等;
- 可以轻松和其他状态联动;
- 总之,需要什么就加入什么,非常灵活。
- 用 watch 联动各个状态 可以分别设置一个或者多个状态,然后可以用 watch 把各个状态联动起来,没有“割裂”感
结构
似乎好像有点乱,不过好用就好。
没有固定的state、action这样的格式,完全看如何组合。虽然看起来很乱,其实这和 compositionAPI 的 setup 才是一样的风格,也就是传说中的心智负担。
关于 Pinia 的 setup 方式
观察了 Pinia 的 setup 方式创建的状态,其结构和Option方式的一致,不是太理解这样做的目的,难道是为了统一结构吗?想想也是,使用状态的时候,不需要关心是采用哪种方式似乎也挺好。
想想也是,如果使用状态的时候,还需要先了解一下结构(创建方式),是不是会增加心智负担?
不过,如果优点大于缺陷的话,我觉得还是可以尝试一下的。
源码
在线演示
转载自:https://juejin.cn/post/7237426124669665337