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 add pinia
// or
npm install pinia

创建pinia并传递给vue实例

创建一个 pinia 并传递给 vue 应用。

在这一步我们可以发现,我们只需要简单创建一个pinia对象传给vue实例就可以自动收集我们后续创建的新store。并不需要像vuex一样把各个模块聚集在根store里面传递给vue实例。总体来说使用更加简单。

import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from './app.vue'
createApp(App).use(createPinia()).mount('#app')

创建store

vuex不同,pinia没有了根storemodules的概念。在pinia中一个store一个文件,一个store里面包含state、getters、actions三部分。总体来说更简单更清晰。

需要使用defineStore来创建store

注意第一个参数一定要唯一

import { defineStore } from "pinia";
export const mainStore = defineStore("main", {
  state: () => {
    return {
      name: "randy man",
      age: 24,
    };
  },
  getters: {
    getterName(state) {
      return state.name.toUpperCase() + "-----" + state.age;
    },
    // 这种方式也可以,不过需要自己手动指定返回值类型
    getterAge(): number {
      return this.age;
    },
  },
  actions: {
    // 直接使用this修改state
    changeName(payload: string) {
      this.name = payload;
      return "success";
    },

    // 异步action
    async fetchData(payload: number) {
      const response = await fetch(
        `https://jsonplaceholder.typicode.com/todos/${payload}`
      );
      const res = response.json();

      // 调用其他action
      // this.changeName("xxx");

      return res;
    },
  },
});

下面我们详细介绍下第二个参数。

state

state就是状态,和vuex一样,就不过多介绍了。只需要注意他是一个方法,返回一个state对象。

state: () => {
  return {
    name: "randy man",
    age: 24,
  };
},

getters

getters是计算属性,和vuex中是一样的。但是需要知道它支持两种写法。

通过this修改state的方式需要自己手动指定返回值类型。

getters: {
  getterName(state) {
    return state.name.toUpperCase() + "-----" + state.age;
  },
  // 这种方式也可以,不过需要自己手动指定返回值类型
  getterAge(): number {
    return this.age;
  },
},

actions

pinia中没有了mutations,所以同步和异步操作都在action中进行。

并且在pinia中是支持直接调用别的action,或者别的模块的action

actions: {
  // 直接使用this修改state
  changeName(payload: string) {
    this.name = payload;
    return "success";
  },
  // 异步action
  async fetchData(payload: number) {
    const response = await fetch(
      `https://jsonplaceholder.typicode.com/todos/${payload}`
    );
    const res = response.json();

    // 调用其他action
    // this.changeName("xxx");

    return res;
  },
},

在 action 里调用其他 store 里的 action 也比较简单,引入对应的 store 后即可访问其内部的方法了,跟在vue组件中使用是一样的。

// user.ts
import { useAppStore } from './app'
export const useUserStore = defineStore({
  id: 'user',
  actions: {
    async login(account, pwd) {
      const { data } = await api.login(account, pwd)
      const appStore = useAppStore()
      appStore.setData(data) // 调用 app store 里的 action 方法
      return data
    }
  }
})

在vue组件使用

vue组件中使用也很简单,需要使用哪个store引入哪个store就可以啦。

<template>
  <div>
    <div>name: {{ name }}</div>
    <div>getterName: {{ getterName }}</div>
    <div>
      <button @click="updateMainName">修改main name</button>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, computed } from "vue";
import { mainStore } from "@/pinia/main";
import { storeToRefs } from "pinia";

export default defineComponent({
  name: "PiniaView",
  setup() {
    const store = mainStore();

    const updateMainName = async () => {
      // 直接修改 不建议
      // store.name = "demi woman";

      // 对象形式修改
      // store.$patch({ name: "demi woman" });

      // 函数形式修改
      // store.$patch((state) => {
      //   state.name = "demi woman";
      // });

      // 通过action修改
      const result = store.changeName("demi woman");
      console.log(result);

      // 返回的值不会被Promise包裹
      const result2 = await store.fetchData(1);
      console.log(result2);
    };

    // 直接解构不能响应式
    // const { name, getterName } = store;

    // 这样响应式
    const name = computed(() => store.name);
    const getterName = computed(() => store.getterName);

    // 这样也能响应式
    // const { name, getterName } = storeToRefs(store);

    return {
      name,
      getterName,
      updateMainName,
    };
  },
});
</script>

vuex相比,使用pinia不需要定义state类型,不用定义key就能得到TypeScript的优势。

可以看到我们使用store的时候,它的所有属性和方法state、getters、actions等都会自动提示出来,并且当我们使用了不存在的属性在编码期间会直接报错。

获取state

