美文网首页
如何更丝滑的使用Vuex

如何更丝滑的使用Vuex

作者: sharpfeel | 来源:发表于2020-03-20 17:11 被阅读0次

vuex-cuer

简介

还在为 vuex 的魔法字符串而烦恼?还在为阅读项目里 vuex 相关的代码而头痛?

如何一目了然的知道某个 type 的功能?定义字符串常量加以注释 或者 使用d.ts文件进行注释?
那如何快捷的定位到 commitdispatch 相应的type 的原函数?


你可以来试试 vuex-cuer ,纵享丝滑

地址

github 
码云 
npm 

示例

demo 
js中的写法 
ts中的写法 

效果

  1. 推荐直接通过commits调用函数,因为这样有能查看到原函数的注释


    Image text
  2. 兼容commit函数调用,并且优化了提示


    Image text


诞生

  1. 由来

    这个库的诞生是因为我实在受不了接手的这个项目里的 vuex 相关的代码,阅读起来令我头皮发麻

    于是我决定使用 Typescript 基于 vuex 来封装一个有类型约束的库。

  2. 结构

    但是在设计之初我遇到了循环引用的问题,场景是:定义一个 store 对象的时候参数有 mutations 等等,然后需要在 mutations 的函数中访问 store 对象,如以下代码:

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    add (state) {
      state.count++
    }
  }
});

问题在于这个时候 store 还没出生,如何在 add 方法中使用 store 呢?
最终我确定了一个思路:以 Store 的类为核心,通过泛型关联其他四个属性 StateMutationsActionsGetters,如下结构:

Image text

然后还是这个问题,如何在 add 方法中使用 store?既然把 Mutations 封装成了类,可以把 store 这个对象绑定到 Mutations 的实例的 this 上面,于是就有了这个约束:

abstract class ICuer<T> {
  protected readonly store!: T;
}

这便是 MutationsActionsGetters 的基类。

但是这样还不够,state 对象也应该关联上,正好一起绑上去,这样同一个 Mutations 的函数互相访问可以省略第一个参数 state

interface IState<S = unknown> {
  state: S;
}

abstract class ICuer<T extends IState = IState> {
  protected readonly state!: T["state"];
  protected readonly store!: T;
}

于是乎就实现了:

class Mutations extends ICuer<ExampleStore> {
  /**
   * 加 `1`
   */
  addOne() {
    this.add(1);
  }

  /**
   * 加 `v`
   */
  add(v: number) {
    this.state.value += v;
    this.store.xxx
  }
}

同理可得 ActionsGetters

当然 Getters 有点区别,他下面的是属性,这并无大碍,构造的时候用 get 属性访问器就行了。


最后就是 Store 类的继承了,Store类 需要知道StateMutationsActionsGetters这四个属性的类型,所以通过泛型来约束:

class StoreCuer<
  S,
  M extends ICuer = ICuer,
  A extends ICuer = ICuer,
  G extends ICuer = ICuer
> extends Store<S> {
  constructor(
    state: S,
    options?: {
      mutations?: M;
      actions?: A;
      getters?: G;
      plugins?: StoreOptions<S>["plugins"];
      strict?: StoreOptions<S>["strict"];
    }
  )
}

然后把这些类型对应到相应的属性:

class StoreCuer<
  S,
  M extends ICuer = ICuer,
  A extends ICuer = ICuer,
  G extends ICuer = ICuer
> extends Store<S> {
  readonly commits!: M;
  readonly dispatchs!: A;
  readonly getters!: G;
}

这样就实现了:

const store = new StoreCuer();

store.getters.xxx //访问 getter
store.commits.xxx(payload?) //调用 commit
store.dispatchs.xxx(payload?) //调用 dispatch



结构就基本Ok了,剩下的就是代码逻辑的实现了。

  1. 优化

    未完待续

用法

  1. class Mutations
class Mutations extends Cuer.Mutations<ExampleStore> {

  test(){
    this.state.xxx //访问 state
    this.store.getters.xxx //访问 getter
    this.xxx //调用当前类的 commit
    this.store.commit("xxx") //调用 commit
    this.store.commits.xxx //调用 commit
  }
}
  1. class Actions
