Vue生态的新成员Pinia的详细介绍

目录
  • 安装和配置
  • Store核心
  • State
  • Getters
  • Actions
  • Vue Devtools
  • 最后
  • 结论
  • 参考文献

Pinia是Vue应用程序的状态管理方案,是Vuex核心团队成员开发。感觉更像是常规的旧 javascript 导入模块,实现了很多Vuex5的提案。

Pinia同时支持Vue2和Vue3,不过下面展示的例子都是使用Vue3,Pinia的版本是Pinia@2.0.9。

Vue2和Vue3使用的Pinia版本有一点不同,因此请查看官方Pinia 文档以获取更多信息。

安装和配置

可以使用npm或者yarn安装Pinia

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

安装完毕后,找到Vue应用程序的文件 main.js (vue-cli初始化的项目,一般都命名为main.js)。从Pinia的npm包中导入createPinia,然后使用Vue的use方法作为插件使用

//main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'

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

接下来,我们去创建一个 store

Store核心

Pinia的Store不同于Vuex的Store。使用Vuex的时候,整个应用程序只有一个主要Store(虽然你可以拆成不同的模块,但是还是一个主存储出口)。然而,今天的主角Pinia则是开箱即用的模块化设计,不在需要一个主要的Store,可以创建不同的Store。例如,我们可以创建一个登录用户Store。

// store/loggedInUser.js
import { defineStore } from 'pinia'

export const useLoggedInUserStore = defineStore({
// id 是必填的,并且所有 Store 中唯一。因为Pinia会将它在devtools显示
  id: 'loggedInUser',
  state () {
    return {
      name: '太凉',
      age: 18,
      email: 'fake@email.com'
    }
  },
  getters: {},
  actions: {}
})

上面我们创建了一个登录用户Store,接下来我们可以直接在组件中引用,然后在setup函数中调用useLoggedInUserStore

<template>
  <div>PiniaApage</div>
  <div>姓名:{{user.name}}</div>
  <div>年龄:{{user.age}}</div>
</template>

<script>
import { useLoggedInUserStore } from '@/store/loggedInUser.js'
export default {
  name: 'PiniaDemoPage1',
  setup () {
    const user = useLoggedInUserStore()
    return {
      user
    }
  }
}
</script>

这与 Vuex 有很大不同,Vuex 的Store  会自动挂载到 当前Vue的实例,可以通过this.$store的方式调用。然而,Pania 方式也让开发人员 更清楚Store来自哪里,因为它是标准的 Javascript 模块导入,可以看到是从哪个文件导入的。

假如,你不用  Composition API的方式,你仍然可以借助一些辅助函数使用Pinia,下面将会详细说,这里先提一嘴。

State

我们将 Store 中的 state 属性设置为一个函数,该函数返回一个包含不同状态值的对象。这与我们在组件中定义data的方式非常相似。事实上,唯一的区别是属性名称:状态与数据

import { defineStore } from 'pinia'
export const useLoggedInUserStore = defineStore({
// id 是必填的,并且所有 Store 中唯一。因为Pinia会将它在devtools显示
  id: 'loggedInUser',
  state () {
    return {
      name: '太凉',
      age: 18,
      email: 'fake@email.com'
    }
  },
  getters: {},
  actions: {}
})

现在,为了从组件中访问 loginUserStore 的状态,我们只需要引用我们需要的Store,这种方式非常优雅。完全不需要像Vuex那样从嵌套对象中找到我们需要的Store。

<template>
  <div>PiniaApage</div>
  <div>姓名:{{user.name}}</div>
  <div>年龄:{{user.age}}</div>
</template>

<script>
import { useLoggedInUserStore } from '@/store/loggedInUser.js'
export default {
  name: 'PiniaDemoPage1',
  setup () {
    //不用在想以前那个 user.state.name的方式获取了
    const user = useLoggedInUserStore()
    return {
      user
    }
  }
}
</script>

警告,不能结构user,因为那样会失去响应式。下面的方式是错误的。

 const {name, email} = useLoggedInUserStore()

如果你使用的不是Composition API的方式,而是Option API的方式。可以通过Pinia的mapState函数获取 State数据。Pinia的mapState函数 和Vuex的mapState虽然名字相同,但是使用方式完全不同。

Pinia的mapState函数的第一个参数是必须是之前创建的Store,第二个参数是Store中的state的属性值。看代码

//PageComponent.vue
<template>
  <h1>你好, 我是 {{name}},我来自地球</h1>
  <h2>联系邮箱:{{email}}</h2>