获取state的方式有三种,但是需要注意通过直接解构的方式数据是不会响应式的。如果需要响应式需要使用computedstoreToRefs

import { storeToRefs } from "pinia";
const store = mainStore();
// 直接解构不能响应式
// const { name } = store;
// 这样响应式
const name = computed(() => store.name);
// 这样也能响应式
// const { name } = storeToRefs(store);

获取getters

获取getters的方式也有三种,但是需要注意通过直接解构的方式数据是不会响应式的。如果需要响应式需要使用computedstoreToRefs

import { storeToRefs } from "pinia";
const store = mainStore();
// 直接解构不能响应式
// const { getterName } = store;
// 这样响应式
const getterName = computed(() => store.getterName);
// 这样也能响应式
// const { getterName } = storeToRefs(store);

修改state

修改state的方式也有很多种,可以直接修改、还可以使用$patch来传递对象或方法来修改、还可以通过action修改。

const updateMainName = async () => {
  // 直接修改 不建议
  // store.name = "demi woman";
  // 对象形式修改
  // store.$patch({ name: "demi woman" });
  // 函数形式修改
  // store.$patch((state) => {
  //   state.name = "demi woman";
  // });
  // 通过action修改
  const result = store.changeName("demi woman");
  // action 返回啥就是啥 result等于'success'
};

虽然修改方式很多,但是还是在实际开发中推荐使用action来修改state

使用action的时候还有一点需要注意。我们知道在vuex中,action如果有返回值是会被Promise包裹resolve出来,也就是会返回一个Promise对象。但是在pinia中,action返回啥就是啥不会被Promise包裹resolve出来。

数据持久化

我们知道,vuexpinia本质上都是对象,都是临时存储,当页面刷新数据都会丢失。

想要刷新不丢失就需要我们手动存储在localStoragesessionStorage里面。如果不想手动处理,我们也可以使用插件。

vuex使用vuex-persistedstate

pinia使用pinia-plugin-persistedstate

具体怎么使用笔者就不再赘述了大家可以自行查看文档,原理都是一样的,通过配置将指定数据存储到localStoragesessionStorage里面实现数据持久化。

总结

  • pinia有完整的 typescript 的支持。不再像使用vuex需要定义key、定义state类型那么麻烦。
  • 足够轻量,压缩后的体积只有1.6kb
  • 去除 mutations,只有 state,getters,actions。跟react-redux类似,同步异步都在action里面进行。根简单清晰。
  • 没有模块嵌套,只有 store 的概念,store 之间可以自由使用,更好的代码分割。更简单易懂。
  • 无需手动添加 storestore 一旦创建便会自动添加,我们只需要在vue组件直接引用需要的store使用即可。

到此这篇关于TypeScript Pinia实战分享(Vuex和Pinia对比梳理总结)的文章就介绍到这了,更多相关TypeScript Pinia 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(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 文档以获取更多信息. 安装和

  • 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

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

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

  • 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 的极速构建工

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

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

  • 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

  • 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 #

  • React中常见的TypeScript定义实战教程

    目录 一 引沿 二 什么是调和 三 什么是Filber 四 实现调和的过程 五 总结 一 引沿 Fiber 架构是React16中引入的新概念,目的就是解决大型 React 应用卡顿,React在遍历更新每一个节点的时候都不是用的真实DOM,都是采用虚拟DOM,所以可以理解成fiber就是React的虚拟DOM,更新Fiber的过程叫做调和,每一个fiber都可以作为一个执行单元来处理,所以每一个 fiber 可以根据自身的过期时间expirationTime,来判断是否还有空间时间执行更新,如

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

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

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

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

  • Springboot插件开发实战分享

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

  • Vue.js实战之Vuex的入门教程

    前言 在 Vue.js 的项目中,如果项目结构简单, 父子组件之间的数据传递可以使用  props 或者 $emit 等方式,详细点击这篇文章查看. 但是如果是大型项目,很多时候都需要在子组件之间传递数据,使用之前的方式就不太方便.Vue 的状态管理工具 Vuex 完美的解决了这个问题. 一.安装并引入 Vuex 项目结构: 首先使用 npm 安装 Vuex cnpm install vuex -S 然后在 main.js 中引入 import Vue from 'vue' import App

  • tomcat6_apache2.2_ajp 负载均衡加集群实战分享

    环境: -------------------------------------------- 一台apache2.2服务器,三台tomcat服务器: apache2.2服务器 1.ip:192.168.1.20 2.只装apache软件:httpd-2.2.6.tar.bz2 安装路径:/usr/local/apache2 tomcat服务器:均配置相同的应用. 1.集群名:balancer://tomcatcluster 2.三台集群服务器ip: IP_1:192.168.1.31 IP_

随机推荐