作用域
计算作用域指的是传递给计算函数Getter的第一个参数。
Autostore在创建Store时,支持配置scope参数来指定计算属性函数的第一个参数,如下:
ts
export enum ObserverScopeRef{
Root = 'root', // 指向State根对象
Current = 'current', // 指向计算属性所在的对象
Parent = 'parent', // 指向计算属性所在对象的父对象
Depends = 'depends' // 指向异步计算的依赖数组,仅在异步计算时生效
Self = 'self' // 指向自身,默认值
}
// 指定Store中计算函数的上下文,如果是字符串代表是当前对象的指定键
// 如果是string[],则代表是当前Store对象的完整路径
export type ComputedScope = ObserverScopeRef | string | string[]
| ((state:any)=>string | string[] | ObserverScopeRef)
const store = new AutoStore( {
user:{
firstName:"Zhang",
lastName:"Fisher",
fullName: computed((scope)=>{
// scope指向user
},["user.firstName","user.lastName"])
}
} )scope参数的类型是ComputedScope,可以是ObserverScopeRef枚举值,也可以是字符串或字符串数组,也可以是一个函数。scope参数的默认值是ObserverScopeRef.Current,即指向计算属性所在的对象。
指定Scope
默认情况下computed的计算函数Getter可以指定scope参数,如下:
- 默认值
默认情况下,scope指向计算函数所在的对象。如上例中,scope指向fullName所在的user对象。
- 全局指定
可以在创建Store时,通过scope参数来全局指定计算属性的默认scope,如下:
tsx
const store = new AutoStore(
{
user: {
firstName: "Zhang",
lastName: "Fisher",
fullName: computed((scope) => {
// scope指向root
return scope.user.firstName + scope.user.lastName;
}),
},
},
{
scope: ObserverScopeRef.Root, // 所有计算属性的默认scope指向状态根
},
);- 局部指定
也可以局部指定计算属性的scope,如下:
tsx
const store = new AutoStore({
user: {
firstName: "Zhang",
lastName: "Fisher",
fullName: computed(
(scope) => {
// scope指向root
return scope.user.firstName + scope.user.lastName;
},
{
scope: ObserverScopeRef.Root, // 仅指定当前计算属性的scope
},
),
},
});取值范围
Current
默认情况下,scope==ObserverScopeRef.Current时,计算函数的scope指向计算函数所在的对象。
tsx
import { ObserverScopeRef, useStore } from "@autostorejs/react";
import { ColorBlock } from "x-react-components";
export default () => {
const { state } = useStore(
{
user: {
firstName: "Zhang",
lastName: "Fisher",
fullName: function (scope) {
// scope指向user对象
return scope.firstName + scope.lastName;
},
},
},
{
// 指定计算属性的默认上下文指向计算函数所有的当前对象
scope: () => ObserverScopeRef.Current,
},
);
return (
<div>
<ColorBlock name="FullName">{state.user.fullName}</ColorBlock>
</div>
);
};- 上面代码中,
fullName函数的scope指向所在的user对象,即state.user。
注意🌝
scope==ObserverScopeRef.Current是默认值,一般不需要指定,以上仅仅是示例。
Root
@autostorejs/react会将计算属函数的scope指向ObserverScopeRef.Root,即当前的State根对象,如下:
tsx
import { useStore, ObserverScopeRef } from "@autostorejs/react";
import { ColorBlock } from "x-react-components";
export default () => {
const { state } = useStore(
{
user: {
firstName: "Zhang",
lastName: "Fisher",
fullName: function (scope) {
// scope指向root对象
return scope.user.firstName + scope.user.lastName;
},
},
},
{
scope: ObserverScopeRef.Root,
},
);
return (
<div>
<ColorBlock name="FullName">{state.user.fullName}</ColorBlock>
</div>
);
};Parent
当scope==ObserverScopeRef.Parent时,指向计算函数所在的对象的父对象。
tsx
import { new AutoStore, ObserverScopeRef } from "@autostorejs/react";
import { ColorBlock } from "x-react-components";
const { state } = new AutoStore(
{
parent: {
user: {
firstName: "Zhang",
lastName: "Fisher",
fullName: function (scope) {
// scope指向user对象的父对象,即parent
return scope.user.firstName + scope.user.lastName;
},
},
},
},
{
// 指定计算属性的默认上下文指向计算函数所有的当前对象
scope: ObserverScopeRef.Parent,
},
);
export default () => {
return (
<div>
<ColorBlock name="FullName">{state.parent.user.fullName}</ColorBlock>
</div>
);
};字符串
当store.options.scope==<字符串>时,此时<字符串>就是指向绝对路径。
tsx
import { new AutoStore } from "@autostorejs/react";
import { ColorBlock } from "x-react-components";
const { state } = new AutoStore(
{
user: {
firstName: "Zhang",
lastName: "Fisher",
fullName: function (scope) {
// this指向user.address.city
return scope;
},
address: {
city: "Quanzhou",
},
},
},
{
scope: "user.address.city",
},
);
export default () => {
return (
<div>
<ColorBlock name="FullName">{state.user.fullName}</ColorBlock>
</div>
);
};提醒
scope===<字符串>时使用的是绝对路径,采用.作为路径分隔符,如user.address.city。
字符串数组
tsx
import { new AutoStore } from "@autostorejs/react";
import { ColorBlock } from "x-react-components";
const { state } = new AutoStore(
{
user: {
firstName: "Zhang",
lastName: "Fisher",
fullName: function (scope) {
// this指向user.address['main.city']
return scope;
},
address: {
"main.city": "Quanzhou",
},
},
},
{
scope: ["user", "address", "main.city"],
},
);
export default () => {
return (
<div>
<ColorBlock name="FullName">{state.user.fullName}</ColorBlock>
</div>
);
};提醒
当状态路径中包含.字符时,可以使用字符串数组来指定路径,避免产生歧义。
Depends
当scope==ObserverScopeRef.Depends时,指向计算函数的依赖项的值。
tsx
import { new AutoStore, computed, ObserverScopeRef } from "@autostorejs/react";
import { ColorBlock } from "x-react-components";
const { state } = new AutoStore({
user: {
firstName: "Zhang",
lastName: "Fisher",
fullName: computed(
async (deps) => {
return deps[0] + deps[1];
},
["user.firstName", "user.lastName"], // 声明依赖
{
async: true,
scope: ObserverScopeRef.Depends,
},
),
},
});
export default () => {
return (
<div>
<ColorBlock name="FullName">{state.user.fullName.value}</ColorBlock>
</div>
);
};提示
ObserverScopeRef.Depends仅在异步计算时生效,而异步计算必须通过computed函数来指定依赖