Pinia

Pinia是西班牙语piña(西班牙语中的“菠萝”)单词的形似。

它是一个状态管理的库,用于跨组件、页面进行状态共享(这点和Vuex、Redux一样),同时兼容Vue2、Vue3,也并不要求你使用Composition API;

Pinia开始于大概2019年,最初是作为一个实验,目的为了探索 Vuex 的下一次迭代会是什么样子,所以它结合了 Vuex 5 核心团队讨论中的许多想法,为Vue重新设计状态管理,让它用起来像组合式API(Composition API)。

最终,团队意识到Pinia已经实现了Vuex5中大部分内容,所以最终决定用Pinia来替代Vuex;

与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的仪式,提供了 Composition-API 风格的 API;

最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持;

和Vuex相比,Pinia有很多的优势:

  • 比如mutations 不再存在;
  • 更友好的TypeScript支持,Vuex之前对TS(TypeScript)的支持很不友好;
  • 不再有modules的嵌套结构,
  • 也不再有命名空间的概念。

01. 安装Pinia

  1. npm install pinia

或者:

  1. yarn add pinia

02. 案例入门

目录结构。

与vuex类似,对于pinia的使用,编程习惯上一般创建“stores”文件夹。

也常见取名为“pinia”。

在index.js文件中,创建一个全局的pinia实例。

  1. import {createPinia} from 'pinia'
  2. const pinia = createPinia()
  3. export default pinia

创建好之后,在全局的main.js文件中,使用这个实例。

  1. import {createApp} from 'vue' // 不支持template选项
  2. // import {createApp} from 'vue/dist/vue.esm-browser' // 支持template选项
  3. import App from './App.vue'
  4. import pinia from './stores/index'
  5. createApp(App).use(pinia).mount('#app')

对于业务逻辑,可以根据模块的不同,将需要管理的state抽离,建立单独的文件,比如counter.js。

定义一个Store:

Store 是使用 defineStore() 定义的,

它需要一个唯一名称,作为第一个参数传递;第二个参数为具体的对象。

defineStore返回的是一个函数,在命名上,统一使用useX作为命名方案,这是约定的规范。

使用defineStore定义的store,默认会与创建的全局pinia关联,可以在组件中直接调用,无需其他操作。

  1. import {defineStore} from 'pinia'
  2. // defineStore第一个参数为name,也称为id,是必传参数。唯一标识Store
  3. const useCounter = defineStore('counter',{
  4. state:()=>({
  5. count:99
  6. })
  7. })
  8. export default useCounter

HomeCom.vue

  1. <template>
  2. <h1>Home Page</h1>
  3. <!-- 注意这里与vuex不同 -->
  4. <p>Home中的count计数:{{counterStore.count}}</p>
  5. <button @click="addCount">count+1</button>
  6. </template>
  7. <script setup>
  8. import useCounter from '@/stores/counter'
  9. import {toRefs} from "vue";
  10. import {storeToRefs} from "pinia";
  11. // 执行函数,拿到Store
  12. const counterStore = useCounter()
  13. // pinia支持直接修改state,不必像vuex那样commit一个mutation
  14. function addCount(){
  15. counterStore.count++
  16. }
  17. // 需要注意的是,直接对Store进行解构,会失去响应式
  18. // const {count} = counterStore
  19. // 保留响应式,可以使用vue提供的方法
  20. // const {count} = toRefs(counterStore)
  21. // 保留响应式,pinia也专门提供了一个方法
  22. const {count} = storeToRefs(counterStore)
  23. </script>
  24. <style scoped>
  25. </style>

03. Store

在应用程序中,可以定义任意数量的Store来管理应用程序的状态,

Store有三个核心概念:state、getters、actions;

类似于组件的data、computed、methods;

Store在它被使用之前是不会创建的,使用defineStore函数定义Store时,返回的是一个函数,

调用这个函数,才会创建对应的 store 。

编程习惯:定义Store时,一般以useX的形式。

04. State

对于state,pinia支持直接修改,不同像vuex那样通过mutation。

pinia也支持一次性修改多个state,用 Store.$patch() ,传入一个对象。

对于Store的内部方法,以$开头。

pinia支持直接替换state对象和重置对象。

stores/user.js:

  1. import { defineStore } from 'pinia'
  2. const useUser = defineStore("user", {
  3. state: () => ({
  4. name: "Mark",
  5. age: 18,
  6. score: 100
  7. })
  8. })
  9. export default useUser

