Last Updated 2019-09-22 15:30:02

模块watch

watch定义当各个stateKey的值发生变化时,要触发的回调。

type WatchFn = (
  oldVal:any,
  newVal:any, 
  fnCtx:FnCtx,
)=> void;

type WatchFnDesc = {
  fn: WatchFn,
  compare?: boolean,
  immediate?: boolean,
  depKeys?: string[],
}

type WatchValueDef = WatchFn | WatchFnDesc;

读者可fork此在线示例做修改来加深理解。

定义watch

我们可以在子模块配置watch属性的对象里定义回调,key就是retKey,value就是watch函数watch描述体

import { run } from 'concent';

run({
  foo:{
    state: {...},
    watch:{
      firstName(firstNameNew, firstNameOld)=> { 
        console.log(`firstName changed from ${firstNameOld} to ${firstNameNew}`);
      },
      fullName:{
        fn:(newState)=> {
          console.log(`any value of firstName or lastName changed will trigger this`);
        },
        depKeys: ['firstName', 'lastName'],
      },
      lastName:{
        fn:(newState)=> {
          console.log(`fn will been triggered when value of lastName changed`);
        },
        immediate: true,//配置状态时,就触发此fn
      }
    }
  }
});

模块computed一样,建议为模块单独定义一个watch文件,导出来给模块用,代码结构按更细粒度的职责分类有利于阅读和维护。

// code in model/foo/watch.js
export function firstName(firstNameNew, firstNameOld)=> { 
  console.log(`firstName changed from ${firstNameOld} to ${firstNameNew}`);
}

export const fullName = {
  fn:(newState)=> {
    console.log(`any value of firstName or lastName changed will trigger this`);
  },
  depKeys: ['firstName', 'lastName'],
}

export const lastName = {
  fn:(newState)=> {
    console.log(`fn will been triggered when value of lastName changed`);
  },
  immediate: true,//配置状态时,就触发此fn
}
改写默认的depKeys

和模块computed一样,当retKey和stateKey同名时,不可以在显示的设定depKeys时重写默认的depKeys

错误定义

// 'firstName'隐含对应的默认depKeys是['firstName'],不可将其改写为['lastName']
export const firstName = {
  fn:(firstName)=> console.log('changed'),
  depKeys: ['lastName'], // wrong !!!}

watch触发时机

watch定义当各个stateKey的值发生变化时,要触发的回调。

  • 模块状态配置完成时,watch默认是不会被触发的(这一点区别于模块computed),除非人工设置immediate为true
  • stateKey的值为非primitive类型时,如果没有使用解构语法总是返回一个新的对象,watch回调也不会被触发,触非人工设置compare为false,表示只要对某个stateKey设了值就触发回调
  • 模块watch触发流程是在模块computed之后

run-module

修改默认配置

当用户不显示的定义immediatecompare时,immediate默认值是falsecompare默认值是true,用户可以在启动concent时,设置新的默认值。

import { run } from 'concent';

run(
  //store配置
  {
    foo:{},
    bar:{},
  },
  //可选配置
  {
    watchCompare: false,//修改模块watch的compare默认值
    watchImmediate: true,//修改模块watch的immediate默认值
  }
);

因为此配置是全局的,对所有模块都生效,所有修改默认值前,要明确的知道修改带来的结果是不是自己想要的效果,从而避免一些额外的bug。