class Actions extends Cuer.Actions<ExampleStore> {

  test(){
    this.state.xxx //访问 state
    this.store.getters.xxx //访问 getter
    this.xxx //调用当前类的 dispatch
    this.store.commit("xxx", payload?) //调用 commit
    this.store.commits.xxx(payload?) //调用 commit
    this.store.dispatch("xxx", payload?) //调用 dispatch
    this.store.dispatchs.xxx(payload?) //调用 dispatchs
  }
}

  1. class Getters
class Getters extends Cuer.Actions<ExampleStore> {
  //使用访问器来实现 getter
  get test() {
    this.state.xxx //访问 state
    this.getters.xxx //访问 getter
    this.xxx //访问当前类的 getter

    return xxx;
  }
}

  1. class StoreCuer
// `StoreCuer` 继承自 `vuex` 的 `Store`,支持除 `module` 之外的大部分内容

class ExampleStore extends Cuer.StoreCuer<
  typeof state,
  Mutations,
  Actions,
  Getters
  > {
  constructor() {
    super(state, {
      mutations: new Mutations(),
      actions: new Actions(),
      getters: new Getters()
    });
  }
}

const store = new ExampleStore();

export default store;


store.state.xxx //访问 state
store.getters.xxx //访问 getter
store.xxx //访问 Store 的函数
store.commit("xxx", payload?) //调用 (优化约束,以强化提示)
store.commits.xxx(payload?) //调用 commit
store.dispatch("xxx", payload?) //调用 (优化约束,以强化提示)
store.dispatchs.xxx(payload?) //调用 dispatch
store.subscribe(fn) // (优化约束,以强化提示)
store.subscribeAction(fn) // (优化约束,以强化提示)
store.mapState({...}) // 映射 state
store.mapStateOfKeys(...) // 映射 state
store.mapGetters({...}) // 映射 getters
store.mapGettersOfKeys(...) // 映射 getters
store.mapActions({...}) // 映射 actions
store.mapActionsOfKeys(...) // 映射 actions
store.mapMutations({...}) // 映射 mutations
store.mapMutationsOfKeys(...) // 映射 mutations


相关文章

  • 如何更丝滑的使用Vuex

    vuex-cuer 简介 还在为 vuex 的魔法字符串而烦恼?还在为阅读项目里 vuex 相关的代码而头痛?如何...

  • 让你的网页更丝滑(一)

    前段时间,我将精力专注在Web性能领域;在这个领域下有个重要的课题是如何让网页更丝滑(流畅)。 想让网页变得丝滑,...

  • vuex状态管理 一

    目录 - 1.什么是vuex? - 2.为什么要使用Vuex? - 3.vuex的核心概念?||如何在组件中去使用...

  • vuex的使用

    同步的vuex提交的流程图: 异步vuex 修改数据的流程 Mutations里面如何传参: Vuex里面如何使用...

  • uniapp 中 vuex调试

    uniapp中内置了vuex依赖,在微信小程序中为了更方便的调试vuex相关数据,使用vuex中的createLo...

  • (十七)Vue3.x使用provide/inject来代替vue

    本章我们将介绍的是如何在vue3.x中使用provide/inject来代替vuex; 1、前言:在使用vuex的...

  • kubernetes 1.18离线安装 一键安装

    kuberentes 离线丝滑安装 为了让kubernetes安装与集群节点管理更丝滑,这次我们是花了大功夫。这次...

  • appium2-基于python调用unittest框架对iOS

    紧急上篇的 appium1-macOS10.12下如何丝滑的使用appium? 我相信环境问题已经解决完毕,虽然...

  • 2018-12-11-nuxt.j-vuex

    首先使用npm install --save-dev vuex把vuex添加到依赖,接下来就是如何在组件中使用vu...

  • iOS 如何丝滑的侧滑返回

    之前项目中开始使用了侧滑返回,本来几行代码搞定的问题后来发现了一个超级尴尬的问题,如下图 返回的时候出现了空白的情...

网友评论

      本文标题:如何更丝滑的使用Vuex

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