全局监视
使用store.watch
方法用于全局监视State
中的数据变化,当所监视的数据发生变化时,可以执行侦听器函数。
监听方法
watch
方法的签名如下:
ts
// 监听全部
watch(listener:WatchListener,options?:WatchListenerOptions):Watcher
// 只监听指定路径
watch(paths:'*' | string | (string|string[])[],
listener:WatchListener,options?:WatchListenerOptions
):Watcher
返回Watcher
类型,用于取消监听。
ts
type Watcher = { off:()=>void }
监听函数
WatchListener
是一个函数,用来处理监视到的数据变化,其签名如下:
ts
type WatchListener<Value=any,Parent=any> =
(operate:StateOperate<Value,Parent>)=>void
type StateOperate<Value=any,Parent=any> = {
type : StateOperateType,
path : string[],
value : Value,
indexs? : number[],
oldValue? : Value,
parentPath?: string[],
parent? : Parent,
reply? : boolean
}
- 当侦听到数据变化时,
watch
会调用WatchListener
函数,并传入一个StateOperate
对象。 StateOperate
对象包括了变化的类型type
,path
,value
等信息。
StateOperate
对象的属性如下:
属性 | 类型 | 说明 |
---|---|---|
type | string | 状态操作类型,取值get ,set ,delete ,insert ,update ,remove ,batch |
path | string[] | 状态路径 |
value | any | 值 |
indexs | number[] | 数组操作时的索引 |
oldValue | any | 旧值 |
parentPath | string[] | 父路径 |
parent | any | 父值 |
reply | boolean | 批量操作时是否回放 |
watch
能状态的读写操作,包括get
,set
,delete
,insert
,update
,remove
,batch
等操作进行监听。get
,set
,delete
适于对象的值的读写insert
,update
,remove
适于数组的操作batch
适于批量操作,当使用batchUpdate
会触发此类型的操作事件,详见批量操作reply
参数用于标识该操作是否是在批量更新时的事件回放。
注意
监听函数只能是一个同步函数
监听选项
ts
type WatchListenerOptions = {
once? : boolean
operates?: '*' | 'read' | 'write' | StateOperateType[] // 只侦听的操作类型
filter? : (args:StateOperate)=>boolean // 过滤器
}
属性 | 类型 | 说明 |
---|---|---|
once | boolean | 是否只监听一次 |
operates | '*'| 'read' | 'write' | StateOperateType[] | 只侦听的操作类型 |
filter | (args:StateOperate)=>boolean | 过滤器函数,返回true 则执行监听函数,否则不执行 |
- 监听函数最重要的参数是
operates
,用来配置要监听的操作类型,可以是'*'
,'read'
,'write'
,或者一个操作类型数组。 - 默认
operates='write'
,即监听所有写操作。 operates='get
代表监听所有读操作。operates='*'
代表监听所有读写删除操作。operates
也可以是一个操作类型数组,比如['set','delete']
,代表监听set
和delete
操作。once
属性用来配置是否只监听一次。filter
函数用来过滤监听的操作,返回true
则执行监听函数,否则不执行。
示例:
tsx
store.watch((operate)=>{
....
},{
operates:'write'
})
全局监听
使用watch(listener,options?)
方法用来全局监听State
中的数据变化,对状态的任何操作均会执行监听函数。
- 通过
watch
方法监听所有的数据变化,当数据发生变化时,会执行监听函数。 watch.options
支持指定要监听的哪些操作类型,比如watch(listener,{operates:['set','delete']})
。
局部监听
除了全局监听外,还可以使用watch(paths,listener,options?)
方法用来只监听指定路径的状态数据变化。
- 可以一次监听多个路径,比如
watch(['order.price','order.count'],listener)
。 - 甚至可以监听路径中包含通配符,比如
watch('order.*'],listener)
。
数组监听
watch
也可以支持数组的监听,比如watch('order.books',listener)
,当order.books
数组发生变化时,会执行监听函数。
区别于普通对的是监听事件#️⃣
- 数组的监听事件有
insert
,update
,remove
三种。 - 对数组成员的操作参数会多一个
indexs
属性,用来标识数组的索引。 get
操作事件也适用于数组
依赖收集
AutoStore
的依赖收集功能就是基于watch
功能实现。
以下是同步计算属性在初始化时的依赖收集的代码:
ts
function collectDependencies(){
let dependencies:string[][] = []
// 1. 侦听所有的get操作
const watcher = this.store.watch((event)=>{
// 将依赖路径保存起来
dependencies.push(event.path)
},{operates:['get']})
// 2. 运行一次同步计算的getter函数
this.run({first:true})
// 3. 依赖收集完成后就结束监听
watcher.off()
// .......
return dependencies
}
INFO
store.watch
方法用于全局监视State
中的数据变化,计算属性的实现也是基于watch
方法。