当前位置: 首页 > news >正文

vue3项目使用pinia状态管理器----通俗易懂

1、首先安装pinia

yarn add pinia
# 或使用npm
npm install pinia

2、在项目的src目录下新建store文件夹,然后store目录下新建index.js / index.ts :

我这里是index,js

import { createPinia } from "pinia"// 创建 Pinia 实例
const pinia  = createPinia()// 导出 Pinia 实例以便将其与应用程序实例关联
export default pinia

3、 接着在项目入口文件main.js 或 main.ts 引入并使用:

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router/router'
import store from './store/index'createApp(App).use(router).use(store).mount('#app')

4、然后使用defineStore来定义状态存储模块,一般使用useXXXXXStore 来约定俗成的命名规范, 我这里是user.js:

import { defineStore } from "pinia"export const useUserStore = defineStore({//id 是为了更好地区分模块id: 'user',state: () => ({name: 'Tony',age: 18,count: 0}),getters: {doubleCount: (state) => state.count * 2,},actions: {// 定义操作或异步请求increment() {// 这里访问state的数据不再是state.XXX,而是通过thisthis.count++}}
})

 5、在组件内使用store:

<template><div><h3>我是测试pinia状态存储的组件,我有一个子组件</h3><div>userStore里的state数据:</div><span>姓名: {{ name }}</span>&nbsp;&nbsp; <span>年龄: {{ age }}</span><div><button @click="handleIncre">修改count:</button>count: {{ count }}</div><!-- 直接调用getters的方法 --><div> Double count is: {{ doubleCount }}</div></div>
</template>

js:

<script setup>
import { ref, reactive } from 'vue'
import TestChild1 from './component/TestChild1.vue'
import { useUserStore } from '../../store/user';
import { storeToRefs } from 'pinia'const userStore = useUserStore()
// 通过storeToRefs包裹,解构出来的属性/方法才有响应式
const { name, age, count,  doubleCount} = storeToRefs(userStore)
// console.log('userStore:', userStore.name, userStore.age, userStore.count)
// console.log(name.value, age.value, count.value);// 调用store的actions的increment方法
const handleIncre = () => {userStore.increment()
}</script>

解构store的变量或方法时,如果没有通过storeToRefs包裹,就失去了响应式:

具有响应式:

6、在store中定义异步获取用户信息方法:

6.1 首先新建一个api文件夹定义模拟异步登录获取用户登录信息接口方法:

~~src/api/index

// 模拟异步登录获取用户信息
const loginUser = () => {return new Promise((resolve, reject) => {setTimeout(() => {resolve({name: 'Tony',age: 18})}, 2000)})
}export default {loginUser
}
6.2 在store,user.js中: 

引入api文件,在actions中定义getUserInfo方法,异步查询时,通常都是async和await一起搭配使用的。

import { defineStore } from "pinia"
import API from '../api/index'export const useUserStore = defineStore({//id 是为了更好地区分模块id: 'user',state: () => ({name: 'Tony',age: 18,count: 0,userInfo: {}}),getters: {doubleCount: (state) => state.count * 2,},actions: {// 定义操作或异步请求increment() {// 这里访问state的数据不再是state.XXX,而是通过thisthis.count++},// 在actions中异步获取loginUser的数据async getUserInfo() {this.userInfo = await API.loginUser()console.log('user-info', this.userInfo);}}
})
 6.3 在vue组件中使用:
<!-- 点击---异步登录获取userInfo --><button @click="getUser">异步登录获取userInfo</button><div>userInfo: {{ userInfo }}</div>
// 调用store的actions的getUserInfo方法异步获取用户登录信息
const getUser = () => {userStore.getUserInfo()
}

 

7、此外,在actions中,方法也可以互相调用:

在actions中定义updateUserName方法,通过传入的新名字newName去改变state中的userInfo的name