</template>
<script>
import {mapState} from 'pinia'
export default{
  computed:{
    ...mapState(useLoggedInUserStore, ['name','email'])
  }
}
</script>

总结:

  • 定义Pinia的state,和组件的data的方式是一样
  • 需要在组件间中手动导入我们需要的Store模块,这样做的好处是明确知道数据的来源,更符合标准的 Javascript

Getters

Pinia中的getters和Vuex中的getters 的作用是相同的,都是作为组件的计算属性(computed)。
创建getters的方式有两种,一种是通过this关键字,一种是通过state具体看代码

//store/usePostsStore.js
import { defineStore } from 'pinia'

export const usePostsStore = defineStore({
  id: 'PostsStore',
  state: ()=>({ posts: ['post 1', 'post 2', 'post 3', 'post 4'] }),
  getters:{

    // 传统函数方式
    postsCount: function(){
      return this.posts.length
    },
    // 传统函数简写方式
    postsCount2(){
      return this.posts.length
    },
    // 箭头函数
    postsCount3:(state)=>state.posts.length,

    //  不能用箭头函数+this的方式,这种方式this指向不对
    // postsCount: ()=> this.posts.length
  }
})

接下来看Composition API方式的组件中如何使用创建的getters,其实用法和state相同。看代码

<template>
  <div>PiniaBpage</div>
  <div> 总数:{{postsStore.postsCount}}</div>
</template>

<script>
import { usePostsStore } from '@/store/usePostsStore.js'
export default {
  name: 'PiniaBpage',
  setup () {
    const postsStore = usePostsStore()
    return {
      postsStore
    }
  }
}
</script>

如果是Option API 的组件,不能像Vuex那样通过mapGetters辅助函数获取。因为Pinia没有mapGetters辅助函数,Pinia中消费getters还是借助 mapState辅助函数

<template>
  <div> 总数:{{postsCount}}</div>
</template>

<script>
import { mapState } from 'pinia'
import { usePostsStore } from "@/store/PostsStore";

export default {
  computed:{
    ...mapState(usePostsStore, ['postsCount'])
  }
};
</script>

Actions

Pinia不同于Vuex,Pinia提供了单一的方式更改state的值,在Pinia中没有mutations,只有action方式。先来看一下Pinia的action怎么用吧。上代码

  • 直接通过this找到对应的state修改
  • 通过.$patch 函数方法
  • 通过.$patch 对象方法
import { defineStore } from 'pinia'

export const usePostsStore = defineStore({
  id: 'PostsStore',
  state: () => ({
    posts: ['post 1', 'post 2', 'post 3', 'post 4'],
    user: { postsCount: 2 },
    age:18,
    errors: []
  }),
  getters: {
    postsCount: function () {
      return this.posts.length
    },
    postsCount2 () {
      return this.posts.length
    },
    // 箭头函数
    postsCount3: (state) => state.posts.length
  },
  actions: {
    insertPost () {
      //方式1:直接通过this找到对应的state修改
      this.posts.push(`post_${Date.now()}`)
      this.user.postsCount++
    },
    removePost () {
      //方式2:通过.$patch 函数方法
      this.$patch((state) => {
        state.posts.shift()
        state.user.postsCount++
      })
      
      //通过.$patch 对象方法
      this.$patch({
        age:30
      });
    }
  }
})

以上展示了三种更改Pinia的State方式。

如果是 Composition API使用方式

<template>
  <div>PiniaBpage</div>
  <div> 总数:{{postsStore.postsCount}}</div>
  <ul>
    <li
      v-for="item in postsStore.posts"
      :key="item"
    >
      {{item}}
    </li>
  </ul>
  <button @click="handleAdd">新增</button>
  <button @click="handleRemove">删除</button>
  <button @click="handleBeforeAdd">新增到前面</button>
</template>

<script>
import { usePostsStore } from '@/store/usePostsStore.js'
  
export default {
  name: 'PiniaBpage',
  setup () {
    const postsStore = usePostsStore()

    // 新增
    const handleAdd = () => {
      postsStore.insertPost()
    }

    // 删除
    const handleRemove = () => {
      postsStore.removePost()
    }
    // 新增到前面,也可以在这里通过$patch修改,同样这里也可以直接修改
   const  handleBeforeAdd=()=>{
     postsStore.$patch((state) => {
        state.posts.shift()
        state.user.postsCount++
     })
   }
    return {
      postsStore,
      handleAdd,
      handleRemove,
      handleBeforeAdd
    }
  }
}
</script>

如果是 Options API使用方式,需要借助 辅助函数 mapActions

