TypeScript在Vuex4中使用TS实战分享

目录
  • 简介
  • createStore
  • GetterTree
  • MutationTree
  • ActionTree
  • ModuleTree
  • 实战
    • 整体目录结构
    • 首先定义根state的类型
    • 在创建store的时候将根state的类型传递进去。
    • 并且需要导出key
    • 在Vue实例使用store的时候将key一并传入。
    • 在vue组件使用
    • 自定义useStore()方法
    • modules的使用
  • 总结

简介

虽然TypeScript知识点学了很多,但是在实际项目中很多小伙伴还并不知道怎么用,今天笔者结合Vuex4来使用TypeScript实战一下。

本文分vuex4类型 Api分析和vuex4实战两部分讲述。

首先我们来分析下 vuex4 的类型 Api

createStore

我们可以先看看createStore方法,发现它需要传递一个泛型,并且这个泛型会应用到state上。

export function createStore<S>(options: StoreOptions<S>): Store<S>;
export interface StoreOptions<S> {
  state?: S | (() => S);
  getters?: GetterTree<S, S>;
  actions?: ActionTree<S, S>;
  mutations?: MutationTree<S>;
  modules?: ModuleTree<S>;
  plugins?: Plugin<S>[];
  strict?: boolean;
  devtools?: boolean;
}

GetterTree

我们可以看到getters的类型GetterTree接收了两个泛型。

export interface GetterTree<S, R> {
  [key: string]: Getter<S, R>;
}

这两个泛型分别应用在本模块state上和根state上。

export type Getter<S, R> = (state: S, getters: any, rootState: R, rootGetters: any) => any;

MutationTree

我们可以看到mutations的类型MutationTree只接收了一个泛型。

export interface MutationTree<S> {
  [key: string]: Mutation<S>;
}

并且这个泛型只应用到本模块state上。

export type Mutation<S> = (state: S, payload?: any) => any;

ActionTree

我们可以看到actions的类型ActionTree接收了两个泛型。

export interface ActionTree<S, R> {
  [key: string]: Action<S, R>;
}

并且也将这两个泛型分别应用在本模块state上和根state上。我们还可以看到,由于action支持对象和方法形式的写法,所以Action的类型是ActionHandlerActionObject的联合类型。

export type Action<S, R> = ActionHandler<S, R> | ActionObject<S, R>;
export type ActionHandler<S, R> = (this: Store<R>, injectee: ActionContext<S, R>, payload?: any) => any;
export interface ActionContext<S, R> {
  dispatch: Dispatch;
  commit: Commit;
  state: S;
  getters: any;
  rootState: R;
  rootGetters: any;
}

ModuleTree

我们可以看到modules的类型ModuleTree只接收了一个泛型。并且将这个泛型传递到了Module里面。

export interface ModuleTree<R> {
  [key: string]: Module<any, R>;
}

我们可以发现,module的类型和createStoreStoreOptions是非常像的。

因为模块本身也有自己的state、getters、actions、mutations、modules

export interface Module<S, R> {
  namespaced?: boolean;
  state?: S | (() => S);
  getters?: GetterTree<S, R>;
  actions?: ActionTree<S, R>;
  mutations?: MutationTree<S>;
  modules?: ModuleTree<R>;
}

了解了vuex4类型 Api接下来我们就进入到实战环节了。

实战

首先我们需要使用vuecli创建一个TypeScript的项目。

整体目录结构

笔者store整体目录结构如下:

  • index.ts 和以前的还是一样,用来创建根store并导出根store
  • interfaces.ts 用来存放store的类型。
  • modules.ts 和以前的还是一样,用来存放模块。

首先定义根state的类型

// interfaces.ts
type Info = { address: string };
export interface IRootState {
  name: string;
  age: number;
  info: Info;
}

在创建store的时候将根state的类型传递进去。

// index.ts
import { createStore, Store } from "vuex";
import { InjectionKey } from "vue";
import { IRootState } from "./interfaces";

export default createStore<IRootState>({
  state: {
    name: "root",
    age: 0,
    info: { address: "" },
  },
  getters: {
    getRootName(state) {
      return state.name;
    },
    getRootInfo(state) {
      return state.info;
    },
  },
  mutations: {},
  actions: {},
});

并且需要导出key

// index.ts
export const key: InjectionKey<Store<IRootState>> = Symbol();

在Vue实例使用store的时候将key一并传入。

// main.ts
import store, { key } from "@/store";

