Skip to content

全局监视

使用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对象包括了变化的类型typepathvalue等信息。

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'],代表监听setdelete操作。
  • 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方法。