作用域
计算作用域指的是传递给计算函数Getter的第一个参数。
@autostorejs/react在创建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 = createStore( {
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 = createStore( {
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 = createStore( {
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 { createStore,ObserverScopeRef } from '@autostorejs/react';
import { ColorBlock } from "x-react-components"
const { state } = createStore({
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 { createStore } from '@autostorejs/react';
import { ColorBlock } from "x-react-components"
const { state } = createStore({
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 { createStore } from '@autostorejs/react';
import { ColorBlock } from "x-react-components"
const { state } = createStore({
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 { createStore,computed,ObserverScopeRef } from '@autostorejs/react';
import { ColorBlock } from "x-react-components"
const { state } = createStore({
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函数来指定依赖