Vue 进阶系列丨Pinia 的基本使用

e0d9fc6e5ca7278e2983a6897bbe04e5.png

Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!


2013年7月28日,尤雨溪第一次在 GItHub 上为 Vue.js 提交代码;2015年10月26日,Vue.js 1.0.0版本发布;2016年10月1日,Vue.js 2.0发布。

最早的 Vue.js 只做视图层,没有路由, 没有状态管理,也没有官方的构建工具,只有一个库,放到网页里就可以直接用了。

后来,Vue.js 慢慢开始加入了一些官方的辅助工具,比如路由(Router)、状态管理方案(Vuex)和构建工具(Vue-cli)等。此时,Vue.js 的定位是:The Progressive Framework。翻译成中文,就是渐进式框架。

Vue.js2.0 引入了很多特性,比如虚拟 DOM,支持 JSX 和 TypeScript,支持流式服务端渲染,提供了跨平台的能力等。Vue.js 在国内的用户有阿里巴巴、百度、腾讯、新浪、网易、滴滴出行、360、美团等等。

Vue 已是一名前端工程师必备的技能,现在就让我们开始深入学习 Vue.js 内部的核心技术原理吧!


什么是 Pinia

Pinia 是 vue 官方成员在2019年11月重新设计的一个状态存储库,它允许你跨组件/页面共享状态,并且是响应式的,类似于 vuex。现在 vuex 已经更新到4.x版本了,你可以认为 pinia 是作为 vuex@5.x 的一种存在。

