兩分鐘上手 pinia

安裝

官網(wǎng)

yarn add pinia
# or with npm
npm install pinia

初始化 Pinia

import { createPinia } from 'pinia'

const pinia = createPinia()
pinia.use(SomePiniaPlugin) // 給 pinia 裝插件

const app = createApp(App)
app.use(pinia)

這里需要注意時間順序:只有在調(diào)用 app.use(pinia) 之后才能調(diào)用 useXxxStore()

使用 Store

注意

  1. defineStore 接受一個 id姻檀,不同數(shù)據(jù)源的 id 必須是不同的
  2. 不能將 useCounter() 的返回值解構(gòu)芥炭,這會導致數(shù)據(jù)響應式的丟失

寫法一:

更像原先的 vuex

// src/stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counterStore', {
  state: ()=> {
    return {j: 0, k: 0}
  }
})

// Counter.vue
import { useCounterStore } from 'path/to/src/stores/counterStore'

export default {
  setup() {
    const counterStore = useCounterStore()
    // TODO 默認情況下可以直接這么更改,但是不推薦 // https://pinia.vuejs.org/core-concepts/state.html#accessing-the-state
    counterStore.j ++
    
    // 這里在視圖里使用 counterStore.j 和 counterStore.k
    // 但你不能解構(gòu) counterStore氛濒,只能像下面這樣解構(gòu):
    const { j, k } = storeToRefs(counterStore) // 注意:這里會自動忽略 方法 和 非響應式數(shù)據(jù)(Creates an object of references with all the state, getters, and plugin-added state properties of the store. Similar to toRefs() but specifically designed for Pinia stores so methods and non reactive properties are completely ignored.)
    return {
      counterStore, j, k,
    }
  },
}
Store Getters

getters 其實就是 store 的計算屬性集合部服,而且 getter 不能是異步函數(shù)

export const useStore = defineStore('main', {
  state: () => ({
    counter: 0,
  }),
  getters: {
    doubleCount(state) {
      return state.counter * 2
    },
    doublePlusOne() {
      return this.doubleCount + 1 // getter 訪問另一個 getter 或者 state 可以用 this
    },
    getUserById: (state) => { // getter 可以返回一個函數(shù)唆姐,不過這會導致緩存失效
      return (userId) => state.users.find((user) => user.id === userId)
    },
    otherGetter(state) { // 你還可以調(diào)用其他的 store
      const otherStore = useOtherStore()
      return state.localData + otherStore.data
    },
  },
})
// store.doubleCount 和 store.doublePlusOne 就可以直接當做屬性使用了
// store.getUserById(userId) 可以當做函數(shù)使用
Store Actions

action 其實就是 store 的 methods,而且可以是異步函數(shù)

export const useUserStore = defineStore('users', {
  state: () => ({
    userData: null,
  }),
  actions: {
    async getUser(token) {
      this.userData = await api.post({ token })
    },
  },
})
// 然后你就可以使用 userStore.getUser(token) 了

寫法二:

推薦這種廓八,符合Vue3 setup的編程模式奉芦,讓結(jié)構(gòu)更加扁平化

import { ref, computed } from 'vue';
import { defineStore } from 'pinia';

export const useUserStore = defineStore('users', () => {
  const userData= ref({});
  const getUser = async () => {
    userData.value = await api.post({ token })
  }
  
  const userName = computed(() => userData.value.name)

  return { userData, userName, getUser };
});

store.$patch(object | fn)

批量更新

counterStore.$patch(
   { name: 'pinia', age: counterStore.age + 1 } 
)

cartStore.$patch((state) => {
  state.items.push({ name: 'vuex', age: 18 })
  state.hasChanged = true
})

store.$subscribe(fn)

用于監(jiān)聽 state 的整體變化。

cartStore.$subscribe((mutation, state) => {
  // import { MutationType } from 'pinia'
  mutation.type // 'direct' | 'patch object' | 'patch function'
  mutation.storeId  
  mutation.payload // 獲取 $patch 接收到的參數(shù)

  localStorage.setItem('cart', JSON.stringify(state))
})

它有一個很方便的特性是會自動在組件卸載時注銷剧蹂,如果你不想要声功,可以在 $subscribe 第二個參數(shù)處傳入 {detached: true} 選項。

你也可以使用 watch 達到類似的效果:

watch(
  pinia.state,
  (state) => {
    localStorage.setItem('piniaState', JSON.stringify(state))
  },
  { deep: true }
)

store.$onAction()

用于監(jiān)控所有 action 的執(zhí)行情況宠叼。

const unsubscribe = someStore.$onAction(
  ({
    name, // action 的名字
    store, // store === someStore
    args, // action 的實際參數(shù)
    after, // action 成功之后執(zhí)行 after
    onError, // action 失敗之后執(zhí)行 onError
  }) => {
    const startTime = Date.now()
    console.log(`開始執(zhí)行 "${name}" 參數(shù)為 [${args.join(', ')}].`)
    after((result) => {
      console.log(
        `執(zhí)行成功 "${name}" 用時 ${Date.now() - startTime}毫秒\n結(jié)果為:${result}`
      )
    })
    onError((error) => {
      console.warn(
        `執(zhí)行失敗 "${name}" 用時 ${Date.now() - startTime}毫秒\n報錯為:${error}.`
      )
    })
  }
)
// $onAction 會在它所在組件卸載時自動銷毀
// 如果你將 $onAction 的第二個參數(shù)設置為 true先巴,那么你需要自己調(diào)用 unsubscribe 來取消監(jiān)聽。

store.$reset()

你可以使用 counterStore.$reset() 重置 state

store.$state

// 下面兩句代碼都能覆蓋原有 state
store.$state = { counter: 666, name: 'Paimon' }
pinia.state.value = {} // 這句常用在 SSR
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冒冬,一起剝皮案震驚了整個濱河市伸蚯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌简烤,老刑警劉巖朝卒,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異乐埠,居然都是意外死亡抗斤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門丈咐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瑞眼,“玉大人,你說我怎么就攤上這事棵逊∩烁恚” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長徒像。 經(jīng)常有香客問我黍特,道長,這世上最難降的妖魔是什么锯蛀? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任灭衷,我火速辦了婚禮,結(jié)果婚禮上旁涤,老公的妹妹穿的比我還像新娘翔曲。我一直安慰自己,他們只是感情好劈愚,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布瞳遍。 她就那樣靜靜地躺著,像睡著了一般菌羽。 火紅的嫁衣襯著肌膚如雪掠械。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天注祖,我揣著相機與錄音猾蒂,去河邊找鬼。 笑死氓轰,一個胖子當著我的面吹牛婚夫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播署鸡,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼案糙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了靴庆?” 一聲冷哼從身側(cè)響起时捌,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炉抒,沒想到半個月后奢讨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡焰薄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年拿诸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塞茅。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡亩码,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出野瘦,到底是詐尸還是另有隱情描沟,我是刑警寧澤飒泻,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站吏廉,受9級特大地震影響泞遗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜席覆,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一史辙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧娜睛,春花似錦髓霞、人聲如沸卦睹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽结序。三九已至障斋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間徐鹤,已是汗流浹背垃环。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留返敬,地道東北人遂庄。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像劲赠,于是被迫代替她去往敵國和親涛目。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容