actions: {// 定义操作或异步请求increment() {// 这里访问state的数据不再是state.XXX,而是通过thisthis.count++},// 在actions中异步获取loginUser的数据async getUserInfo(newName) {this.userInfo = await API.loginUser()console.log('user-info', this.userInfo);this.updateUserName(newName)},updateUserName(name) {if(name) {this.userInfo.name = name}}}

 组件内调用actions的getUserInfo方法时传入newName:

// 调用store的actions的getUserInfo方法异步获取用户登录信息
const newName = ref('小白很白')const getUser = () => {userStore.getUserInfo(newName.value)
}

8、pinia数据持久化

数据持久化之前,刷新页面,pinia的数据会丢失,跟vuex一样,但是pinia做数据持久化是可以通过插件快速完成。

该插件的默认配置如下:

  • 使用 localStorage 进行存储
  • store.$id 作为 storage 默认的 key
  • 使用 JSON.stringify/JSON.parse 进行序列化/反序列化
  • 整个 state 默认将被持久化’
8.1 pnpm安装:
pnpm i pinia-plugin-persistedstate
8.2  将插件添加到 pinia 实例上:

~~store/index:

import { createPinia } from "pinia"
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'// 创建 Pinia 实例
const pinia  = createPinia()
pinia.use(piniaPluginPersistedstate)// 导出 Pinia 实例以便将其与应用程序实例关联
export default pinia
8.3 在对应的store中,将 persist 选项设置为 true 。
import { defineStore } from "pinia"
import API from '../api/index'export const useUserStore = defineStore({//id 是为了更好地区分模块id: 'user',state: () => ({name: 'Tony',age: 18,count: 0,userInfo: {name: '',age: null,info:[]}}),getters: {doubleCount: (state) => state.count * 2,},actions: {// 定义操作或异步请求...// 在actions中异步获取loginUser的数据...},persist: true,
})

现在,你的整个 Store 将使用默认持久化配置保存。

控制台Application 的 localStorage如图:

9、pinia的modules模块化:

9.1 先在store目录下创建modules文件夹,把之前的user.js复制到里面,在创建个counter.js文件: 

9.2  把对应的user.js和counter.js文件的方法和属性修好,导出给外面组件使用:

~user.js:

import { defineStore } from "pinia"
import API from '@/api/index'export const useUserStore = defineStore({//id 是为了更好地区分模块id: 'user',state: () => ({name: 'Tony',age: 18,count: 0,userInfo: {name: '',age: null,info:[]}}),getters: {doubleCount: (state) => state.count * 2,},actions: {// 定义操作或异步请求increment() {// 这里访问state的数据不再是state.XXX,而是通过thisthis.count++},// 在actions中异步获取loginUser的数据async getUserInfo(newName) {this.userInfo = await API.loginUser()console.log('user-info', this.userInfo);this.updateUserName(newName)},updateUserName(name) {if(name) {this.userInfo.name = name}}},persist: true,
})

~counter.js: 

import {  defineStore} from 'pinia'export const useCounterStore = defineStore({id: 'counter',state: () => ({counterCount: 21}),getters: {tenCount: (state) => {return state.counterCount *10}},actions: {decrement() {this.counterCount--}},// 持久化persist: true,
})
9.3 main.js

模块化统一导出

import { createPinia } from "pinia"
// pinia持久化插件
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'// 创建 Pinia 实例
const pinia  = createPinia()
pinia.use(piniaPluginPersistedstate)// 导出 Pinia 实例以便将其与应用程序实例关联
export default pinia// 模块化导出
// import { useUserStore } from '@/store/modules/user.js'
// export { useUserStore }
// import { useCounterStore } from '@/store/modules/counter.js'
// export { useCounterStore }// 模块化统一导出,简写
export * from './modules/user'
export * from './modules/counter'
9.4 在页面中使用

先引入store/index

// import { useUserStore } from '../../store/user';
import { useUserStore, useCounterStore } from '../../store/index'

 通过storeToRefs解构出counterCount, tenCount属性,方法可直接调用

// store的模块化使用,调用useCounterStore的属性/方法
const counterStore = useCounterStore()
const { counterCount, tenCount } = storeToRefs(counterStore)const handleDecre = () => {counterStore.decrement()
}

模板:

<div>################################ start ==> pinia modules模块化 #############################</div><!-- store的模块化使用,调用useCounterStore的counterCount属性 --><div>counterStore的counterCount:{{ counterCount }}</div><button @click="handleDecre">修改counterCount</button><div>10倍counterCount:{{ tenCount }}</div><div>################################ end ==> pinia modules模块化 #############################</div>

 效果:

​​​​​​​

 以上就是pinia的vue3使用。

http://www.lryc.cn/news/355796.html

相关文章:

  • 零基础学Java第二十五天之Lambda表达式
  • VSCode配置Lua5.4安装
  • CI/CD:持续集成/持续部署
  • ComfyUI工作流网站
  • 【机器学习】机器学习基础概念与初步探索
  • 学英语材料:单口喜剧、讲故事、短剧喜剧以及广播剧和播客节目
  • Docker Compose使用
  • 如何优雅的卸载linux上的todesk
  • 【Vue】el-checkbox多选框实现单选效果,选中一个选项则自动取消其他勾选
  • Linux中使用vi编辑器自动缩进4个字符
  • #笔记#笔记#其他
  • gtask笔记
  • 【Linux学习】深入探索进程等待与进程退出码和退出信号
  • Linux:线程
  • 卡到BUG了:删除重发白得积分(以前删除会扣减积分)
  • 轻松拿捏C语言——【字符函数】字符分类函数、字符转换函数
  • 【Rust日报】ratatui版本更新
  • 力扣每日一题 5/28
  • async函数和await函数
  • Redis面试题深度解析
  • Ubuntu 22.04 .NET8 程序 环境安装和运行
  • MetaRTC-ffmpeg arm移植
  • 【乐吾乐3D可视化组态编辑器】模型类型与属性
  • PyQt下拉框QComboBox点击下拉时即更新下拉数据
  • 网上有哪些正规的兼职副业赚钱平台?分享10类正规的网上兼职赚钱平台,让你在家也能赚钱~
  • Spring:JWT
  • Python的selenium爬取
  • Linux--进程间通信(1)(匿名管道)
  • Hive环境搭建
  • 网络编程基础(四)