与vuex相比,有以下几点不同

  • 没有 mutations,只有 actions。

  • 完美支持TS,相比于vuex,支持 ts 还需要做一些额外的工作,具体内容请移步Vue 进阶系列丨Vuex+TS 代码提示

  • 没有命名空间模块,pinia的store是扁平化结构,你创建的多个store都是相互隔离的,没有嵌套关系。

  • 不再需要注入、导入函数。


  • 创建项目

    npm init vite@latest

    引入 pinia

    npm install pinia
    // main.ts
    import { createPinia } from 'pinia'
    
    
    app.use(createPinia())

    定义一个store

    通过 defineStore 来定义 store,它需要一个唯一的名称,作为第一个参数传入:

    // @/store/firstStore.js
    
    
    import { defineStore } from 'pinia'
    
    
    // 定义并导出容器,第一个参数是容器id,必须唯一,用来将所有的容器
    // 挂载到根容器上
    export const useFirstStore = defineStore('myStore',{
      // 定义state,用来存储状态的
      state:()=>{
        return {}
      },
      // 定义getters,类似于computed,具有缓存g功能
      getters:{},
      // 定义actions,类似于methods,用来修改state,做一些业务逻辑
      actions:{}
    })

    使用刚刚定义的 store:

    import { useFirstStore } from '@/store/firstStore.js'
    
    
    <script setup lang='ts'>
      // 拿到store
      const firstStore = useFirstStore()
    </script>

    state

    定义 state:

    import { defineStore } from 'pinia'
    
    
    // 挂载到根容器上
    export const useFirstStore = defineStore('myStore',{
      // 定义state,用来存储状态的
      state:()=>{
        return {
          count:0,
          arr:[1,2,3]
        }
      },
      // 定义getters,类似于computed,具有缓存g功能
      getters:{},
      // 定义actions,类似于methods,用来修改state,做一些业务逻辑
      actions:{}
    })

    使用 state:

    import { useFirstStore } from '@/store/firstStore.js'
    
    
    <template>
      {{firstStore.count}}
    </template>
    <script setup lang='ts'>
      // 拿到store
      const firstStore = useFirstStore()
      console.log(firstStore.count) // 0
    </script>

    注意,将 store 解构之后,就不是响应式的了,如果想要解构,则需要使用 storeToRefs 函数包裹。

    原因很简单,store 其实就是一个 reactive 对象,当我们解构的时候,就不是响应式数据了,就像 vue3 中一样,需要使用 toRefs 函数。

    import { useFirstStore } from '@/store/firstStore.js'
    import { storeToRefs } from 'pinia
    <template>
      {{count}}
      {{arr}}
    </template>
    <script setup lang='ts'>
      // 拿到store
      const firstStore = useFirstStore()
      // 这样就不是响应式的了,当我们修改count的值的时候,页面不会响应式变化
      const { count,arr } = firstStore  // 错误的做法
      const { count,arr } = storeToRefs(firstStore) // 正确的做法
    </script>

    修改 state:

    import { useFirstStore } from '@/store/firstStore.js'
    
    
    <template>
      {{count}}
    </template>
    <script setup lang='ts'>
      // 拿到store
      const firstStore = useFirstStore()
    
    
      // 方式一,直接修改
      firstStore.count += 1
      // 方式二,如果修改多个数据,可以使用$patch批量修改
      firstStore.$patch({
        count:firstStore.count + 1,
        arr:[...firstStore.arr,4]
      })
      // 方式三: $patch一个函数
      firstStore.$patch(state=>{
        state.count++
        state.arr.push(4)
      })
      // 方式四,调用actions
      firstStore.changeCount()
      // 方式五,替换整个state
      firstStore.$state={
        count:2,
        arr:[1,2,3,4]
      }
      // 方式六:重置state
      firstStore.$reset()
    </script>

    Getters

    定义 getters:

    import { defineStore } from 'pinia'
    
    
    // 挂载到根容器上
    export const useFirstStore = defineStore('myStore',{
      // 定义state,用来存储状态的
      state:()=>{
        return {
          count:0,
          arr:[1,2,3]
        }
      },
      // 定义getters,类似于computed,具有缓存g功能
      getters:{
        // 依赖state
        doubleCount(state){
          return state.count *2
        },
        // 依赖其他的getters, :number 是指定返回值类型为number类型
        otherCount():number{
          return this.doubleCount + 1
        }
      },
      // 定义actions,类似于methods,用来修改state,做一些业务逻辑
      actions:{}
    })

    获取 getters:

    import { useFirstStore } from '@/store/firstStore.js'
    
    
    <template>
      {{firstStore.doubleCount}}
      {{firstStore.otherCount}}
    </template>
    <script setup lang='ts'>
      // 拿到store
      const firstStore = useFirstStore()
      console.log(firstStore.doubleCount)
      console.log(firstStore.otherCount)
    </script>

    Actions

    定义 actions:

    import { defineStore } from 'pinia'
    
    
    // 挂载到根容器上
    export const useFirstStore = defineStore('myStore',{
      // 定义state,用来存储状态的
      state:()=>{
        return {
          count:0,
          arr:[1,2,3]
        }
      },
      // 定义getters,类似于computed,具有缓存g功能
      getters:{
        // 依赖state
        doubleCount(state){
          return state.count *2
        },
        // 依赖其他的getters, :number 是指定返回值类型为number类型
        otherCount():number{
          return this.doubleCount + 1
        }
      },
      // 定义actions,类似于methods,用来修改state,做一些业务逻辑
      actions:{
        // 接收一个参数num,参数的类型是number类型
        addCount(num:number){
          // 通过this获取state中的数据,就像vue2的optionsApi一样
          this.count+=num  
        }
      }
    })

    调用 actions:

    import { useFirstStore } from '@/store/firstStore.js'
    
    
    <template>
      {{firstStore.count}}
    </template>
    <script setup lang='ts'>
      // 拿到store
      const firstStore = useFirstStore()
      firstStore.addCount(10)
    </script>

    至此,pinia 在 vue3 中的简单使用到此就结束了,还是很推荐大家去使用pinia 的,尤其是在TS项目里。现在pinia已经被官方接管了,而且它也是 vue官方成员开发的。这里是 pinia 官网:https://pinia.vuejs.org/ ,大家也可以去官网深入学习。


    Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!

    69ac1f10bbf1e77967d2fd572bf4d096.png

    叶阳辉

    HFun 前端攻城狮

    往期精彩:

  • Vue 进阶系列丨Object 的变化侦测

  • Vue 进阶系列丨Array 的变化侦测

  • Vue 进阶系列丨虚拟DOM和VNode

  • Vue 进阶系列丨Patch 和模板编译

  • Vue 进阶系列丨事件相关的实例方法

  • Vue 进阶系列丨生命周期相关的实例方法

  • Vue 进阶系列丨生命周期

  • Vue 进阶系列丨自定义指令

  • Vue 进阶系列丨最佳实践

  • Vue 进阶系列丨Mixin 混入

  • Vue 进阶系列丨权限控制 addRoute()

  • Vue 进阶系列丨插槽

  • Vue 进阶系列丨npm发布vue组件

  • Vue 进阶系列丨Vuex+TS 代码提示

  • Vue 进阶系列丨自定义指令实现按钮权限功能

  • 来源:HFun TM

    物联沃分享整理
    物联沃-IOTWORD物联网 » Vue 进阶系列丨Pinia 的基本使用

    发表评论