TypeScript?Pinia實戰(zhàn)分享(Vuex和Pinia對比梳理總結(jié))
簡介
今天我們再來實戰(zhàn)下官方推薦的新的vue
狀態(tài)管理工具Pinia
。
pinia
由 vue
團隊中成員所開發(fā)的,因此也被認為是下一代的 vuex
,即 vuex5.x
,在 vue3
的項目中使用也是備受推崇。所以 pinia
的學習迫在眉睫。
下面我們正式開始pinia
的學習吧。
安裝
yarn add pinia // or npm install pinia
創(chuàng)建pinia并傳遞給vue實例
創(chuàng)建一個 pinia
并傳遞給 vue
應(yīng)用。
在這一步我們可以發(fā)現(xiàn),我們只需要簡單創(chuàng)建一個pinia
對象傳給vue
實例就可以自動收集我們后續(xù)創(chuàng)建的新store
。并不需要像vuex
一樣把各個模塊聚集在根store
里面?zhèn)鬟f給vue
實例??傮w來說使用更加簡單。
import { createPinia } from 'pinia' import { createApp } from 'vue' import App from './app.vue' createApp(App).use(createPinia()).mount('#app')
創(chuàng)建store
與vuex
不同,pinia
沒有了根store
和modules
的概念。在pinia
中一個store
一個文件,一個store
里面包含state、getters、actions
三部分??傮w來說更簡單更清晰。
需要使用defineStore
來創(chuàng)建store
。
注意第一個參數(shù)一定要唯一
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(); // 調(diào)用其他action // this.changeName("xxx"); return res; }, }, });
下面我們詳細介紹下第二個參數(shù)。
state
state
就是狀態(tài),和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
中是支持直接調(diào)用別的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(); // 調(diào)用其他action // this.changeName("xxx"); return res; }, },
在 action
里調(diào)用其他 store
里的 action
也比較簡單,引入對應(yīng)的 store
后即可訪問其內(nèi)部的方法了,跟在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) // 調(diào)用 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" }); // 函數(shù)形式修改 // 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); }; // 直接解構(gòu)不能響應(yīng)式 // const { name, getterName } = store; // 這樣響應(yīng)式 const name = computed(() => store.name); const getterName = computed(() => store.getterName); // 這樣也能響應(yīng)式 // const { name, getterName } = storeToRefs(store); return { name, getterName, updateMainName, }; }, }); </script>
跟vuex
相比,使用pinia
不需要定義state
類型,不用定義key
就能得到TypeScript
的優(yōu)勢。
可以看到我們使用store
的時候,它的所有屬性和方法state、getters、actions
等都會自動提示出來,并且當我們使用了不存在的屬性在編碼期間會直接報錯。
獲取state
獲取state
的方式有三種,但是需要注意通過直接解構(gòu)的方式數(shù)據(jù)是不會響應(yīng)式的。如果需要響應(yīng)式需要使用computed
或storeToRefs
import { storeToRefs } from "pinia"; const store = mainStore(); // 直接解構(gòu)不能響應(yīng)式 // const { name } = store; // 這樣響應(yīng)式 const name = computed(() => store.name); // 這樣也能響應(yīng)式 // const { name } = storeToRefs(store);
獲取getters
獲取getters
的方式也有三種,但是需要注意通過直接解構(gòu)的方式數(shù)據(jù)是不會響應(yīng)式的。如果需要響應(yīng)式需要使用computed
或storeToRefs
import { storeToRefs } from "pinia"; const store = mainStore(); // 直接解構(gòu)不能響應(yīng)式 // const { getterName } = store; // 這樣響應(yīng)式 const getterName = computed(() => store.getterName); // 這樣也能響應(yīng)式 // const { getterName } = storeToRefs(store);
修改state
修改state
的方式也有很多種,可以直接修改、還可以使用$patch
來傳遞對象或方法來修改、還可以通過action
修改。
const updateMainName = async () => { // 直接修改 不建議 // store.name = "demi woman"; // 對象形式修改 // store.$patch({ name: "demi woman" }); // 函數(shù)形式修改 // store.$patch((state) => { // state.name = "demi woman"; // }); // 通過action修改 const result = store.changeName("demi woman"); // action 返回啥就是啥 result等于'success' };
雖然修改方式很多,但是還是在實際開發(fā)中推薦使用action
來修改state
。
使用action
的時候還有一點需要注意。我們知道在vuex
中,action
如果有返回值是會被Promise
包裹resolve
出來,也就是會返回一個Promise
對象。但是在pinia
中,action
返回啥就是啥不會被Promise
包裹resolve
出來。
數(shù)據(jù)持久化
我們知道,vuex
和pinia
本質(zhì)上都是對象,都是臨時存儲,當頁面刷新數(shù)據(jù)都會丟失。
想要刷新不丟失就需要我們手動存儲在localStorage
或sessionStorage
里面。如果不想手動處理,我們也可以使用插件。
vuex
使用vuex-persistedstate
pinia
使用pinia-plugin-persistedstate
具體怎么使用筆者就不再贅述了大家可以自行查看文檔,原理都是一樣的,通過配置將指定數(shù)據(jù)存儲到localStorage
或sessionStorage
里面實現(xiàn)數(shù)據(jù)持久化。
總結(jié)
pinia
有完整的typescript
的支持。不再像使用vuex
需要定義key
、定義state
類型那么麻煩。- 足夠輕量,壓縮后的體積只有
1.6kb
。 - 去除
mutations
,只有state,getters,actions
。跟react-redux
類似,同步異步都在action
里面進行。根簡單清晰。 - 沒有模塊嵌套,只有
store
的概念,store
之間可以自由使用,更好的代碼分割。更簡單易懂。 - 無需手動添加
store
,store
一旦創(chuàng)建便會自動添加,我們只需要在vue
組件直接引用需要的store
使用即可。
到此這篇關(guān)于TypeScript Pinia實戰(zhàn)分享(Vuex和Pinia對比梳理總結(jié))的文章就介紹到這了,更多相關(guān)TypeScript Pinia 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js 獲取本周、上周、本月、上月、本季度、上季度的開始結(jié)束日期
這篇文章主要介紹了js 獲取 本周、上周、本月、上月、本季度、上季度的開始結(jié)束日期,需要的朋友可以參考下2020-02-02javascript實現(xiàn)劃詞標記劃詞搜索功能修正版
javascript實現(xiàn)劃詞標記劃詞搜索功能修正版...2006-12-12JavaScript宏任務(wù)和微任務(wù)區(qū)別介紹
這篇文章主要介紹了JavaScript宏任務(wù)和微任務(wù)區(qū)別介紹,js中的任務(wù),大致分為2類,一類是同步任務(wù),另一類是異步任務(wù)。而異步任務(wù),又分為宏任務(wù)和微任務(wù),這兩個任務(wù)是兩個隊列,所以是先進先出的2022-07-07Boostrap基礎(chǔ)教程之JavaScript插件篇
Boostrap提供了12種JavaScript插件,在本文中給大家介紹了,不知道的朋友可以參考下,本文重點給大家介紹bootstrap基礎(chǔ)之js插件,感興趣的朋友一起學習吧2016-09-09