Pinia 初体验

Pinia.js是由Vue.js团队核心成员开发的新一代状态管理器,使用Composition Api进行重新设计的,也被视为下一代Vuex。

Pinia是一个Vue的状态管理库,允许跨组件、跨页面进行全局共享状态,也由于其设计的简洁性、和对typescript的良好支持,取代Vuex指日可待。

或许,你在想在vue3中Composition API完全可以使用响应式变量进行全局共享状态,为什么还需要Pinia呢?其实你忽略的一点,你这样做在单页面进行应用是完全可以的,但是如果页面时服务端进行渲染呈现可能就有问题了.

安装

npm install pinia

引入到项目

在 main.js 中只需要调用createPinia()方法将pinia实例化,然后挂载到vue实例上就可以了.

import { createApp } from 'vue'
import App from './App.vue' import { createPinia } from 'pinia' const app = createApp(App) const pinia = createPinia()
app.use(pinia) app.mount('#app')

下一步就应该去创建我们的数据仓库store了,store中存储的是我们需要共享的数据.

创建store需要调用pinia中的defineStore方法,该方法接受两个参数,第一个参数是store的唯一 id,第二个参数是store的配置属性.

defineStore方法配置store属性时,有两种写法,一种是Option 对象形式,一种是Setup 函数形式。

对于 Option 的方式和 Vuex 是一样的, 区别在于, 取消了 Mutations 而让 Actions 同时能进行同步和异步的操作, 这很方便.

在 src 目录下创建一个 store / index.js 的文件:

import { defineStore } from 'pinia'

// 模块1
export const useStore = defineStore("store", {
state: () => ({
name: 'youge',
age: 18
}), // 同步 / 异步 都可以写在一起, 这比 Veux 方便多了
actions: {
changeName(name) {
this.name = name
},
aysncChangeName(name) {
setTimeout(() => {
this.name = name
}, 2000)
}
}
}) // 模块2
// export const useStore2 = defineStore("store2", { })

我其实还是更偏向这种 vuex 风格写法的.

当然用 setup 的写法也支持的.

import { ref } from 'vue'
import { defineStore } from 'pinia' // 模块1
export const useStore = defineStore('store2', () => { // 原来的 state 数据直接进行定义即可, 主要要响应式
let name = ref('youge')
let age = ref(18) // 同步/异步任务, 直接定义成普通函数即可
const changeName = (newName) => name.value = newName function aysncChangeName(newName) {
setTimeout(() => {
name.value = newName
}, 2000);
} // 划重点! 这里一定要 return 出去哦
return { name, changeName, aysncChangeName }
}) // 模块2
// export const useStore2 = defineStore("store2", () => { })

则对应的视图, 这里以 setup 的风格:

<template>
<div>
<p>同步获取 store 的 name 为: {{ name }}</p>
<p>异步获取 store 的 name 为: {{ name }}</p>
</div>
<button @click="changeName('jack')">同步修改数据</button>
<button @click="aysncChangeName('jack')">异步修改数据</button>
</template> <script setup>
// import Father from './Father.vue'
import { useStore } from './store'
import { storeToRefs } from 'pinia' const store = useStore() // store 的方法, 直接解构使用就行
const { changeName, aysncChangeName } = store // store 的变量就需要包装一下成响应式了
const { name } = storeToRefs(store) </script>

如果用 setup 的写法呢, 需注意变量结构会丢失响应式, 需要用 pinia 提供的 storeToRefs 包装一下即可.

<template>
<!-- <div>
<Father />
</div> --> <div>
<p>同步获取 store 的 name 为: {{ name }}</p>
<p>异步获取 store 的 name 为: {{ name }}</p>
</div>
<button @click="changeName('jack')">同步修改数据</button>
<button @click="aysncChangeName('jack')">异步修改数据</button>
<button @click="handleClick('jack')">直接修改数据</button>
</template> <script setup>
// import Father from './Father.vue'
import { useStore } from './store'
import { storeToRefs } from 'pinia' const store = useStore()
const { changeName, aysncChangeName } = store
// store 的变量就需要包装一下成响应式了
const { name } = storeToRefs(store) const handleClick = (newName) => store.name = newName </script>