// PostEditorComponent.vue
<template>
  <input type="text" v-model="post" />
  <button @click="insertPost(post)">保存</button>
</template>
<script>
import {mapActions} from 'pinia'
import { usePostsStore } from '@/store/PostsStore';
export default{
  data(){
    return { post: '' }
  }, 
  methods:{
    ...mapActions(usePostsStore, ['insertPost'])
  }
}
</script>

其实Pinia的action使用非常灵活

  • 可以在组件或者其他actions里面调用
  • 可以在其他的Store的actions里面调用
import { useAuthStore } from './auth-store'

export const useSettingsStore = defineStore('settings', {
  state: () => ({
    // ...
  }),
  actions: {
    async fetchUserPreferences(preferences) {
      const auth = useAuthStore()
      if (auth.isAuthenticated) {
        this.preferences = await fetchPreferences()
      } else {
        throw new Error('User must be authenticated')
      }
    },
  },
})
  • 支持同步和异步
  • 可以支持灵活的参数
  • ...............

Vue Devtools

在 Vue 2 中,Pania 支持在 Vuex 选项卡中查看状态,甚至可以看到时间轨迹。时间轨迹的标签几乎没有在 Vuex 中使用时那么好。
至于 Vue 3,Pania 仅支持在 devtools 中查看状态,不支持时间轨迹功能。然而,这实际上比 Vuex 为 Vue 3 提供的要多,因为它在最新的开发工具中根本不支持。

最后

快速回顾一下 Pinia 最显着的功能,以帮助你去快速了解Pinia,并应用于项目中

  • 由 Vue.js 核心团队成员维护
  • 感觉更像是常规的旧 javascript 导入模块,将操作为方法调用,直接在store上访问状态等。
  • 不再mutations
  • 与 Vue Devtools 集成

结论

Pinia虽然是Vue生态的新成员,但是事实证明Pinia是最优前途的状态管理解决方案,具有直观的API,模块化,清晰导入来源。

参考文献

Pinia, an Alternative Vue.js Store
官网