Home.vue

  1. <template>
  2. <div class="home">
  3. <h2>Home View</h2>
  4. <h2>name: {{ name }}</h2>
  5. <h2>age: {{ age }}</h2>
  6. <h2>level: {{ score }}</h2>
  7. <button @click="changeState">修改state</button>
  8. <button @click="resetState">重置state</button>
  9. </div>
  10. </template>
  11. <script setup>
  12. import useUser from '@/stores/user'
  13. import { storeToRefs } from 'pinia';
  14. const userStore = useUser()
  15. const { name, age, score } = storeToRefs(userStore)
  16. function changeState() {
  17. // 1.一个个修改状态
  18. // userStore.name = "kobe"
  19. // userStore.age = 20
  20. // userStore.score = 200
  21. // 2.一次性修改多个状态
  22. // userStore.$patch({
  23. // name: "james",
  24. // age: 35
  25. // })
  26. // 3.替换state为新的对象
  27. const oldState = userStore.$state
  28. userStore.$state = {
  29. name: "curry",
  30. score: 200
  31. }
  32. console.log(oldState === userStore.$state) // true。pinia这个功能并不是真的直接替换。
  33. }
  34. function resetState() {
  35. userStore.$reset()
  36. }
  37. </script>

05. Getters

Getters相当于Store的计算属性:

  • 用 defineStore() 中的 getters 属性定义;

  • getters中可以定义接受一个state作为参数的函数;


counter.js:

  1. // 定义关于counter的store
  2. import { defineStore } from 'pinia'
  3. import useUser from './user'
  4. const useCounter = defineStore("counter", {
  5. state: () => ({
  6. count: 99,
  7. subjects: [
  8. { id: 111, name: "语文" },
  9. { id: 112, name: "英语" },
  10. { id: 113, name: "数学" },
  11. ]
  12. }),
  13. getters: {
  14. // 1.基本使用
  15. doubleCount(state) {
  16. return state.count * 2
  17. },
  18. // 2.一个getter引入另外一个getter
  19. doubleCountAddOne() {
  20. // this是store实例
  21. return this.doubleCount + 1
  22. },
  23. // 3.getters也支持返回一个函数
  24. getFriendById(state) {
  25. return function(id) {
  26. for (let i = 0; i < state.subjects.length; i++) {
  27. const subject = state.friends[i]
  28. if (subject.id === id) {
  29. return subject
  30. }
  31. }
  32. }
  33. },
  34. // 4.getters中用到别的store中的数据
  35. showMessage(state) {
  36. // 1.获取user信息
  37. const userStore = useUser()
  38. // 2.获取自己的信息
  39. // 3.拼接信息
  40. return `name:${userStore.name}-count:${state.count}`
  41. }
  42. },
  43. })
  44. export default useCounter

06. Actions

Actions 相当于组件中的 methods。

  • 使用 defineStore() 中的 actions 属性定义。

一般网络请求相关的state管理(异步操作),就使用action完成。

  1. import { defineStore } from 'pinia'
  2. const useHome = defineStore("home", {
  3. state: () => ({
  4. banners: [],
  5. recommends: []
  6. }),
  7. actions: {
  8. async fetchHomeMultidata() {
  9. const res = await fetch("http://123.207.32.32:8000/home/multidata")
  10. const data = await res.json()
  11. this.banners = data.data.banner.list
  12. this.recommends = data.data.recommend.list
  13. // return new Promise(async (resolve, reject) => {
  14. // const res = await fetch("http://123.207.32.32:8000/home/multidata")
  15. // const data = await res.json()
  16. // this.banners = data.data.banner.list
  17. // this.recommends = data.data.recommend.list
  18. // resolve("bbb")
  19. // })
  20. }
  21. }
  22. })
  23. export default useHome

