vue3 基础-Pinia 可能替代 Vuex 的全局数据状态管理
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( ) 问题
原因是 pinia 在 main.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 的全局数据状态管理的更多相关文章
- 使用 react 的 hooks 进行全局的状态管理
使用 react 的 hooks 进行全局的状态管理 React 最新正式版已经支持了 Hooks API,先快速过一下新的 API 和大概的用法. // useState,简单粗暴,setState ...
- computed 和 watch 组合使用,监听数据全局数据状态
我要实现的就是,当接口返回数据时,我在任何组件中都能感知到到该数据的变化,然后根据业务逻辑进行处理.展示. 实现这个效果的方式很多,比如当接口返回数据后,就emit这数据,在另外组件中on接收渲染即可 ...
- 基于 vite 创建 vue3 全家桶项目(vite + vue3 + tsx + pinia)
vite 最近非常火,它是 vue 作者尤大神发布前端构建工具,底层基于 Rollup,无论是启动速度还是热加载速度都非常快.vite 随 vue3 正式版一起发布,刚开始的时候与 vue 绑定在一起 ...
- Vue3 Vite3 状态管理 pinia 基本使用、持久化、在路由守卫中的使用
在<基于 vite 创建 vue3 项目>一文中整合了 pinia,有不少伙伴不知道 pinia 是什么,本文简单介绍 pinia.主要包括三方面: pinia 的基本用法,在<基于 ...
- 23年用vuex进行状态管理out了,都开始用pinia啦!
1 Vue2项目中,Vuex状态管理工具,几乎可以说是必不可少的了.而在Vu3中,尤大大推荐我们使用pinia(拍你啊)进行状态管理,咱得听话,用就完了. 使用之前我们来看一下,使用 pinia 给我 ...
- 实战进阶 Vue3+Axios+pinia
实战进阶 Vue3+Axios+pinia 创建文件utils/request.js import Axios from 'axios'; export const request = Axios.c ...
- Redux/Mobx/Akita/Vuex对比 - 选择更适合低代码场景的状态管理方案
近期准备开发一个数据分析 SDK,定位是作为数据中台向外输出数据分析能力的载体,前端的功能表现类似低代码平台的各种拖拉拽.作为中台能力的载体,SDK 未来很大概率会需要支持多种视图层框架,比如Vue2 ...
- 微信小程序全局状态管理 wxscv
微信小程序中,数据状态不同页面中不能跨页面同步更新,也就是缺失类似vuex,mobx,redux全局的数据状态管理功能. 有些人移植了这些库,但是毕竟不是微信小程序生态的东西. Tencent也发布了 ...
- 状态管理之 Flux、Redux、Vuex、MobX(概念篇)
本文是对 Flux.Redux.Vuex.MobX 几种常用状态管理模式的总结,偏向于概念层面,不涉及过多代码. 状态管理 什么是状态管理? 状态管理就是,把组件之间需要共享的状态抽取出来,遵循特定的 ...
- 2022.07.13 vue3下pinia的简单使用及持久化
使用前说明: 当前demo使用了vue3 + vite + typescript + pinia搭建的简单项目,主要介绍了在单文件组件(sfc)基础上使用pinia的用法,懒得看api的兄弟们,来这瞅 ...
随机推荐
- JavaScript 之 高级程序设计 基础篇 (一)
导读 此篇文章为作者拜读JavaScrpit 第四版(红宝石)的笔记内容.适用于有经验的程序员阅读:作者 java开发出身.在之前前后端不分离的时代 使用esayUI JQuery的时代 经常写 js ...
- autMan奥特曼机器人对接新千寻Pro微信框架详细教程
文件下载 1.安装指定版本微信 https://www.123865.com/s/3Wd9-q13jH 2.最新千寻pro下载 [点此网盘下载] 框架教程 1.安装上面的指定微信版本,跟最新的千寻框架 ...
- JavaGUI - [01] 常见API
题记部分 一.Component 作为基类,提供了如下常用的方法来设置组件的大小.位置.可见性等. setLocation(int x,int y) 设置组件的位置 setSize(int width ...
- Hbase - hbase hbck介绍
原文地址:https://bbs.huaweicloud.com/blogs/353332 HBaseFsck(hbck)是一种命令行工具,可检查hbase集群的region一致性和表完整性的问题,同 ...
- WPF无边框的一个方案(保留默认窗口的拖动、阴影等效果)
使用 WindowStyle="None" AllowsTransparency="True" 的方式达成无边框的效果有很多无法忽视的缺陷,比如失去了拖动效果. ...
- PPT图片搭配
- 【小鼓捣】手搓Verilog-CPU测试全流程自动化
自动化流程思路 1.C++/Python:生成大量包含指定指令的mips程序(A.asm) 2.命令行:导出该mips程序指令的机器码(A.txt) 3.魔改MARS:产生测试所需的IM.DM存入信息 ...
- 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 ...
- 自动旋转ROS小车(rviz+urdf+xacro)(附加python操作键盘控制小车运动)
博客地址:https://www.cnblogs.com/zylyehuo/ 成果图 STEP1 创建工作空间 mkdir -p car_ws/src cd car_ws catkin_make ST ...
- 2025年3月GESP八级真题解析
第一题--上学 题目描述 C 城可以视为由 \(n\) 个结点与 \(m\) 条边组成的无向图.这些结点依次以 \(1,2,-,n\) 标号,边依次以 \(1,2,-,m\) 标号.第 \(i\) 条 ...