或者直接用对象.属性的方式, 不通过结构也行的, 这样也不会丢失响应式.

<template>
<!-- <div>
<Father />
</div> --> <div>
<p>同步获取 store 的 name 为: {{ store.name }}</p>
<p>异步获取 store 的 name 为: {{ store.name }}</p>
</div>
<!-- 1. 同步 / 异步 修改 -->
<button @click="store.changeName('jack')">同步修改数据</button>
<button @click="store.aysncChangeName('jack')">异步修改数据</button>
<!-- 2. 直接在标签上改 -->
<button @click="handleClick('jack')">直接修改数据</button> </template> <script setup>
import { useStore } from './store' const store = useStore()
const handleClick = (newName) => store.name = newName </script>

子组件调用触发的 getActivePinia( ) 问题

原因是 piniamain.js 中还没有注册好, 便已在其他文件 (组件) 中使用了它, 就会报错了, 方案就是提前注册呀.

首先, 在 App.vue 同级目录下新建一个名为 "pinia.js" 的文件, 当然文件名和位置都是可以任意的, 这里只是建议.

// src/pinix.js

import { createPinia } from "pinia"

const pinia = createPinia()

export default pinia

然后, 在 main.js 进行引用注册 pinia.

// main.js
import { createApp } from 'vue'
import App from './App.vue' import pinia from './pinia' const app = createApp(App) app.use(pinia)
app.mount('#app')

最后, 在需要用到全局 store 的地方分别进行引入 即可.

如父组件 App.vue

<template>
<div>
<p>同步获取 store 的 name 为: {{ store.name }}</p>
<p>异步获取 store 的 name 为: {{ store.name }}</p>
</div>
<!-- 1. 同步 / 异步 修改 -->
<button @click="store.changeName('jack')">同步修改数据</button>
<button @click="store.aysncChangeName('jack')">异步修改数据</button>
<!-- 2. 直接在标签修改 -->
<button @click="handleClick('jack')">直接修改数据</button>
<p>
子组件:
<Child />
</p>
</template> <script setup>
// import Father from './Father.vue'
import Child from './Child.vue'
import { useStore } from './store' import pinia from './pinia'
const store = useStore(pinia) const handleClick = (newName) => store.name = newName </script>

里面的子组件 Child.vue, 注意在 script 标签中一定要加上 setup

<template>
<div>
数据: {{ store.name }}
</div>
</template> <script setup>
import { useStore } from './store'
import pinia from './pinia' const store = useStore(pinia) </script>

页面:

同步获取 store 的 name 为: youge

异步获取 store 的 name 为: youge

(同步修改数据)  (异步修改数据)  (直接修改数据)
子组件:
数据: youge

这真的是, 用 Pinia 感觉就和没有用一样丝滑.

不过这里也只是初步体验, 具体使用还是待考察中.