createApp(App).use(store, key).mount("#app");

在vue组件使用

这样我们在vue组件就能享受到TypeScript的优势啦。

注意这里的useStore(),也需要我们把key传递进去。

import { useStore } from "vuex";
import { key } from "@/store";
setup() {
  const store = useStore(key);

  return {
    rootName: store.state.name,
  };
},

可以看到,我们使用state的时候就会被自动提示啦。

并且当你使用不存在的属性时会在我们编写代码的时候就会直接报错提示。

相较js,大大提高了开发效率不说,还减少了bug

自定义useStore()方法

如果觉得每次useStore(),还需要我们把key传递进去麻烦的话,我们可以创建自己的useStore()方法。

// index.ts
import { useStore as baseUseStore } from "vuex";

export function useStore() {
  return baseUseStore(key);
}

这样我们在vue组件使用store的时候引入自己的useStore方法就可以啦。

import { useStore } from "@/store";

setup() {
  const store = useStore();

  return {
    rootName: store.state.name,
  };
},

我们知道,在实际项目中只创建一个根store是远远不够的。一般我们都会使用modules。下面笔者介绍下怎么使用modules

modules的使用

模块的类型是Module,并且需要传递本模块state类型和根state类型。

本模块state类型需要传递进去我们可以理解,但是为什么要传递根state类型呢?

因为我们的gettersactions参数里面是有rootState的,所以需要引入根state类型。

// modeuls/test1.ts
import { Module } from "vuex";
import { IRootState, ITest1State } from "../interfaces";
const Test1: Module<ITest1State, IRootState> = {
  state: {
    name: "test1",
    count: 0,
  },
  getters: {
    getTest1Name(state) {
      return state.name;
    },
    getAllName(state, rootState) {
      return state.name + rootState.age;
    },
  },
};
export default Test1;

创建好模块后我们需要在根store里面引入进去,引入方式和以前还是一样。

并且我们需要把模块的state类型一并传递到InjectionKey中和根state类型形成交叉类型,并重新生成key

// index.ts
import { createStore, Store, useStore as baseUseStore } from "vuex";
import { InjectionKey } from "vue";
import { IRootState, ITest1State } from "./interfaces";
import test1 from "./modeuls/test1";
export default createStore<IRootState>({
  // ...
  modules: {
    test1: test1,
    // ...多个模块,类似
  },
});
// 定义模块类型
type Modules = {
  test1: ITest1State;
  // ...多个模块,类似
};

// 使用交叉类型形成新的key
export const key: InjectionKey<Store<IRootState & Modules>> = Symbol();

我们来看看在vue组件中的使用效果。

我们可以发现,当我们使用state的时候,test1模块也会被提示出来

并且它里面的属性也会被直接提示出来

好了,实战环节就讲述的差不多了,小伙伴们时候都懂了呢?

总结

虽然vuex4TypeScript有了很好的支持,但是笔者觉得还是不够的。

比如 使用麻烦,每次需要定义一个key,还需要把可以传递到vueuse方法里面,并且在使用useStore的时候也还需要将key传递进去,无疑增加了开发成本。

其次,这样的配置并不会对getters、mutations、actions生效,只会对state有提示。

pinia比起来,整体使用体验还是会差很多。如果想学习pinia,并想了解pinia和vuex区别的话可以看看TypeScript Pinia实战分享(Vuex和Pinia对比梳理总结)一文。

