美文网首页每天学一点Vue3
把 nf-state 改为 ts 形式

把 nf-state 改为 ts 形式

作者: 自然框架 | 来源:发表于2022-05-12 11:19 被阅读0次

    以前 nf-state 是普通 js 的形式,尝试着改为 ts 的形式。

    效果不太理想,目前的水平还看不懂 pinia 的源码,所以暂时采用自己的想法来实现。

    Typescript 的优点

    • 明确类型
    • 有提示
    • 代码检查

    原生js没有地方写类型的定义,只能用 jsDoc 写注释,但是写来写去就乱了。ts可以明确定义对象的结构,可以更明确一些。

    而编辑器(比如vscode)也可以给出提示和代码检查,这种代码检查要比 单纯的ESLint更严格和准确一些。

    比如:

    
    /**
     * 内部保存状态的容器
     */
    export interface Store {
      [index: string | symbol] : any
    }
    
    /**
     * 状态的类型,对象和数组都需要实现这个接口
     * * $id —— 状态标识,string | symbol
     * * _value —— 记录原值,可以是对象,也可以是 function 
     * * isLog —— 是否记录日志。true :记日志;false: 不记日志(默认值)
     * * 内置方法
     * * * $reset —— 重置
     * * * $patch —— 修改部分属性
     * * * set $state —— 整体赋值,会去掉原属性
     * * * $toRaw —— 取原型,不包含内部方法
     * * * get log() —— 获取日志
     * * * 
     * * 
     */
    export interface IState {
      /**
       * 状态标识,string | symbol
       */
      get $id(): string | symbol
      
      /**
       * 记录原值,可以是对象,也可以是 function 
       */
      get $_value(): any
      
      /**
       * 是否记录日志。true :记日志;false: 不记日志(默认值)
       */
      $isLog: boolean
    
      /**
       * 重置
       */
      $reset (): void
      
      /**
       * 修改部分属性
       */
      $patch(_val: any): void
      
      /**
       * 整体赋值,会去掉原属性
       */
      set $state(value: any)
      
      /**
       * 取原型,不包含内部方法
       */
      $toRaw<T>(): T
      
      /**
       * 获取日志
       */
      get $log(): Array<StateLogInfo>
    }
    
    /**
     * 日志的类型
     * * {
     * *   time: '时间戳',
     * *   kind: '', // 操作类型
     * *   oldValue: {},
     * *   newValue: {},
     * *   subValue: {}, // 参数
     * *   callFun: '' // 调用的函数名
     * * }
     */
     export interface StateLogInfo {
      time: number,
      kind: string, // 操作类型
      oldValue: any,
      newValue: any,
      subValue: any, // 参数
      callFun: string // 调用的函数名
    }
    
    /**
     * 记录状态的变化日志容器,用key来区分
     * * stateLog = {
     * *  key: {
     * *   log: [
     * *     {
     * *       time: '时间戳',
     * *       kind: '', // 操作类型
     * *       oldValue: {},
     * *       newValue: {},
     * *       subValue: {}, // 参数
     * *       callFun: '' // 调用的函数名
     * *     }
     * *   ]
     * *  }
     * * }
     */
    export interface StateLog {
      [index: string | symbol] : {
        log: Array<StateLogInfo>
      }
    }
    
    /**
     * 创建状态的选项。
     * * isLocal —— true:局部状态;false:全局状态(默认属性);
     * * isLog ——  true:做记录;false:不用做记录(默认属性);
     * * level ——
     * * * 1:宽松,可以各种改变属性,适合弹窗、抽屉、多tab切换等。
     * * * 2:一般,不能通过属性直接改状态,只能通过内置函数、action 改变状态
     * * * 3:严格,不能通过属性、内置函数改状态,只能通过 action 改变状态
     * * * 4:超严,只能在指定组件内改变状态,比如当前用户的状态,只能在登录组件改,其他组件完全只读
     */
    export interface StateOption {
      /**
       * true:局部状态;false:全局状态(默认属性);
       */
      isLocal?: boolean, 
      /**
       * true:做记录;false:不用做记录(默认属性);
       */
      isLog?: boolean, // 
      /**
       * 1:宽松,可以各种改变属性,适合弹窗、抽屉、多tab切换等。
       * 2:一般,不能通过属性直接改状态,只能通过内置函数、action 改变状态
       * 3:严格,不能通过属性、内置函数改状态,只能通过 action 改变状态
       * 4:超严,只能在指定组件内改变状态,比如当前用户的状态,只能在登录组件改,其他组件完全只读
      */
      level?: number
    }
    
    
    /**
     * 创建一个状态的参数类型
     */
    export interface StateCreateOption {
      state?: any,
      getters?: any,
      actions?: any
    }
    
    /**
     * 创建多个状态的类型
     */
    export interface StateCreateListOption {
      store: {
        [index: string | symbol]: StateCreateOption | any
      },
      init: () => void
    }
    

    好吧,还是各种any。因为状态管理,需要接收各种类型,目前还不知道如何处理,泛型可以解决一部分,剩余的以后再说。

    Typescript 的思考

    js 实在是太灵活了,可以有各种写法,对各种写法都规定类型,目前的水平还是比较吃力。

    ts 好像只能在编写和打包时进行检查,运行时好像无能为力了。

    而状态管理,主要实在运行时存入状态和取出状态,这种时候 ts 要如何做类型检查呢?或则,我的想法本身就不对?

    小结

    目前的水平硬改为 ts,有点痛苦,也许以后会好些。

    .d.ts 文件还是不同清楚如何自动生成,所以只好手动,好在对外的函数不是太多。

    另外,vite 打包的时候,并没有包括 type 文件,所以,只好手动拷贝一份过去。

    满篇的爆红,很头疼。。。

    相关文章

      网友评论

        本文标题:把 nf-state 改为 ts 形式

        本文链接:https://www.haomeiwen.com/subject/dzssurtx.html