到此这篇关于Vue生态的新成员Pinia的详细介绍的文章就介绍到这了,更多相关Vue Pinia内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue3中vuex与pinia的踩坑笔记记录

    目录 介绍 安装使用 简单对比写法差异与共同点 Vuex 和 Pinia 的优缺点 何时使用Pinia,何时使用Vuex 总结 介绍 Pinia 是 Vue.js 的轻量级状态管理库,最近很受欢迎.它使用 Vue 3 中的新反应系统来构建一个直观且完全类型化的状态管理库. Pinia的成功可以归功于其管理存储数据的独特功能(可扩展性.存储模块组织.状态变化分组.多存储创建等). 另一方面,Vuex也是为Vue框架建立的一个流行的状态管理库,它也是Vue核心团队推荐的状态管理库.Vuex高度关注应

  • Vue状态管理之使用Pinia代替Vuex

    目录 1.Pinia是什么 2.Pinia简单上手 3.使用体验 1.Pinia是什么 Pinia是一个vue的状态管理方案,是vuex团队成员开发,实现了很多vuex5的提案,更加地轻量化且有devtools的支持 vuex4一直被人诟病对于typescript的支持不良好,vuex5也迟迟未来 所以有了pinia的出现 相较于vuex: pinia无需创建复杂的包装器来支持typescript,对于typescript类型判断是天然支持的,享受ide带来的自动补全,减少开发的心智负担,减少v

  • Vue生态的新成员Pinia的详细介绍

    目录 安装和配置 Store核心 State Getters Actions Vue Devtools 最后 结论 参考文献 Pinia是Vue应用程序的状态管理方案,是Vuex核心团队成员开发.感觉更像是常规的旧 javascript 导入模块,实现了很多Vuex5的提案. Pinia同时支持Vue2和Vue3,不过下面展示的例子都是使用Vue3,Pinia的版本是Pinia@2.0.9. Vue2和Vue3使用的Pinia版本有一点不同,因此请查看官方Pinia 文档以获取更多信息. 安装和

  • vue.js实例对象+组件树的详细介绍

    vue的实例对象 首先用js的new关键字实例化一个vue el: vue组件或对象装载在页面的位置,可通过id或class或标签名 template: 装载的内容.HTML代码/包含指令或者其他组件的HTML片段,template将是我们使用的模板 **data:** 数据通过data引入到组件中 在组件中的data要以函数的形式返回数据,当不同的界面用了同一个组件时,才不会以为一个组件的值发生改变而改变其他页面的内容. {{ }} 双括号语法里面放入数据的变量 组件注册语法糖 全局组件 A方

  • C++通信新特性协程详细介绍

    目录 一.关于协程 二.协程的好处 三.协程得用法 四.与线程的区别 五.协程示例 一.关于协程 从 1.54.0 版本开始,Boost.Asio 支持协程.虽然您可以直接使用 Boost.Coroutine,但 Boost.Asio 中对协程的显式支持使得使用它们变得更加容易. 协程让您创建一个反映实际程序逻辑的结构.异步操作不会拆分函数,因为没有处理程序来定义异步操作完成时应该发生什么.程序可以使用顺序结构,而不是让处理程序相互调用. 二.协程的好处 考虑多任务协作的场景. 如果是线程的并发

  • c# 类和成员的修饰详细介绍

    基本概念: 一.类是对于业务处理对象的封装, 包括状态和行为的封装. 二.类的成员种类: 1.常量: 数据值恒定不变的一个符号 2.字段: 字段表示一个只读或者可读写的数据值. 通常用字段来标识一个类或者类产生对象的某种状态, 在实践中,通常将字段标识为private, 避免从类/对象外破坏类/对象的状态. 3.实例构造器(Constructor):将新对象的实例字段初始化为良好初始状态的一种特殊方法. 4.类型构造器,也就是静态的Constructor, 用来初始化类的静态字段. 5.方法:一

  • Java 8新特性方法引用详细介绍

    Java 8新特性方法引用 对于引用来说我们一般都是用在对象,而对象引用的特点是:不同的引用对象可以操作同一块内容! Java 8的方法引用定义了四种格式: 引用静态方法     ClassName :: staticMethodName 引用对象方法:  Object:: methodName 引用特定类型方法: ClassName :: methodName 引用构造方法: ClassName  :: new  静态方法引用示例 /** * 静态方法引用 * @param <P> 引用方法

  • vue store之状态管理模式的详细介绍

    状态管理 一.状态管理(vuex)简介 uex是专为vue.js应用程序开发的状态管理模式.它采用集中存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.vuex也集成刀vue的官方调试工具devtools extension,提供了诸如零配置的time-travel调试.状态快照导入导出等高级调试功能. Vuex 的思想 当我们在页面上点击一个按钮,它会处发(dispatch)一个action, action 随后会执行(commit)一个mutation, mut

  • Vue替代vuex的存储库Pinia详细介绍

    目录 前言 Pinia介绍 1. 创建一个Pinia store 2. 访问State 3. Pinia修改数据的四种方法 4. 重置State 5. 替换state 6. 订阅状态 7. Getters 与vuex比较 Pinia的优点 前言 vue3已经发布很长一段时间了,vue官网也已经默认访问vue3的文档了.因此打算系系统统仔仔细细的学习一波 使用官方提供的脚手架工具新建一个vue3项目会发现,官方已将pinia作为默认的状态存储库提供在安装选项中了. vuex的仓库中官方也有这么一段

  • Vue状态管理库Pinia详细介绍

    目录 什么是 Pinia 如何使用 Pinia 认识 Store 定义一个store 使用 store 操作 State Getters 1. 认识和定义 Getters 2. 访问 Getters 认识和定义 Action 什么是 Pinia Pinia (西班牙语中的菠萝),本质上依然是一个状态管理的库,用于跨组件.页面进行状态共享. pinia 与 vuex 的区别: 更友好的TypeScript支持,Vuex之前对TS的支持很不友好 与 Vuex 相比,Pinia 提供了一个更简单的 A

  • Vue.js状态管理之Pinia与Vuex详解

    目录 前言 Pinia 和 Vuex 简介 什么是Pinia? 什么是 Vuex? Pinia 的特点 模块化设计 完整的开发工具支持 Pinia 很直观 Pinia 是可扩展的 TypeScript 支持 Pinia 轻量的 Vuex的特点 模块 开发工具支持 热重载 TypeScript 支持 Pinia和Vuex的代码对比 Pinia 和 Vuex 的优缺点 Pinia 的优点 Pinia 的缺点 Vuex 的优点 Vuex 的缺点 我应该使用哪个:Pinia 还是 Vuex? 结论 前言

  • 使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一)

    1. 根据官方指引,构建项目框架 # 安装vue $ cnpm install vue@2.1.6 # 全局安装 vue-cli $ cnpm install --global vue-cli # 创建一个基于 webpack 模板的新项目my-project $ vue init webpack my-project # 进入项目目录 $ cd my-project # 安装依赖,走你 $ cnpm install # 运行项目 $ cnpm run dev 2. 运行项目之后,会看到以下界面

随机推荐