Pinia(您将喜欢使用的 Vue 存储库)

基本使用

这就是使用 pinia 在 API 方面的样子(请务必查看 Getting Started 以获取完整说明)。 您首先创建一个 Store :

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

export const useCounterStore = defineStore('counter', {
  state: () => {
    return { count: 0 }
  },
  // 也可以定义为
  // state: () => ({ count: 0 })
  actions: {
    increment() {
      this.count++
    },
  },
  getters:{
    
  }
})

然后你在一个组件中 使用 它:

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

export default {
  setup() {
    const counter = useCounterStore()

    counter.count++
    // 带自动补全 ✨
    counter.$patch({ count: counter.count + 1 })
    // 或使用 action 代替
    counter.increment()
  },
}

其他方法查看官方文档

安装

yarn add pinia
# 或者使用 npm
npm install pinia

如果您的应用使用 Vue 2,您还需要安装组合 API:@vue/composition-api。 如果您使用 Nuxt,则应遵循 这些说明

创建一个 pinia(根存储)并将其传递给应用程序:

import { createPinia } from 'pinia'

app.use(createPinia())

如果您使用的是 Vue 2,您还需要安装一个插件并将创建的 pinia 注入应用程序的根目录:

import { createPinia, PiniaVuePlugin } from 'pinia'

  Vue.use(PiniaVuePlugin)
  const pinia = createPinia()

  new Vue({
    el: '#app',
    // 其他选项...
    // ...
    // 注意同一个 `pinia` 实例可以在多个 Vue 应用程序中使用
    // 同一个页面
    pinia,
  })

Store

它托管全局状态。(集中式状态管理)它有点像一个始终存在并且每个人都可以读取和写入的组件。它有三个概念stategettersactions 并且可以安全地假设这些概念等同于组件中的“数据”、“计算”和“方法”。

存储应该包含可以在整个应用程序中访问的数据。

定义一个Store

import { defineStore } from 'pinia'

// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id ,Pinia 使用它来将 store 连接到 devtools。
export const useStore = defineStore('main', {
  state: () => {
    return { count: 0 }
  },
  // 也可以定义为
  // state: () => ({ count: 0 })
  actions: {
    increment() {
      this.count++
    },
  },
  getters:{
    
  }
})

这个 name,也称为 id,是必要的,Pinia 使用它来将 store 连接到 devtools。 将返回的函数命名为 use... 是跨可组合项的约定,以使其符合你的使用习惯。

使用Store

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

export default {
  setup() {
    const store = useStore()

    return {
      // 您可以返回整个 store 实例以在模板中使用它
      store,
    }
  },
}

注意:

Store中得类型不支持解构

const store = useStore()

const { name, doubleCount } = store // ❌ 这不起作用,因为它会破坏响应式

const { name, doubleCount } = storeToRefs(store) // ❎ 通过storeToRefs()解构可以保持响应式

访问Store

const store = useStore()

  store.counter++

重置Store

const store = useStore()

  store.$reset()

组合式API使用

// ./src/stores/counterStore.js

import { defineStore } from 'pinia',

const useCounterStore = defineStore('counterStore', {
  state: () => ({
    counter: 0
  })
})
import { useCounterStore } from '../stores/counterStore'

  export default {
    setup() {
      const counterStore = useCounterStore()

      return { counterStore }
    },
    computed: {
      tripleCounter() {
        return counterStore.counter * 3
      },
    },
  }

选项式API使用

如果您不使用 Composition API,并且使用的是 computed、methods、...,则可以使用 mapState() 帮助器将状态属性映射为只读计算属性:

import { mapState } from 'pinia'
  import { useCounterStore } from '../stores/counterStore'

  export default {
    computed: {
      // 允许访问组件内部的 this.counter
      // 与从 store.counter 读取相同
      ...mapState(useCounterStore, {
        myOwnName: 'counter',
        // 您还可以编写一个访问 store 的函数
        double: store => store.counter * 2,
        // 它可以正常读取“this”,但无法正常写入...
        magicValue(store) {
          return store.someGetter + this.counter + this.double
        },
      }),
    },
  }

