Pinia,确实很好用啊

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 3 天,点击查看活动详情


在 vuex5 的提案中,阐述了这么几点想法:

  • 支持 options api 和 composition api 两种语法创建 Store
  • 不在需要 mutations,有 state,getters 和 actions 就够了
  • 没有嵌套模块,而是用组合的 stores 来代替
  • 对 ts 的支持
  • 很好的支持代码分割

Pinia 最初也只是为了探索下一代 Vuex 可能是什么样子的,也结合了 Vuex 5 核心团队讨论中的许多想法。最终,他们意识到 Pinia 已经实现了在 Vuex 5 中想要的大部分内容,所以将其作为新一代的状态管理器。

与 Vuex 相比,Pinia 的 API 更简洁,也更符合日常的开发习惯,更重要的是,在与 TypeScript 一起使用时有着更为可靠的类型推断。

这里是 Pinia 官网提供的一个在线的 Pinia Demo,大家可以在上面学习。

安装和使用

在项目中使用 yarnnpm 安装好 pinia

yarn add pinia
// or with npm
npm install pinia
复制代码

在 main.js 中,创建一个 pinia 并且挂载到 app 上

// vue3
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).use(createPinia()).mount('#app')


// vue2
import { createPinia, PiniaVuePlugin } from 'pinia'

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

new Vue({
  el: '#app',
  // ...
  pinia,
})
复制代码

Store

我们在定义 store 的时候,需要给其传递一个唯一的 name,相当于 id 的作用,不能和其他的 store 重复。

在 store 的命名方面,我们可以约定好 usexxx,比如 useStore,这也更加符合我们的开发命名习惯。

在组件中,只需要将 store 实例化,就能直接使用其内部的state,actions 和 getters。

// @/store/counter
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => {
    return {
      counter: 0,
      name: 'Eduardo',
      item: [],
    }
  },
})

// 在组件中使用
import { useStore } from '@/stores/counter'

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

    return {
      store,
    }
  },
}
复制代码

这里需要注意的一个点是:不能直接解构store中的值,否则就会失去响应式。我们可以用 storeToRefs来解决这个问题。

const store = useStore()
const { name, counter } = storeToRefs(store)
复制代码

State

修改 State 的 4 种方式

我们可以直接对 state 中的值进行更改,而无需像 vuex 使用 mutations,这种方法适用于单个属性值的变化。

const store = useStore()
store.counter++
复制代码

也可以使用 $patch 来更改 state 中多个属性值

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

在上面的案例中,给 $patch 传的参数是一个对象,还有一种方式是传递函数,这种方式更适用于操作一些数组,对象等复杂一点的属性。

store.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
  state.counter++
})
复制代码

甚至,我们可以通过替换整个 state 来更改状态

store.$state = { counter: 666, name: 'Paimon' }
复制代码

重置 state

如果想将 state 中的属性重置为初始值,再也不需要一个个赋值了, Pinia 中提供了一个 $reset 方法 ,帮助你一键重置。

const store = useStore()

store.$reset()
复制代码

Getters

getters 可以类比计算属性,也可以通过 this 来直接访问store中的其他 gettters。

同样,getters 也具有缓存特性,同一个 getters 就算被调用多次,只要值不变,依旧只执行一次。

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

Action

在 Pinia 中,action 是可以支持同步和异步的,这也是相比于 Vuex 更加好用的一点。

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

  actions: {
    async registerUser(login, password) {
      try {
        this.userData = await api.post({ login, password })
      } catch (error) {
        return error
      }
    },
  },
})
复制代码
const user = useUsers()
user.registerUser('123','123')
复制代码

总结

以上便是 Pinia 的一些用法, Pinia 已经成为默认的状态管理工具,在体验方面也会比Vuex好很多,以后我们用到 Pinia 的地方肯定会越来越多,所以先学为敬。

本文如果有什么不对的地方,还忘各位大佬指正。

猜你喜欢

转载自juejin.im/post/7086035956385447967