Pinia是什么
Pinia
是 Vue
的存储库,容许您跨组件/页面共享状态。Pinia
这款产品最后是为了摸索 Vuex
的下一个版本,整合了外围团队对于 Vuex 5
的许多想法。最终,咱们意识到 Pinia
曾经实现了咱们想要在 Vuex 5
中提供的大部分内容,因而决定将其作为 新的官网举荐
。
Pinia特点
- 足够轻量,Pinia 重约
1kb
,甚至会遗记它的存在! - 去除
Mutation
,Actions
反对同步和异步(Actions
一个顶俩,写起来简洁); - 无需手动注册
Store
,Store 仅须要时才主动注册。如果从不应用,则永远不会“注册”(省心); - 没有模块嵌套,只有
Store
的概念,Store 之间能够自在应用,更好的代码宰割; Vue2
和Vue3
都能反对;- 反对大型项目迁徙期间,
Pinia
和Vuex
混合应用(贴心迁徙); - 更完满的
typescript
的反对; - 与
Vue devtools
挂钩,Vue2 和 Vue3 开发体验更好; - 反对插件扩大性能;
- 反对模块热更新,无需加载页面能够批改容器,能够放弃任何现有的状态;
- 反对服务端渲染;
Vuex
与 Pinia
用哪个
Vuex
当初处于保护模式。它依然能够工作,但不再增加新的性能。对于新的利用我的项目
,倡议应用 Pinia
。Pinia
曾经实现了咱们想要在 Vuex 5
中提供的大部分内容,因而决定将其作为 新的官网举荐(留神:旧版网站没有更新)
如何应用 Pinia
一、装置
npm install pinia
二、定义 Store
新建 src/stores 目录并在其上面创立 index.ts
Pinia
的目录通常被称为 stores 而不是store
, 这是为了强调Pinia
应用多个store
,而不是Vuex
中的单个store
,同时也有迁徙期间Pinia
和Vuex
混合应用的思考。
// 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
中删除了 Mutation
,Actions
反对同步和异步
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疾速入门 (一)