作用域
计算作用域
指的是传递给计算函数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
函数来指定依赖