百科狗-知识改变命运!
--

defineStore - Pinia(状态管理)

是丫丫呀1年前 (2023-11-21)阅读数 26#技术干货
文章标签属性

defineStore

我们得知道 Store 是用defineStore()定义的,它的第一个参数要求是一个独一无二的名字:

import { defineStore } from 'pinia'

// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID
export const useStore = defineStore('main', {
  // 其他配置...
})

这个名字,也被用作 id ,是必须传入的, Pinia 将用它来连接 store 和 devtools。为了养成习惯性的用法,将返回的函数命名为use...是一个符合组合式函数风格的约定。

defineStore()的第二个参数可接受两类值::Setup函数或Options对象。


Option 式

defineStore - Pinia(状态管理)

与 Vue 的 Options API(选项式 API)类似,我们也可以传入一个带有stateactionsgetters属性的Options对象。

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0, name: 'Eduardo' }),
  getters: {
    doubleCount: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++
    },
  },
})

你可以认为state是 Store 的数据(data),getters是 Store 的计算属性(computed),而actions则是 Store 的方法(methods)。

为方便上手使用,Option Store 应尽可能直观简单。


Setup 式

还有另一种可能的语法来定义 Store。与 Vue Composition API 的Setup函数类似,我们可以传入一个函数,该函数定义了一些响应式属性和方法,并且返回一个带有我们想暴露出去的属性和方法的对象。

export const useCounterStore = defineStore('counter', () => {

  const count = ref(0)
  const name = ref('Eduardo')

  const doubleCount = computed(() => count.value * 2) function increment() {
    count.value++
  }

  return { count, name, doubleCount, increment }
})

在Setup式中:ref()成为state属性,computed()变成gettersfunction()变成actions

  • Setup式 Store 比Options式 Store,带来更多的灵活性,因为您可以在 Store 中,创建观察者并自由使用任何可组合的。但是,请记住,使用任何可组合,会得更复杂的 SSR。
  • 与 Vue 的 Composition API 和 Option API一样,选择你觉得最舒服的一个。如果您不确定,请先尝试 Option 式 Store。


使用Store

虽然我们前面定义了一个 store(名称为类似use…Store的格式),但在组件setup()中,调用useStore()之前,store 实例是不会被创建的:

import { useCounterStore } from '@/stores/counter'

export default {
  setup() {
    const store = useCounterStore() return {
      // 为了能在模板中使用它,你可以返回整个 Store 实例
      store,
    }
  },
}

你可以定义任意多的 store,但为了让使用 pinia 的益处最大化(比如允许构建工具自动进行代码分割以及 TypeScript 推断),你应该在不同的文件中去定义 store。

如果你还不会使用 setup 组件,你也可以通过映射辅助函数来使用 Pinia。

一旦 store 被实例化,你可以直接访问在 store 的 state、getters 和 actions 中定义的任何属性。我们将在后续章节继续了解这些细节,目前自动补全将帮助你使用相关属性。


⚠注意,如果这 Store 是一个用reactive包裹的对象,这意味着不需要在getter之后写.value。就像setup()中的props一样,我们不能解构它,因为会丧失响应性:

export default defineComponent({ setup() {
    const store = useCounterStore()
    // ❌ 这将无法生效,因为它破坏了响应性
    // 这与从 `props` 中解构是一样的
    const { name, doubleCount } = store

    name // "Eduardo"
    doubleCount // 0

    setTimeout(() => {
      store.increment()
    }, 1000)

    return {
      // 始终是 "Eduardo"
      name,
      // will always be 0
      doubleCount,
      // will also always be 0
      doubleNumber: store.doubleCount,

      // ✅ 个将是响应式的
      doubleValue: computed(() => store.doubleCount),
    }
  },
})

为了从 Store 中提取属性,同时保持其响应性,您需要使用storeToRefs(),它将为每个响应性属性创建引用。当你只使用 Store 的状态而不调用任何action时,它会非常有用。

⚠注意,您可以直接从 Store 中解构action,因为它们也绑定到 Store 本身:

import { storeToRefs } from 'pinia'

export default defineComponent({
  setup() {
    const store = useCounterStore()
    // `name` and `doubleCount` 都是响应式 refs
    // 这也将为由插件添加的属性创建 refs
    //同时会跳过任何 action 或非响应式(非 ref/响应式)属性
    const { name, doubleCount } = storeToRefs(store)
    // 名为 increment 的 action 可以直接提取
    const { increment } = store

    return {
      name,
      doubleCount,
      increment,
    }
  },
})

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)