本篇文章同步更新於個人部落格,歡迎交流指教~謝謝您的閱讀
專案開發過程中常會有狀態共享的需求。昨天介紹了 Nuxt3 useState
Composable 來管理共享狀態(D19文章),今天將介紹狀態管理工具 Pinia。
狀態管理預計分為以下三篇說明,本篇將介紹 Pinia
Pinia 是 Vue 官方推薦使用的狀態管理工具,支援 Vue2 跟 Vue3,可以理解為 VueX 的接班人
Pinia vs VueX:
mutations
,統一透過 action
操作 state
Pinia 其他優點:
搭配 Nuxt 整合模組 @pinia/nuxt
進行安裝:
npm install pinia @pinia/nuxt
使用 npm 安裝時如果報錯
ERESOLVE could not resolve
,在package.json
加入以下內容,重新安裝即可"overrides": { "vue": "latest" }
如果不想全域引入 defineStore
,也可以在頁面各別引入:import { defineStore } from 'pinia'
export default defineNuxtConfig({
modules: [
'@pinia/nuxt'
],
pinia: { // 想要各別引入可以移除這段
autoImports: [
'defineStore'
]
}
})
在 store 資料夾建立檔案,範例 store/index.js
先以 Option Stores 進行說明,比較直觀好理解
export const useMainStore = defineStore('main', {
state: () => ({
counter: 0
}),
getters: {
doubleCounter() {
return this.counter * 2;
}
},
actions: {
increment() {
this.counter++
}
}
})
接著將以上內容改寫為 Composition API
ref()
:用來定義 state 屬性computed()
:定義 gettersfunction()
:定義 actionsexport const useMainStore = defineStore('main', () => {
const counter = ref(0);
const doubleCounter = computed(() => counter.value * 2)
const increment = () => {
counter.value++
}
return {
counter,
doubleCounter,
increment
}
})
<template>
<div>
{{ mainStore.counter }}
{{ mainStore.doubleCounter }}
<button @click="mainStore.increment()">increment</button>
</div>
</template>
<script setup>
import { useMainStore } from '@/store/index';
const mainStore = useMainStore();
</script>
import { useMainStore } from '@/store';
export default defineNuxtPlugin(({ $pinia }) => {
return {
provide: {
store: useMainStore($pinia)
}
};
});
使用 $store
取得狀態
<template>
<div>
{{ $store.counter }}
{{ $store.doubleCounter }}
<button @click="$store.increment()">increment</button>
</div>
</template>
<script setup>
const { $store } = useNuxtApp();
</script>
使用 $reset()
還原狀態
<template>
<div>
{{ $store.counter }}
<button @click="reset()">reset</button>
</div>
</template>
<script setup>
const { $store } = useNuxtApp();
const reset = () => {
$store.$reset();
};
</script>
必須自訂 reset 方法
export const useMainStore = defineStore('main', () => {
const counter = ref(0);
const reset = () => {
counter.value = 0;
}
return {
counter,
reset
}
})
參考資源:
https://nuxt.com/docs/getting-started/state-management
https://pinia.vuejs.org/ssr/nuxt.html#nuxt-js
https://nuxt.com/docs/migration/configuration#vuex
https://blog.twjoin.com/vue-state-management-介紹-pinia-9f8695110cd7