vue3 基础-Pinia 可能替代 Vuex 的全局数据状态管理的更多相关文章

  1. 使用 react 的 hooks 进行全局的状态管理

    使用 react 的 hooks 进行全局的状态管理 React 最新正式版已经支持了 Hooks API,先快速过一下新的 API 和大概的用法. // useState,简单粗暴,setState ...

  2. computed 和 watch 组合使用,监听数据全局数据状态

    我要实现的就是,当接口返回数据时,我在任何组件中都能感知到到该数据的变化,然后根据业务逻辑进行处理.展示. 实现这个效果的方式很多,比如当接口返回数据后,就emit这数据,在另外组件中on接收渲染即可 ...

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

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

  4. Vue3 Vite3 状态管理 pinia 基本使用、持久化、在路由守卫中的使用

    在<基于 vite 创建 vue3 项目>一文中整合了 pinia,有不少伙伴不知道 pinia 是什么,本文简单介绍 pinia.主要包括三方面: pinia 的基本用法,在<基于 ...

  5. 23年用vuex进行状态管理out了,都开始用pinia啦!

    1 Vue2项目中,Vuex状态管理工具,几乎可以说是必不可少的了.而在Vu3中,尤大大推荐我们使用pinia(拍你啊)进行状态管理,咱得听话,用就完了. 使用之前我们来看一下,使用 pinia 给我 ...

  6. 实战进阶 Vue3+Axios+pinia

    实战进阶 Vue3+Axios+pinia 创建文件utils/request.js import Axios from 'axios'; export const request = Axios.c ...

  7. Redux/Mobx/Akita/Vuex对比 - 选择更适合低代码场景的状态管理方案

    近期准备开发一个数据分析 SDK,定位是作为数据中台向外输出数据分析能力的载体,前端的功能表现类似低代码平台的各种拖拉拽.作为中台能力的载体,SDK 未来很大概率会需要支持多种视图层框架,比如Vue2 ...

  8. 微信小程序全局状态管理 wxscv

    微信小程序中,数据状态不同页面中不能跨页面同步更新,也就是缺失类似vuex,mobx,redux全局的数据状态管理功能. 有些人移植了这些库,但是毕竟不是微信小程序生态的东西. Tencent也发布了 ...

  9. 状态管理之 Flux、Redux、Vuex、MobX(概念篇)

    本文是对 Flux.Redux.Vuex.MobX 几种常用状态管理模式的总结,偏向于概念层面,不涉及过多代码. 状态管理 什么是状态管理? 状态管理就是,把组件之间需要共享的状态抽取出来,遵循特定的 ...

  10. 2022.07.13 vue3下pinia的简单使用及持久化

    使用前说明: 当前demo使用了vue3 + vite + typescript + pinia搭建的简单项目,主要介绍了在单文件组件(sfc)基础上使用pinia的用法,懒得看api的兄弟们,来这瞅 ...

随机推荐

  1. JavaScript 之 高级程序设计 基础篇 (一)

    导读 此篇文章为作者拜读JavaScrpit 第四版(红宝石)的笔记内容.适用于有经验的程序员阅读:作者 java开发出身.在之前前后端不分离的时代 使用esayUI JQuery的时代 经常写 js ...

  2. autMan奥特曼机器人对接新千寻Pro微信框架详细教程

    文件下载 1.安装指定版本微信 https://www.123865.com/s/3Wd9-q13jH 2.最新千寻pro下载 [点此网盘下载] 框架教程 1.安装上面的指定微信版本,跟最新的千寻框架 ...

  3. JavaGUI - [01] 常见API

    题记部分 一.Component 作为基类,提供了如下常用的方法来设置组件的大小.位置.可见性等. setLocation(int x,int y) 设置组件的位置 setSize(int width ...

  4. Hbase - hbase hbck介绍

    原文地址:https://bbs.huaweicloud.com/blogs/353332 HBaseFsck(hbck)是一种命令行工具,可检查hbase集群的region一致性和表完整性的问题,同 ...

  5. WPF无边框的一个方案(保留默认窗口的拖动、阴影等效果)

    使用 WindowStyle="None" AllowsTransparency="True" 的方式达成无边框的效果有很多无法忽视的缺陷,比如失去了拖动效果. ...

  6. PPT图片搭配

  7. 【小鼓捣】手搓Verilog-CPU测试全流程自动化

    自动化流程思路 1.C++/Python:生成大量包含指定指令的mips程序(A.asm) 2.命令行:导出该mips程序指令的机器码(A.txt) 3.魔改MARS:产生测试所需的IM.DM存入信息 ...

  8. How to use the shell, terminal and the advanced tools

    How to use the shell, terminal and the advanced tools Introduction ‍ Why use English instead of Chin ...

  9. 自动旋转ROS小车(rviz+urdf+xacro)(附加python操作键盘控制小车运动)

    博客地址:https://www.cnblogs.com/zylyehuo/ 成果图 STEP1 创建工作空间 mkdir -p car_ws/src cd car_ws catkin_make ST ...

  10. 2025年3月GESP八级真题解析

    第一题--上学 题目描述 C 城可以视为由 \(n\) 个结点与 \(m\) 条边组成的无向图.这些结点依次以 \(1,2,-,n\) 标号,边依次以 \(1,2,-,m\) 标号.第 \(i\) 条 ...