• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • getters

    Getter 完全等同于 Store 的 state 的计算值。具备缓存功能。它们可以用defineStore()中的getters属性定义。推荐使用箭头函数,并且它将接收state作为第一个参数:

    export const useStore = defineStore('main', {
      state: () => ({
        count: 0,
      }),
      getters: {
        doubleCount: (state) => state.count * 2,
      },
    })
    

    大多数时候,getter 只会依赖state,但是,他们可能需要使用其他 getter。因此,在定义常规函数时,可以通过this访问整个 store 实例,但是在使用 TypeScript 时,必须定义返回类型,这是为了避免 TypeScript 的已知缺陷。使用箭头函数定义的 getter,不必定义返回类型;不使用this的 getter,也必定义返回类型。

    export const useStore = defineStore('main', {
      state: () => ({
        count: 0,
      }),
      getters: {
        // 自动推断出返回类型是一个 number
        doubleCount(state) {
          return state.count * 2
        },
        // 返回类型**必须**明确设置
        doublePlusOne(): number {
          // 整个 store 的 自动补全和类型标注
          return this.doubleCount + 1
        },
      },
    })
    

    然后你可以直接在 store 实例上访问 getter:

    <template>
      <p>Double count is {{ store.doubleCount }}</p>
    </template>
    
    <script>
    export default {
      setup() {
        const store = useCounterStore()
        return { store }
      },
    }
    </script>
    


    访问其他 getter

    与计算属性一样,您可以组合多个 getter。通过this访问任何其他 getter。即使您不使用 TypeScript,您也可以使用 JSDoc 提示您的 IDE 类型。

    export const useStore = defineStore('main', {
      state: () => ({
        count: 0,
      }),
      getters: {
        // 类型是自动推断出来的,因为我们没有使用 `this`
        doubleCount: (state) => state.count * 2,
        // 这里我们需要自己添加类型(在 JS 中使用 JSDoc)
        // 可以用 this 来引用 getter
        /**
         * 返回 count 的值乘以 2 加 1
         *
         * @returns {number}
         */
        doubleCountPlusOne() {
          // 自动补全
          return this.doubleCount + 1
        },
      },
    })
    


    向 getter 传递参数

    getter 只是幕后的计算属性,所以不可以向它们传递任何参数。不过,你可以从 getter 返回一个函数,该函数可以接受任意参数:

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

    并在组件中使用:

    <script>
    export default {
      setup() {
        const store = useStore()
        return { getUserById: store.getUserById }
      },
    }
    </script>
    
    <template>
      <p>User 2: {{ getUserById(2) }}</p>
    </template>
    

    请注意,当你这样做时,getter 不再缓存,它们只是一个被你调用的函数。不过,你可以在 getter 本身中缓存一些结果,虽然这种做法并不常见,但有证明表明它的性能会更好:

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


    访问其他 Store 的 getter

    要使用其他存储 getter,您可以直接在 getter 内部使用它:

    import { useOtherStore } from './other-store'
    
    export const useStore = defineStore('main', {
      state: () => ({
        // ...
      }),
      getters: {
        otherGetter(state) {
          const otherStore = useOtherStore()
          return state.localData + otherStore.data
        },
      },
    })
    


    在组件 setup()中,使用 getter

    作为 store 的一个属性,你可以直接访问任何 getter(与 state 属性完全一样):

    export default {
      setup() {
        const store = useCounterStore()
    
        store.count = 3
        store.doubleCount // 6
      },
    }
    


    选项 API 组件中,使用 getter

    对于以下示例,您可以假设已创建以下 Store:

    // Example File Path:
    // ./src/stores/counter.js
    
    import { defineStore } from 'pinia'
    
    export const useCounterStore = defineStore('counter', {
      state: () => ({
        count: 0,
      }),
      getters: {
        doubleCount(state) {
          return state.count * 2
        },
      },
    })
    


    在 setup()组件中调用 store

    虽然 Composition API 并不适合所有人,但setup()钩子可以使在 Options API 中使用 Pinia 变得更容易。不需要额外的地图辅助功能!

    import { useCounterStore } from '../stores/counter'
    
    export default {
      setup() {
        const counterStore = useCounterStore()
        return { counterStore }
      },
      computed: {
        quadrupleCounter() {
          return this.counterStore.doubleCount * 2
        },
      },
    }
    


    在无 setup()组件中调用 store

    您可以使用上一部分 state 中使用的mapState()函数来映射到 getter:

    import { mapState } from 'pinia'
    import { useCounterStore } from '../stores/counter'
    
    export default {
      computed: {
        // 允许在组件中访问 this.doubleCount
        // 与从 store.doubleCount 中读取的相同
        ...mapState(useCounterStore, ['doubleCount']),
        // 与上述相同,但将其注册为 this.myOwnName
        ...mapState(useCounterStore, {
          myOwnName: 'doubleCount',
          // 你也可以写一个函数来获得对 store 的访问权
          double: (store) => store.doubleCount,
        }),
      },
    }
    

    上篇:state

    下篇:actions