pinia的使用总结


一、定义一个store

  • 安装pinia yarn add pinia
  • 引入pinia
//main.ts
import { createPinia } from 'pinia'
app.use(createPinia())
  • 定义一个store
    defineStore() 需要一个唯一的名称,作为第一个参数传递
import { defineStore } from 'pinia'

// useStore could be anything like useUser, useCart
// the first argument is a unique id of the store across your application
export const useStore = defineStore('main', {
  // other options...
})

  • 使用store
import { useCounterStore } from '@/stores/counter'
const store =useCounterStore()
//获取state 方法一
const doubleValue=computed(() => store.doubleCount),
//获取state 结构state 方法二
const { name, doubleCount } = storeToRefs(store)

//修改state数据 方法一
store.counter++
//修改多个数据 方法二
store.$patch({
  name:"xxx",
  doubleCount+=1
})
//修改多个数据 方法三
store.$patch(state=>{
  state.name='xxx'
  state.doubleCount+=1
  state.arr.push(2)
})
//修改多个数据 方法四
//将操作封装到一个函数里面然后调用即可
store.changeState()

二、核心概念

1.state

定义一个state

import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => {
    return {
     count: 0 as number  //可以指定数据类型
      }
  },   //必须是一个箭头函数否则类型不会推导
  // could also be defined as
  // state: () => ({ count: 0 })
  getters: {
    doubleCount: (state) => state.counter * 2,
  },
  actions: {
    increment() {
      this.count++
    },
  },
})

组件内使用state

import { useCounterStore } from '@/stores/counter'
const store =useCounterStore()
//获取state 方法一
const doubleValue=computed(() => store.doubleCount),
//获取state 结构state 方法二
const { name, doubleCount } = storeToRefs(store)

//修改state数据 方法一
store.counter++
//修改多个数据 方法二
store.$patch({
  name:"xxx",
  doubleCount+=1
})
//修改多个数据 方法三
store.$patch(state=>{
  state.name='xxx'
  state.doubleCount+=1
  state.arr.push(2)
})
//修改多个数据 方法四
//将操作封装到一个函数里面然后调用即可
store.changeState()
//您可以通过调用store 上的方法将状态重置为其初始值:$reset()
store.$reset()

2.getters

接受state参数,鼓励使用箭头函数
定义一个getters

  getters: {
   //方法一 使用state获取数据
    doubleCount: (state) => state.counter * 2,
    },
    //方法二使用this获取数据,类型推导不出来必须手动指定返回值类型
    
    //如果要访问其他的getters必须使用this这种写法
    doublePlusOne(): number {
      // autocompletion and typings for the whole store ✨
      return this.doubleCount + 1
    },

   //方法三 支持payload 返回值为一个函数就可以解决payload的问题
    getUserById (state) {
      return (userId) => state.users.find((user) => user.id === userId)
    },
   //方法四接受其他store里面的getters 
    otherGetter(state) {
      const otherStore = useOtherStore()   //直接使用其他store就可以调用了
      return state.localData + otherStore.data
  },

组件内使用getters

const  doubleCount=computed(()=>{
    return store.doubleCount
}) 

3.action

可以接受一个payload参数
定义一个action

  actions: {
    //支持自定义参数 payload
    increment(num:number) {
      this.count+=num
    },
    //支持使用$patch做批量更新数据
    changeState(){
      this.$patch(state=>{
        state.name='xxx'
        state.doubleCount+=1
        state.arr.push(2)
    })
   },
    //使用其他容器的actions
    async fetchUserPreferences() {
      const auth = useAuthStore()    //直接把其他容器加载进来使用就可以了
      if (auth.isAuthenticated) {
        this.preferences = await fetchPreferences()
      } else {
        throw new Error('User must be authenticated')
      }
    },
  },

组件内使用action

store.increment(10)
store.changeState()

三、函数式写法

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  function increment() {
    count.value++
  }

  return { count, increment }
})

四、插件

Pinia 插件是一个函数,可以选择返回要添加到商店的属性。它需要一个可选参数,一个context:

import { createPinia } from 'pinia'

// add a property named `secret` to every store that is created after this plugin is installed
// this could be in a different file
function SecretPiniaPlugin() {
  return { secret: 'the cake is a lie' }
}

const pinia = createPinia()
// give the plugin to pinia
pinia.use(SecretPiniaPlugin)

// in another file
const store = useStore()
store.secret // 'the cake is a lie'

五、与vuex的区别

  • mutations no longer exist. They were very often perceived as extremely verbose. They initially brought devtools integration but that is no longer an issue. //没有mutation
  • No need to create custom complex wrappers to support TypeScript, everything is typed and the API is designed in a way to leverage TS type inference as much as possible. //很好的支持typescript
    No more magic strings to inject, import the functions, call them, enjoy autocompletion!
  • No need to dynamically add stores, they are all dynamic by default and you won’t even notice. Note you can still manually use a store to register it whenever you want but because it is automatic you don’t need to worry about it.
  • No more nested structuring of modules. You can still nest stores implicitly by importing and using a store inside another but Pinia offers a flat structuring by design while still enabling ways of cross composition among stores. You can even have circular dependencies of stores. //没有module了
  • No namespaced modules. Given the flat architecture of stores, “namespacing” stores is inherent to how they are defined and you could say all stores are namespaced. //没有命名空间

版权声明:本文为weixin_46787337原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。