Pinia 中將參數傳遞給 getter

Vuex 3.x 允許我們在 store 中定義 “getter”(可以認爲是 store 的計算屬性)。就像計算屬性一樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被重新計算。

Getter 接受 state 作爲其第一個參數:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

Getter 也可以接受其他 getter 作爲第二個參數:

getters: {
  // ...
  doneTodosCount: (state, getters) => {
    return getters.doneTodos.length
  }
}

在 Pinia 中定義常規函數時通過 this 訪問到整個 store 的實例,可以通過 this 訪問任何其他 getter:

export const useStore = defineStore('main', {
  state: () => ({
    counter: 0,
  }),
  getters: {
    doubleCount: (state) => state.counter * 2,
    doubleCountPlusOne() {
      return this.doubleCount + 1
    },
  },
})

Vuex 4.x 允許你也可以通過讓 getter 返回一個函數,來實現給 getter 傳參。在你對 store 裏的數組進行查詢時非常有用。

getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}

在 Pinia 中將參數傳遞給 getter 也是這樣的,您可以從 getter 返回一個函數以接受任何參數。

export const useStore = defineStore('main', {
  getters: {
    getUserById: (state) => {
      return (userId) => state.users.find((user) => user.id === userId)
    },
  },
})

注意,getter 在通過方法訪問時,每次都會去進行調用,而不會緩存結果。

<template>
  <p>User 2: {{ getUserById(2) }}</p>
</template>

請注意,Pinia 中 store 是一個用 reactive 包裹的對象,這意味着不需要在 getter 之後寫 .value,但是,就像 setup 中的 props 一樣,我們不能對其進行解構:

export default defineComponent({
  setup() {
    const store = useStore()
    // ❌ 這不起作用,因爲它會破壞響應式
    const { name, doubleCount } = store
    name // "eduardo"
    doubleCount // 2
    return {
      // 一直會是 "eduardo"
      name,
      // 一直會是 2
      }
  },
})

爲了從 Store 中提取屬性同時保持其響應式,您需要使用 storeToRefs()。它將爲任何響應式屬性創建 refs。當您僅使用 store 中的狀態但不調用任何操作時,這很有用:

import { storeToRefs } from 'pinia'
export default defineComponent({
  setup() {
    const store = useStore()
    // `name``doubleCount` 是響應式引用
    const { name, doubleCount } = storeToRefs(store)
    return {
      name,
      doubleCount
    }
  },
})
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Am1VZk1x4vOS8qUi5eNX1w