简介

今天我们再来实战下官方推荐的新的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 内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

TypeScript Pinia实战分享(Vuex和Pinia对比梳理总结)的更多相关文章

  1. Vue状态管理库Pinia详细介绍

    这篇文章主要介绍了Vue3-pinia状态管理,pinia是 vue3 新的状态管理工具,简单来说相当于之前 vuex,它去掉了 Mutations 但是也是支持 vue2 的,需要的朋友可以参考下

  2. 一文详解Pinia和Vuex与两个Vue状态管理模式

    这篇文章主要介绍了一文详解Pinia和Vuex与两个Vue状态管理模式,Pinia和Vuex一样都是是vue的全局状态管理器。其实Pinia就是Vuex5,只不过为了尊重原作者的贡献就沿用了这个看起来很甜的名字Pinia

  3. 使用typescript类型实现ThreeSum

    这篇文章主要介绍了使用typescript类型实现ThreeSum,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以一下,希望对你学习又是帮助

  4.  typeScript入门基础介绍

    这篇文章主要介绍了 typeScript入门基础,TypeScript 是由微软开发的开源、跨平台的编程语言,是 javaScript 的超集,最终被编译为 javaScript代码。常常被简称为TS支持JS、ES语法,下文将继续其他基础介绍,需要的朋友可以参考一下

  5. typescript返回值类型和参数类型的具体使用

    本文主要介绍了typescript返回值类型和参数类型的具体使用文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  6. uniapp中vuex的应用使用步骤

    Vuex是一个专为Vue.js应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,下面这篇文章主要给大家介绍了关于uniapp中vuex的应用使用,需要的朋友可以参考下

  7. Vue3 携手 TypeScript 搭建完整项目结构

    TypeScript 是JS的一个超级,主要提供了类型系统和对ES6的支持,使用 TypeScript 可以增加代码的可读性和可维护性,在 react 和 vue 社区中也越来越多人开始使用TypeScript,这篇文章主要介绍了Vue3 携手 TypeScript 搭建完整项目结构,需要的朋友可以参考下

  8. 关于TypeScript开发的6六个实用小技巧分享

    TypeScript是Javascrip t超集,支持静态类型检测,可以在编译期提前暴露问题,节省debug时间,下面这篇文章主要给大家介绍了关于TypeScript开发的6六个实用小技巧,需要的朋友可以参考下

  9. typescript+react实现移动端和PC端简单拖拽效果

    这篇文章主要为大家详细介绍了typescript+react实现移动端和PC端简单拖拽效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. vue3中router路由以及vuex的store使用解析

    这篇文章主要介绍了vue3中router路由以及vuex的store使用解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部