使用 Pinia 的五个技巧,你知道几个

2023年 11月 23日 47.8k 0

在这篇文章中,想与大家分享使用 Pinia 的五大技巧。

以下是简要总结:

  • 不要创建无用的 getter
  • 在 Option Stores 中使用组合式函数(composables)
  • 对于复杂的组合式函数,使用 Setup Stores
  • 使用 Setup Stores 注入全局变量,如路由器(Router)
  • 如何创建私有状态
  • 1、不要创建无用的 getter

    你并不需要为所有事情使用 getter。在 Vuex 中有一个普遍的误解,认为你应该总是通过 getter 访问状态。

    这是不正确的。

    当你需要从状态中计算出某些东西时,getter 是有用的,例如,如果你有一个待办事项列表,想知道有多少已完成,你可以为此创建一个 getter。

    在生产代码中经常看到过这样的代码:

    export default Vuex.Store({
      state: () => ({ counter: 0 }),
      getters: {
        // 完全无用的 getter
        getCount: state => state.counter,
      },
    })

    这在 Vuex 中只是不必要的样板代码,在 Pinia 中也是如此。你可以直接访问状态:

    const counterStore = useCounterStore()
    counterStore.counter // 0 ✅

    PS:大多数时候你不需要 storeToRefs()(或 toRef())。你可以直接使用 store,Vue 的响应式真的很方便 😄。

    2、在 Option Stores 中使用组合式函数

    你可以在 option stores 中使用一些组合式函数,特别是那些持有状态且可写的组合式函数。例如,你可以使用 @vueuse/core 的 useLocalStorage() 将一些状态存储在浏览器的本地存储中。

    import { useLocalStorage } from '@vueuse/core'
    const useAuthStore = defineStore('auth', {
      state: () => ({
        user: useLocalStorage('pinia/user/login', 'alice'),
      }),
    })

    或者使用 refDebounced() 对 ref 的更改进行防抖处理:

    import { refDebounced } from '@vueuse/core'
    const useSearchStore = defineStore('search', {
      state: () => ({
        user: {
          text: refDebounced(/* ... */),
        },
      }),
    })

    3、在 Setup Stores 中使用复杂的组合式函数

    在 Setup stores 中,你可以使用任何你想要的组合式函数。你可以连接到 websocket、蓝牙处理或甚至游戏手柄!

    import { useWebSocket } from '@vueuse/core'
    export const useServerInfoStore = defineStore('server-info', () => {
      const { status, data, send, open, close } = useWebSocket('ws://websocketurl')
      return {
        status,
        data,
        send,
        open,
        close,
      }
    })

    Pinia 会自动识别哪些是状态、getter 或动作。记住,必须从 setup 函数返回所有状态属性。

    在 setup stores 中使用 inject()

    你可以在 setup stores 中使用 inject() 来访问应用级别提供的变量,如路由器实例:

    import { useRouter } from 'vue-router'
    export const useAuthStore('auth', () => {
      const router = useRouter()
      function logout() {
        // 登出用户
        return router.push('/login')
      }
      return {
        logout
      }
    })

    使用嵌套 Stores 创建私有状态

    setup stores 的一个黄金规则是返回每一个状态片段:

    export const useAuthStore('auth', () => {
      const user = ref(null)
      const token = ref(null)
      // 我们必须返回 user 和 token
      return {
        user,
        token,
      }
    })

    但如果我们想要隐藏一些 store 中的状态怎么办?我们可以创建一个包含私有状态的嵌套 store:

    export const usePrivateAuthState('auth-private', () => {
      const token = ref(null)
      return {
        token,
      }
    })
    export const useAuthStore('auth', () => {
      const user = ref(null)
      const privateState = usePrivateAuthState()
      privateState.token // 仅在此 store 中可访问
      return {
        user,
      }
    })

    在 SSR 中使用仅客户端状态

    服务器端渲染(SSR)是提高应用性能的绝佳方式。然而,与仅客户端应用相比,它带来了一些额外的困难。例如,你无法访问 window、document 或任何其他特定于浏览器的 API,如本地存储。

    在 Option Stores 中,这要求你使用 hydrate 选项告诉 Pinia 某些状态不应在客户端上进行 hydrate:

    import { useLocalStorage } from '@vueuse/core'
    const useAuthStore = defineStore('auth', {
      state: () => ({
        user: useLocalStorage('pinia/user/login', 'alice'),
      }),
      hydrate(state, initialState) {
        state.user = useLocalStorage('pinia/user/login', 'alice')
      },
    })

    在 Setup Stores 中,你可以使用 skipHydrate 辅助函数标记某些状态为仅客户端状态:

    import { defineStore, skipHydrate } from 'pinia'
    const useAuthStore = defineStore('auth', () => {
      const user = skipHydrate(useLocalStorage('pinia/user/login', 'alice'))
      return { user }
    })

    总结

    当然还有许多其他的技巧可以分享,但这些是我认为比较有用的。此外,大多数人对它们并不了解。你有没有发现任何有用的 Pinia 技巧或窍门?

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论