如果您希望能够写入这些状态属性(例如,如果您有一个表单),您可以使用 mapWritableState() 代替。 请注意,您不能传递类似于 mapState() 的函数:

import { mapWritableState } from 'pinia'
  import { useCounterStore } from '../stores/counterStore'

  export default {
    computed: {
      // 允许访问组件内的 this.counter 并允许设置它
      // this.counter++
      // 与从 store.counter 读取相同
      ...mapWritableState(useCounterStore, ['counter'])
        // 与上面相同,但将其注册为 this.myOwnName
        ...mapWritableState(useCounterStore, {
          myOwnName: 'counter',
        }),
    },
  }

改变状态

除了直接用 store.counter++ 修改 store,你还可以调用 $patch 方法。 它允许您使用部分“state”对象同时应用多个更改:

store.$patch({
  counter: store.counter + 1,
  name: 'Abalam',
})

但是,使用这种语法应用某些突变非常困难或代价高昂:任何集合修改(例如,从数组中推送、删除、拼接元素)都需要您创建一个新集合。 正因为如此,$patch 方法也接受一个函数来批量修改集合内部分对象的情况:

cartStore.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
  state.hasChanged = true
})

这里的主要区别是$patch() 允许您将批量更改的日志写入开发工具中的一个条目中。 注意两者,state $patch() 的直接更改都出现在 devtools 中,并且可以进行 time travelled(在 Vue 3 中还没有)。

替换state

您可以通过将其 $state 属性设置为新对象来替换 Store 的整个状态:

store.$state = { counter: 666, name: 'Paimon' }

您还可以通过更改 pinia 实例的 state 来替换应用程序的整个状态。 这在 SSR for hydration 期间使用。

pinia.state.value = {}

订阅状态

……

Getters

方法一:箭头函数

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

方法二:常规函数

export const useStore = defineStore('main', {
  state: () => ({
    counter: 0,
  }),
  getters: {
    // 自动将返回类型推断为数字
    doubleCount(state) {
      return state.counter * 2
    },
    // 返回类型必须明确设置
    //我们可以在定义常规函数时通过 this 访问到 整个 store 的实例, 但是需要定义返回类型(在 TypeScript 中)。
    doublePlusOne(): number {
      return this.counter * 2 + 1
    },
  },
})

使用getter

<template>
  <p>Double count is {{ store.doubleCount }}</p>
</template>

<script>
  export default {
    setup() {
      const store = useStore()

      return { store }
    },
  }
</script>

getter可以接受参数

可以访问其他仓库中得getter

与 setup() 一起使用

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

export default {
  setup() {
    const store = useStore()

    store.counter = 3
    store.doubleCount // 6
  },
}

使用选项式API

Getters | Pinia 中文文档

Actions

Actions 相当于组件中的 methods。 它们可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑

actions 可以是异步的

操作可以通过 this 访问 whole store instance

export const useStore = defineStore('main', {
  state: () => ({
    counter: 0,
  }),
  actions: {
    increment() {
      this.counter++
    },
    randomizeCounter() {
      this.counter = Math.round(100 * Math.random())
    },
  },
})
import { mande } from 'mande'

const api = mande('/api/users')

export const useUsers = defineStore('users', {
  state: () => ({
    userData: null,
    // ...
  }),

  actions: {
    async registerUser(login, password) {
      try {
        this.userData = await api.post({ login, password })
        showTooltip(`Welcome back ${this.userData.name}!`)
      } catch (error) {
        showTooltip(error)
        // 让表单组件显示错误
        return error
      }
    },
  },
})

组件中调用actions

const main = useMainStore()
  // Actions 像 methods 一样被调用:
  main.randomizeCounter()

可以访问其他仓库中得getter

与 setup() 一起使用

您可以直接调用任何操作作为 store 的方法:

export default {
  setup() {
    const store = useStore()

    store.randomizeCounter()
  },
}

使用选项API

Actions | Pinia 中文文档

Plugins

……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值