第一次尝试pinia

671 阅读2分钟

pinia入门

The Vue Store that you will enjoy using


[Pinia官网](https://pinia.vuejs.org/)
[github地址](https://github.com/vuejs/pinia)
顺便推下崔大的mini-vue [https://github.com/cuixiaorui/mini-vue](https://github.com/cuixiaorui/mini-vue)

Pinia很早听说了,一直没了解过。最近看到pinia在gitHub被放到了vue里面,官网地址也放倒了vuejs的二级域名下,所以搞一搞。虽然公司用不到V3和pinia,但是不影响我学习。 另外Pinia不光支持V3的compositionApi也支持OptionsApi,并且对TS的支持比vuex好的多,还比vuex轻。

now start!

安装

    yarn add pinia
    # or with npm
    npm install pinia

创建Pinia根仓库

在这里我们通过 createPinia() 创建一个管理全局的状态库,用来保存数据状态以及业务逻辑。

    import { createPinia } from 'pinia'
    app.use(createPinia())`

定义一个仓库

通过 defineStore(id,options) 来从创建一个仓库,形参id必须是唯一的,Pinia会根据这个唯一的id来获取对应的仓库。例如:我们定义一个userStore来存储用户信息。state就是我们仓库中需要存储的状态。

    // userStore.js
    export const useUserStore = defineStore('user',{
        state:()=>{
            return {
                userInfo:{
                    name:'𝓒𝓸𝓬𝓪𝓒𝓸𝓵𝓪',
                    tel:'18100000000',
                    location:'Mars',
                    notes:['胖子','菜鸡'],
                    address:'火星'
                }
    
            }
        }
    })
  
   // user.vue
   import {useUserStore} from "../../store/usertStore"
   const userStore = useUserStore()
   console.log(userStore.userInfo) // 打印state中userInfo的Proxy对象

在Vuex中,我们有getters,Pinia中也有getters方法,定义方式跟vuex相似。下面三种写法都是可以的,但是要注意箭头函数的是不能使用 this 哦!官方更推荐使用箭头函数的。

   export const useUserStore = defineStore('user',{
        state:()=>{ ... },
        getters:{
           // getUser:(state)=>state.userInfo,
           // getUser:function(state){ return state.userInfo }
           getUser:function(){ return this.userInfo }
        }
   }

Pinia中取消了Vuex中的mutations,而是都统一放到了 actions中。也就是说我们以后可以不考虑同步异步,一股脑都放到actions中就可以了。

     // userStore.js
     export const useUserStore = defineStore('user',{
        state:()=>{ ... },
        getters:{ ... },
        actions: {
             getUserInfo() {
                 // 有点懒,用setTimeout来模拟下接口请求
                 return new Promise((resolve, reject) => {
                     setTimeout(() => {
                         resolve(this.userInfo)
                     }, 1000)
                 })
             }
         }
     })
     // user.vue
        async function getUser(){
         // 可以获取返回值
         const info = await userStore.getUserInfo()
        }
        getUser()

另外当我们拥有个store时,我们如何去调用 otherStore 呢? 例如我们有一个note.js,里面到处了noteStore.

    // user.js
    import {useNoteStore} from './notes'        
    const noteStore = useNoteStore()
    // 之后的话我们就可以使用noteStore来调用该仓库中的内容了

最后,在官方文档中提到了一个 $onAction,可以用来观察我们触发调用的store的actions动作。

    export const unsubscribe = ({name, store, args, after, onError}) => {
    // name actions函数的名字
    // store 当前调用的store实例
    // args 入参
    const startTime = Date.now()
    // 一个钩子函数,可以在我们actions结束之前修改我们想要返回的内容
    after((result) => {
        console.log(
            `Finished "${name}" after ${
                Date.now() - startTime
            }ms.\nResult: `, result
        )
        result.name = '可口可乐'
    })


    // onError,官方推荐:将此钩子与错误跟踪服务(如Sentry)结合使用可能是个好主意
    // 此处可以捕获异常,本以为捕获之后我们可以在promise resolve之前去处理报错。但是实际好像不可以。

    onError((error) => {
        console.warn(
            `Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
        )
        return Promise.resolve({
            name:'报错'
        })
    })

    // userStore.js调用
    import {useUserStore} from "../../store/usertStore"
    const userStore = useUserStore()
    userStore.$onAction(unsubscribe)

第一次写技术类文章,很多都是测试之后好多遍最后才敢拿来做例子。在这里先谢谢各位老大的观看,如有错误请指正。