安装 Pinia
Pinia Vite
pinia只支持vue项目
使用 Pinia
在vue项目中导入pinia
1 2 3 4 5 6 7 8 9 10
| import { createApp } from 'vue' import App from './App.vue'
import { createPinia } from 'pinia'
const pinia = createPinia()
onst app = createApp(App) app.use(pinia) app.mount('#app')
|
options API
在选项式写法中:this 指的是 store 实例, 可以通过 this.state 访问 state
组合式写法中:setup中没有 this 是 undefined
创建 store 文件夹
创建index.ts 文件
创建仓库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import {defineStore} from 'pinia'
export const useMainStore = defineStore('mian',{
state:()=>{ return { foo:100, count:100, arr:[1,2,3] } },
getters:{ },
actions:{ } })
|
使用
模板中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| <templte> <p>{{ mainStore.count }}</p> <p>{{ mainStore.foo }}</p>
</hr> <p>{{ count }}</p> <p>{{ foo }}</p>
<p><button @click="handleClick"></button></p> </templte> <script> import {useMainStore} from '../store' const mianStore = useMainStore()
cosnt {count, foo} = storeToRefs(mainStore) cosnt handleClick = () => { mainStore.count++ mainStore.foo++ mainStore.$patch({ count: mainStore.count+1, foo: 'hello', arr: [...mainStore.arr,4] }) mainStore.$patch(state => { state.count++, state.foo = 'hello', state.arr.push(4) })
mainStore.changeState()
}
</script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| getters:{ count(state) { console.log('count 调用了') return state.count + 10 }
count():number { console.log('count 调用了') return this.count + 10 } }
|
composition API
创建仓库
store/counter.ts
1 2 3 4 5
| import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => { return {} })
|
App.vue
1 2 3 4 5 6 7 8 9
| <script setup lang="ts"> import { useCounterStore } from './store/counter' const store = useCounterStore() </script>
<template> App </template>
|
进行状态管理
counter.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import { defineStore } from 'pinia' import { computed, ref } from 'vue'
export const useCounterStore = defineStore('counter', () => { const count = ref(100) const doubleCount = computed(() => count.value * 2) const update = () => count.value++ const asyncUpdate = () => { setTimeout(() => { count.value++ }, 1000) } return { count, doubleCount, update, asyncUpdate } })
|
使用数据和修改数据的方法
App.vue
1 2 3 4 5 6 7 8 9 10 11 12
| <script setup lang="ts"> import { useCounterStore } from './store/counter'
const store = useCounterStore() </script>
<template> APP {{ store.count }} {{ store.doubleCount }} <button @click="store.update()">count++</button> <button @click="store.asyncUpdate()">async update</button> </template>
|
storeToRefs
使用 storeToRefs 解决解构仓库状态丢失响应式的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <script setup lang="ts"> import { storeToRefs } from 'pinia' import { useCounterStore } from './store/counter'
const store = useCounterStore()
const { count, doubleCount } = storeToRefs(store) const { update, asyncUpdate } = store </script>
<template> APP {{ count }} {{ doubleCount }} <button @click="update">count++</button> <button @click="asyncUpdate">async update</button> </template>
|
Vuex 和 Pinia 的主要区别
体积大小:Vuex 核心有 state、mutations、actions、getters和modules。而 Pinia 则更简单,去除了modules 和 mutations,更加轻量化、更适用中小型项目
调试:vuex支持时间快照,在调试工具中可以看到mutations修改state数据的记录,并且可以回到对应的历史状态
状态组织:在 Vuex 中,所有的状态都被组织在一个大的单一对象中。而在 Pinia 中,每个 store 都是一个独立的状态容器,这使得状态更容易组织和管理
类型安全:Pinia 有更好的 TypeScript 支持,因此如果你使用 TypeScript,Pinia 可能会更适合你
开发工具支持:虽然 Vuex 和 Pinia 都支持 Vue.js 开发工具,但 Pinia 提供了一些更多的内置功能
服务器端渲染支持:Pinia 对服务器端渲染(SSR)提供了内置支持
兼容性:Vuex 和 Pinia 都支持 Vue 2 和 Vue 3