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. DexExpress Wpf BackstageItemWithImage

    参考链接: https://docs.devexpress.com/WPF/DevExpress.Xpf.Ribbon.BackstageItemWithImage.GlyphStyle 设置 Bac ...

  2. Hive - [08] 数据仓库物理模型设计

    分区 分区是将表的数据按照某个列的值进行划分和存储的一种方式.通过分区,可以将数据按照特定的维度进行组织,提高查询效率和数据管理的灵活性. 一.分区的优势 提高查询性能:通过分区,可以将数据按照特定的 ...

  3. Linux - 禁ping & 开放访问端口

    适用于Linux操作系统 禁ping 1.编辑 /etc/sysctl.conf 文件,文件末尾增加如下内容后,保存退出. net.ipv4.icmp_echo_ignore_all = 1 2.在命 ...

  4. 机器学习 | 强化学习(8) | 探索与开发(Exploration and Exploitation)

    8-探索与开发(Exploration and Exploitation) 1.导论 探索与开发二难问题 基于决策的决策过程存在以下两种选择 开发:基于目前的学习做最优的决策 探索:获取更多的学习 最 ...

  5. Linux系列:如何调试 malloc 的底层源码

    一:背景 1. 讲故事 上一篇我们聊过 C# 调用 C 的 malloc 代码来演示heap的内存泄露问题,但要想深入研究得必须把 malloc 的实现库 libc.so 给调试起来,大家都知道在Li ...

  6. django4.2 与python 最新对应关系表

  7. Golang 入门 : 变量

    变量 Go语言是静态强类型语言,所以变量是有明确类型的.变量实质上就是在内存中的一小块空间,用来存储特定类型的可变数据.如果没有变量我们的程序只能将数值写死都是静态的数据,无法更改,变量可以让我们进行 ...

  8. linux 上安装portainer.io

    inux 上安装portainer.io    1.portainer.io是什么?    2.安装,运行镜像    3.登陆1.portainer.io是什么?Portainer是一个轻量级的Doc ...

  9. 使用PowerPoint优雅地更改证件照底色

    使用PowerPoint优雅地更改证件照底色 首先我们打开一张空白的演示文稿,并将要修改的证件照进行粘贴.(图片来自窝窝摄影,侵删) 选中图片,点击 格式,再点击 删除背景. 点击标记要保留的区域,对 ...

  10. 获取不到http请求头自定义参数

    对外提供的API,需请求方在http请求头中传app_id(下划线分割) 然后服务端通过request.getHeader("app_id")获取不到对应的参数值 排查原因,是因为 ...