到此这篇关于TypeScript在Vuex4中使用TS实战分享的文章就介绍到这了,更多相关TypeScript Vuex4内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue生态的新成员Pinia的详细介绍

    目录 安装和配置 Store核心 State Getters Actions Vue Devtools 最后 结论 参考文献 Pinia是Vue应用程序的状态管理方案,是Vuex核心团队成员开发.感觉更像是常规的旧 javascript 导入模块,实现了很多Vuex5的提案. Pinia同时支持Vue2和Vue3,不过下面展示的例子都是使用Vue3,Pinia的版本是Pinia@2.0.9. Vue2和Vue3使用的Pinia版本有一点不同,因此请查看官方Pinia 文档以获取更多信息. 安装和

  • vue3搭配pinia的踩坑实战记录

    目录 前言 An Object could not be cloned? VUE 3的toRaw PINIA与VUE 3可以混合搭配? 同样的操作在VUE 3下的结果 最后的解决方式 总结 前言 最近接手了一个新项目,用的是VUE3+pinia的组合.由于之前没有用过这2个库,只能现学现做.幸运的是这两者的上手难度都不大,项目可以正常开发.但这其中也遇到了一些坑,今天就来讲其中我印象最深的一个. An Object could not be cloned? 不知道有多少开发者遇到过这个报错——A

  • TypeScript Pinia实战分享(Vuex和Pinia对比梳理总结)

    目录 简介 安装 创建pinia并传递给vue实例 创建store state getters actions 在vue组件使用 获取state 获取getters 修改state 数据持久化 总结 简介 今天我们再来实战下官方推荐的新的vue状态管理工具Pinia. pinia 由 vue 团队中成员所开发的,因此也被认为是下一代的 vuex,即 vuex5.x,在 vue3 的项目中使用也是备受推崇.所以 pinia 的学习迫在眉睫. 下面我们正式开始pinia的学习吧. 安装 yarn a

  • Vue3状态管理之Pinia的入门使用教程

    目录 Vue3 新的发展方向(来源于尤大知乎) 一.Pinia 简介与基础 1.1 Pinia 简介 1.2 Pinia 基础 二.Pinia 在Vue3-Vite中的使用 2.1 基础使用流程 2.2 state 中数据的解构访问 2.3 state 中数据的修改方式(actions和组件中) 2.4 getters 的使用 三.Pinia 数据持久化 总结 Vue3 新的发展方向(来源于尤大知乎) Vue 3 将在 2022 年 2 月 7 日 成为新的默认版本 基于 Vite 的极速构建工

  • Pinia简单使用以及数据持久化详解

    目录 基本介绍 基本使用与state actions的使用 getters的使用 storeToRefs的使用 pinia模块化 pinia数据持久化 用法 常见疑问 进阶用法 总结 基本介绍 Pinia 是 Vue.js 的轻量级状态管理库 官方网站:pinia.vuejs.org/ pinia和vuex4一样,也是vue官方的状态管理工具(作者是 Vue 核心团队成员) pinia相比vuex4,对于vue3的兼容性更好 pinia相比vuex4,具备完善的类型推荐 pinia同样支持vue

  • 使用VueCli3+TypeScript+Vuex一步步构建todoList的方法

    前言 Vue3.x 即将来袭,使用 TypeScirpt 重构,TypeScript 将成为 vue 社区的标配,出于一名程序员的焦虑,决定现在 Vue2.6.x 踩一波坑. vue 官方文档已经简略地对 typescript 的支持进行了介绍,我们使用 Vue Cli3 直接生成项目 创建项目 ❓为什么使用 Vue Cli3 构建项目 官方维护,后续升级减少兼容性问题 使用以下配置进行项目的生成: Babel 对 Ts 进行转译 TSLint 对 TS 代码进行规范,后续会使用 prettie

  • vue3中vuex与pinia的踩坑笔记记录

    目录 介绍 安装使用 简单对比写法差异与共同点 Vuex 和 Pinia 的优缺点 何时使用Pinia,何时使用Vuex 总结 介绍 Pinia 是 Vue.js 的轻量级状态管理库,最近很受欢迎.它使用 Vue 3 中的新反应系统来构建一个直观且完全类型化的状态管理库. Pinia的成功可以归功于其管理存储数据的独特功能(可扩展性.存储模块组织.状态变化分组.多存储创建等). 另一方面,Vuex也是为Vue框架建立的一个流行的状态管理库,它也是Vue核心团队推荐的状态管理库.Vuex高度关注应

  • TypeScript在Vuex4中使用TS实战分享

    目录 简介 createStore GetterTree MutationTree ActionTree ModuleTree 实战 整体目录结构 首先定义根state的类型 在创建store的时候将根state的类型传递进去. 并且需要导出key 在Vue实例使用store的时候将key一并传入. 在vue组件使用 自定义useStore()方法 modules的使用 总结 简介 虽然TypeScript知识点学了很多,但是在实际项目中很多小伙伴还并不知道怎么用,今天笔者结合Vuex4来使用T

  • vue项目中使用ts(typescript)入门教程

    目录 1.引入Typescript 2.配置文件webpack配置 3.让项目识别.ts 4.vue组件的编写 data()中定义数据 props传值 完整代码案例 最近项目需要将原vue项目结合ts的使用进行改造,这个后面应该是中大型项目的发展趋势,看到一篇不错的入门教程,结合它并进行了一点拓展记录之.本文从安装到vue组件编写进行了说明,适合入门. 1.引入Typescript npm install vue-class-component vue-property-decorator --

  • 如何在vue中使用ts的示例代码

    本文介绍了如何在vue中使用ts的示例代码,分享给大家,具体如下: 注意:此文并不是把vue改为全部替换为ts,而是可以在原来的项目中植入ts文件,目前只是实践阶段,向ts转化过程中的过渡. ts有什么用? 类型检查.直接编译到原生js.引入新的语法糖 为什么用ts? TypeScript的设计目的应该是解决JavaScript的"痛点":弱类型和没有命名空间,导致很难模块化,不适合开发大型程序.另外它还提供了一些语法糖来帮助大家更方便地实践面向对象的编程. typescript不仅可

  • 如何获取TypeScript的声明文件.d.ts

    一.TypeScript的声明文件就像C/C++用.h文件.当使用TypeScript调用其他已经编写好的类库时,可以提供IntelliSense智能提示. 二.使用npm指令来获取.d.ts文件 install -save @types/jquery -g 运行后在type/jquery目录下生成4个文件:index.d.ts,lincense,package.json,readme.md,其中的index.d.ts即为jquery的声明文件. 三.npm需要Nodejs环境,安装步骤如下 1

  • 千万级用户系统SQL调优实战分享

    用户日活百万级,注册用户千万级,而且若还没有进行分库分表,则该DB里的用户表可能就一张,单表上千万的用户数据. 某系统专门通过各种条件筛选大量用户,接着对那些用户去推送一些消息: 一些促销活动消息 让你办会员卡的消息 告诉你有一个特价商品的消息 通过一些条件筛选出大量用户,针对这些用户做推送,该过程较耗时-筛选用户过程. 用户日活百万级,注册用户千万级,而且若还没有进行分库分表,则该DB里的用户表可能就一张,单表上千万的用户数据. 对运营系统筛选用户的SQL: SELECT id, name 

  • Python爬取城市租房信息实战分享

    目录 一.单线程爬虫 二.优化为多线程爬虫 三.使用asyncio进一步优化 四.存入Mysql数据库 (一)建表 (二)将数据存入数据库中 五.最终效果图 (已打码) 思路:先单线程爬虫,测试可以成功爬取之后再优化为多线程,最后存入数据库 以爬取郑州市租房信息为例 注意:本实战项目仅以学习为目的,为避免给网站造成太大压力,请将代码中的num修改成较小的数字,并将线程改小 一.单线程爬虫 # 用session取代requests # 解析库使用bs4 # 并发库使用concurrent impo

  • Springboot插件开发实战分享

    目录 一 背景 二 监控日志插件开发 1 新建aop切面执行类MonitorLogInterceptor 三 总结 一 背景 项目新增监控系统,对各个系统进行监控接口调用情况,初期的时候是在各个项目公共引用的依赖包里面新增aop切面来完成对各个系统的接口调用进行监控,但是这样有缺点,一是不同项目的接口路径不同,导致aop切面要写多个切面路径,二是一些不需要进行监控的系统,因为引入了公共包也被监控了,这样侵入性就太强了.为了解决这个问题,就可以通过springboot的可插拔属性了. 二 监控日志

  • 前端React Nextjs中的TS类型过滤实用技巧

    目录 自我介绍 分步介绍 开胃小菜 keyof in Conditional 泛型 正餐开始 实战应用例子 最后 大家好,我是零一,相信大家在阅读同事写的代码或者优秀的开源库的代码时,一定见过各种各样的风骚的TS写法,不花点时间下去根本看不懂,换作是我们,可能就直接一个 any 完事了,但是真正当项目体积变大后,你会发现这些 TS骚操作真的很重要,因为它能很好地帮助你做静态类型校验 自我介绍 TS类型过滤,英文名(我自己取的)叫 FilterConditionally,这是它完整的样子 type

  • Springboot集成kafka高级应用实战分享

    目录 深入应用 1.1 springboot-kafka 1.2 消息发送 1.2.1 发送类型 1.2.2 序列化 1.2.3 分区策略 1.3 消息消费 1.3.1 消息组别 1.3.2 位移提交 深入应用 1.1 springboot-kafka 1)配置文件 kafka: bootstrap-servers: 52.82.98.209:10903,52.82.98.209:10904 producer: # producer 生产者 retries: 0 # 重试次数 acks: 1 #

随机推荐