Pinia是什么

PiniaVue 的存储库,容许您跨组件/页面共享状态。Pinia 这款产品最后是为了摸索 Vuex 的下一个版本,整合了外围团队对于 Vuex 5 的许多想法。最终,咱们意识到 Pinia 曾经实现了咱们想要在 Vuex 5 中提供的大部分内容,因而决定将其作为 新的官网举荐

Pinia特点

  • 足够轻量,Pinia 重约 1kb,甚至会遗记它的存在!
  • 去除 MutationActions 反对同步和异步(Actions一个顶俩,写起来简洁);
  • 无需手动注册 Store,Store 仅须要时才主动注册。如果从不应用,则永远不会“注册”(省心);
  • 没有模块嵌套,只有 Store 的概念,Store 之间能够自在应用,更好的代码宰割;
  • Vue2Vue3 都能反对;
  • 反对大型项目迁徙期间,PiniaVuex 混合应用(贴心迁徙);
  • 更完满的 typescript 的反对;
  • Vue devtools 挂钩,Vue2 和 Vue3 开发体验更好;
  • 反对插件扩大性能;
  • 反对模块热更新,无需加载页面能够批改容器,能够放弃任何现有的状态;
  • 反对服务端渲染;

VuexPinia 用哪个

Vuex 当初处于保护模式。它依然能够工作,但不再增加新的性能。对于新的利用我的项目,倡议应用 PiniaPinia 曾经实现了咱们想要在 Vuex 5 中提供的大部分内容,因而决定将其作为 新的官网举荐(留神:旧版网站没有更新)

如何应用 Pinia

一、装置

npm install pinia

二、定义 Store

新建 src/stores 目录并在其上面创立 index.ts

Pinia 的目录通常被称为 stores 而不是 store, 这是为了强调 Pinia 应用多个 store,而不是 Vuex 中的单个 store,同时也有迁徙期间 PiniaVuex 混合应用的思考。
// src/stores/index.ts// 引入Store定义函数import { defineStore } from 'pinia'// 定义Store实例并导出,useStore能够是任何货色,比方useUser, useCart// 第一个参数,惟一不可反复,字符串类型,作为仓库ID 以辨别仓库// 第二个参数,以对象模式配置仓库的state,getters,actionsexport const useStore = defineStore('main', {  // state 举荐箭头函数,为了TS类型推断  state: () => {    return {      name: '张三',      counter: 0    }  },  getters: {},  actions: {}})

在 main.ts 中引入并挂载到根实例

// src/main.tsimport { createApp } from 'vue'import App from './App.vue'import { createPinia } from 'pinia'// 创立Vue利用实例// 实例化 Pinia// 以插件模式挂载Pinia实例createApp(App).use(createPinia()).mount('#app')

三、State

1、拜访State

<template>  <div>     <button @click="handleClick">批改状态数据</button>     <!-- 模板内不须要加.value -->     <p>{{store.name}}</p>     <!-- computed获取 -->     <p>{{name}}</p>     <!-- 或者应用解构之后的 -->     <p>{{counter}}</p>  </div></template><script lang="ts" setup>import { useStore } from '@/stores/index.ts'// 使一般数据变响应式的函数  import { storeToRefs } from "pinia";const store = useStore()// 联合computed获取const name = computed(() => store.name)// 解构并使数据具备响应式const { counter } = storeToRefs(store);// 点击 + 1;function handleClick() {  // ref数据这里须要加.value拜访  counter.value++;}</script>

2、批改State

1、单个参数批改 state

store.counter++

2、多个参数批改 state

store.$patch({  counter: store.counter + 1,  name: 'Abalam',})

3、全副批改 state

store.$state = { counter: 666, name: 'Paimon' }或pinia.state.value = {}

3、重置State

将状态重置为初始值

const store = useStore()store.$reset()

4、vue2写法

import { mapState } from 'pinia'import { useCounterStore } from '../stores/counterStore'export default {  computed: {    ...mapState(useCounterStore, ['counter'])    // 或    ...mapState(useCounterStore, {      myOwnName: 'counter',      double: store => store.counter * 2,      magicValue(store) {        return store.someGetter + this.counter + this.double      },    }),  },}

四、Getters

getter 中的值有缓存个性,相似于computed,如果值没有扭转,屡次应用也只会调用一次

1、定义Getters

export const useStore = defineStore('main', {  state: () => ({    counter: 0,  }),  getters: {    doubleCount: (state) => state.counter * 2,    // 主动推导返回类型    doubleCount(state) {      return state.counter * 2    },    // 依赖getters返回参数,则须要显性的设置返回类型    doublePlusOne(): number {      return this.doubleCount + 1    },  },})

2、应用Getters

<template>  <p>Double count is {{ store.doubleCount }}</p></template><script>export default {  setup() {    const store = useStore()        return { store }  },}</script>

3、vue2写法

import { mapState } from 'pinia'import { useCounterStore } from '../stores/counterStore'export default {  computed: {    ...mapState(useCounterStore, ['doubleCount'])    // 或    ...mapState(useCounterStore, {      myOwnName: 'doubleCounter',      double: store => store.doubleCount,    }),  },}

五、Actions

Pinia 中删除了 MutationActions 反对同步和异步

1、定义 Actions

// 同步export const useStore = defineStore('main', {  state: () => ({    counter: 0,    userData: null,  }),  actions: {     increment() {      this.counter++    },    randomizeCounter() {      this.counter = Math.round(100 * Math.random())    },  },})
// 异步import { mande } from 'mande'const api = mande('/api/users')export const useUsers = defineStore('users', {  state: () => ({    userData: null,  }),  actions: {    async registerUser(login, password) {      this.userData = await api.post({ login, password })    },  },})

2、调用 Actions

1、能够间接调用 store 的任何办法

<script>export default {  setup() {    const store = useStore()    store.randomizeCounter()  },}</script>

2、action 间的互相调用,间接用 this 拜访即可。

 export const useUserStore = defineStore({'user',  actions: {    increment() {      this.counter++    },    increase() {      // 调用另一个 action 的办法      this.increment()    },  }})

3、在 action 里调用其余 store 里的 action 也比较简单,引入对应的 store 后即可拜访其外部的办法。

import { useAuthStore } from './auth-store'export const useSettingsStore = defineStore('settings', {  state: () => ({    preferences: null,  }),  actions: {    async fetchUserPreferences() {      // 调用 auth-store store 里的 action 办法      const auth = useAuthStore()      if (auth.isAuthenticated) {        this.preferences = await fetchPreferences()      } else {        throw new Error('User must be authenticated')      }    },  },})

3、vue2写法

import { mapActions } from 'pinia'import { useCounterStore } from '../stores/counterStore'export default {  methods: {    ...mapActions(useCounterStore, ['increment'])    // 或    ...mapActions(useCounterStore, { myOwnName: 'doubleCounter' }),  },}

总结

总得来说,Pinia 就是 Vuex 的官网代替版,能够更好的反对 Vue2,Vue3以及TypeScript。在 Vuex 的根底上去掉了 Mutation模块嵌套等概念,语法更简洁间接, 更合乎 Vue3 的 Composition api,为 TypeScript 提供了更好的类型推导。以上是 Pinia.js 用法的一些介绍,Pinia.js 的内容还远不止这些,更多内容及应用有待大家本人摸索。Pinia文档

参考文章

  • Vue3新版中文文档
  • Pinia文档
  • 新一代状态管理工具,Pinia.js 上手指南
  • 大菠萝?Pinia曾经来了,再不学你就out了
  • pinia疾速入门 (一)