Vue06-Pinia的更多相关文章

  1. 轻量级状态管理库Pinia试吃

      最近连续看了几个GitHub上的开源项目,里面都用到了 Pinia 这个状态管理库,于是研究了一下,发现确实是个好东西!那么,Pinia 的特点: 轻量化 -- Pinia 体积约1KB,十分轻巧 ...

  2. 简单了解一下pinia的结构

    随着 Vue3 的正式转正,Pinia 也渐渐火了起来.所以要更新一下自己的知识树了.这里主要是看看新的状态是什么"形态". 状态的容器还是"reactive" ...

  3. 在Vue3项目中使用pinia代替Vuex进行数据存储

    pinia是一个vue的状态存储库,你可以使用它来存储.共享一些跨组件或者页面的数据,使用起来和vuex非常类似.pina相对Vuex来说,更好的ts支持和代码自动补全功能.本篇随笔介绍pinia的基 ...

  4. vue下一代状态管理Pinia.js 保证你看的明明白白!

    1.pinia的简单介绍 Pinia最初是在2019年11月左右重新设计使用Composition API的 Vue 商店外观的实验. 从那时起,最初的原则相同,但 Pinia 适用于 Vue 2 和 ...

  5. 结合 Vuex 和 Pinia 做一个适合自己的状态管理 nf-state

    一开始学习了一下 Vuex,感觉比较冗余,就自己做了一个轻量级的状态管理. 后来又学习了 Pinia,于是参考 Pinia 改进了一下自己的状态管理. 结合 Vuex 和 Pinia, 保留需要的功能 ...

  6. 一文解析Pinia和Vuex,带你全面理解这两个Vue状态管理模式

    Pinia和Vuex一样都是是vue的全局状态管理器.其实Pinia就是Vuex5,只不过为了尊重原作者的贡献就沿用了这个看起来很甜的名字Pinia. 本文将通过Vue3的形式对两者的不同实现方式进行 ...

  7. pinia 入门及使用

    自上月从上海结束工作回来 在家闲来无事 想写点东西打发时间 也顺便学习学习新的技术.偶然发现了 pinia 据说比vuex好用些 所以便搭了个demo尝试着用了下 感觉确实不错,于是便有了这篇随笔. ...

  8. 基于 vite 创建 vue3 全家桶项目(vite + vue3 + tsx + pinia)

    vite 最近非常火,它是 vue 作者尤大神发布前端构建工具,底层基于 Rollup,无论是启动速度还是热加载速度都非常快.vite 随 vue3 正式版一起发布,刚开始的时候与 vue 绑定在一起 ...

  9. 使用Vite快速构建Vue3+ts+pinia脚手架

    一.前言 vue3的快速更新,很多IT发展快的地区在22开始都已经提上日程,小编所在的青岛好像最近才有点风波.vue3的人才在青岛还是比较稀缺的哈,纯属小编自己的看法,可能小编是个井底之蛙!! vue ...

  10. vue3中pinia的使用总结

    pinia的简介和优势: Pinia是Vue生态里Vuex的代替者,一个全新Vue的状态管理库.在Vue3成为正式版以后,尤雨溪强势推荐的项目就是Pinia.那先来看看Pinia比Vuex好的地方,也 ...

随机推荐

  1. 小议ml.NET机器学习与人机责任划分

    最近,特斯拉宣布召回110万辆车,名义上是纠正单踏板不良习惯,背后原因可能是这些车辆的电子控制单元存在缺陷,可能导致刹车失灵(潮州等交通事故至今没有定论).这个事件引起了人们对于机器学习技术和人机责任 ...

  2. Vue3 路由优化,使页面初次渲染效率翻倍

    3996 条路由? addRoute函数用了大约1s才执行完毕.通过观察,发现居然有3996条路由记录. 可是项目并没有这么多的页面啊~ 重复路由 let routes: Array<Route ...

  3. Docker数据持久化与数据共享

    上篇文章的最后我们使用Docker部署了一个纯前端项目,但还有一个很重要的问题就是容器中产生的数据(比如log文件),容器一旦被删除,容器内的所有数据也就没有了,为了避免这个问题我们可以将数据存储到容 ...

  4. Hugging News #0821: 新的里程碑:一百万个代码仓库!

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  5. CentOS 内网YUM源配置使用

    YUM介绍 yum,是Yellow dog Updater, Modified 的简称,是杜克大学为了提高RPM 软件包安装性而开发的一种软件包管理器.起初是由yellow dog 这一发行版的开发者 ...

  6. 数据可视化【原创】vue+arcgis+threejs 实现海量建筑物房屋渲染,性能优化

    本文适合对vue,arcgis4.x,threejs,ES6较熟悉的人群食用. 先报备一下版本号 "vue": "^2.6.11" "@arcgis/ ...

  7. 485modbus转profinet网关连接威纶通与三菱变频器modbus通讯

    485modbus转profinet网关连三菱变频器modbus通讯触摸屏监控 本案例介绍了如何通过485modbus转profinet网关连接威纶通与三菱变频器进行modbus通讯.485modbu ...

  8. Python 列表操作指南1

    Python 列表 mylist = ["apple", "banana", "cherry"] 列表用于在单个变量中存储多个项目.列表是 ...

  9. MySQL快速导入千万条数据(2)

    目录 一.导入前1000万条数据 二.导入前2000万条数据 三.导入后面的1000万条数据 四.建索引 五.总结 接上文,继续测试3000万条记录快速导入数据库. 一.导入前1000万条数据 清库. ...

  10. [WUSTCTF 2020]朴实无华

    打开网页,就显示一个Hack me ,查看源码也是啥也没有,就用御剑扫一下 发现存在robots.txt文件 根据提示,打开/fAke_f1agggg.php 还真就一个错误的flag 仔细看了看,居 ...