23年用vuex进行状态管理out了,都开始用pinia啦!
1 Vue2项目中,Vuex状态管理工具,几乎可以说是必不可少的了。而在Vu3中,尤大大推荐我们使用pinia(拍你啊)进行状态管理,咱得听话,用就完了。
使用之前我们来看一下,使用 pinia 给我们带来哪些好处?
官网介绍:Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态
个人理解:在我看来就是变态版 vuex,听说是为了尊重原作者,所以给改名了叫 pinia(拍你啊)
看看都有啥变态的
- 兼容 vue2、vue3,该说不说这一点 vuex 也支持
- Typescript 支持更友好
- 体积小,1kb 左右,vuex 350k 以上
- 支持插件扩展和服务器端渲染 ssr
- pinia 只有 state、getter、action,抛弃了 Vuex 中的 Mutation。
- mutation 干啥了?vuex 中改/处理变数据源 store 数据的集合(唯一的),必须是同步。
- 我们需要在组件里面调用 dispatch() 方法提交 Actions
- Actions 再通过 commit 方法提交 mutations
- 通过 mutations 里面的方法修改 state(数据)
- 最后 render 到组件里面
- 为啥同步?
- mutation 中如果写异步 Le,commit 在触发 mutation 事件时,异步的回调函数不知道是什么时候执行的,所以在 devtools 中难以追踪变化了
- mutation 干啥了?vuex 中改/处理变数据源 store 数据的集合(唯一的),必须是同步。
- pinia 中 action 支持同步和异步。上面也说了下为啥,还不知道为啥可以搜一下为啥。
- 不用创建各个模块嵌套了。Vuex 中才分不同模块我们需要用到 modules:模块化拆分。在 pinia 中每个 store 都是独立的,互相不影响,没啥事。
用 vue3 demo 讲解 pinia 的使用。
1、搭建项目、安装以来
Vue3 + TS + Vite 项目
参考:Vue3.x 全家桶+vite+TS-搭建 Vue3.x 项目
参考:vue3 学习
1). 创建项目
npm create vite@latest my-vite-app --template vue-ts
2). 安装 pinia 依赖
npm install pinia
3).全局挂在 pinia
我们在 main.ts 主文件中,引入 pinia 的createPinia 方法, 创建根存储,以方便全局调用。
import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
const pinia = createPinia();
const app = createApp(App);
app.use(pinia);
app.mount("#app");
2、搞正事,创建数据仓库 store
应用场景:
. 多个视图依赖于同一状态。
. 来自不同视图的行为需要变更同一状态。
我们需要用到 pinia 的defineStore() 方法,创建一个 store。
defineStore:
- 参数 1:(name) store 的唯一标识 id。也就是 vuex 中 modules:模块化拆分的模块标识
- 参数 2:(options) 相关配置,通俗来讲就是数据,和修改数据的一系列方法 state、getter、action 都在这里
创建后编写代码如下:
/src/store/piniaStore.ts
import { defineStore } from 'pinia'
export const useUsersStore = defineStore('pinia_id', {
})
3、组件中调用 pinia
我们在上一步已经引入了 pinia,并且在 store 文件下创建了一个叫 piniaStore 的 store,接下来让我们看看在组件里如何调用
<script setup lang="ts">
import { useUsersStore } from "../src/store/piniaStore";
const store = useUsersStore();
console.log(store);
</script>
方法很简单一个 useUsersStore 方法搞定,我们看一下打印内容:
$dispose: f $dispose()$id: "pinia_id"
$onAction: f ()
$patch: f $patch(partialStateOrMutator)
$reset: f Sreset()
$subscribe: Ssubscribe(callback, options2 = ) const removeSubscription = addSuoscription(suhotUpdate: (newStore) => f...]
也就这些哈,没啥玩楞。
4、state 属性
我们往 store 里加点数据源 state 吧!
export const useUsersStore = defineStore("pinia_id", {
state: () => {
return {
age: 20,
message:'我来存放公共数据哈!'
sex: "男",
};
},
});
4.1 读取 state 数据
回想一下 vuex 怎么访问的
- 组件中访问 State 中数据的第一种方式:
this.$store.state.全局数据名称
- 组件中访问 State 中数据的第二种方式:
// 从vuex中按需导入mapState函数
import { mapState } from 'vuex'
// 将全局数据 因设为当前组件的计算属性
computed: {
...mapState(['count'])
}
pinia 如何访问呢?
其实我们定义的 state 数据就在 useUsersStore 内,我们自行就可以直接拿到相关数据
<template>
<p>描述:{{ message }}</p>
<p>年龄:{{ age }}</p>
<p>性别:{{ sex }}</p>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useUsersStore } from "../src/store/piniaStore";
const store = useUsersStore();
const message = ref<string>(store.message);
const age = ref<number>(store.age);
const sex = ref<string>(store.sex);
</script>
当然我们也可以用 es6 解构赋值来优化一下
const { message, age, sex } = store;
4.2 多个组件使用 state
我们使用 pinia 更想做到多组件公用统一数据,新建一个 Child.vue 其实用法很简单直接调用使用即可
<template>
<p>我是一个子元素</p>
<p>描述:{{ message }}</p>
<p>年龄:{{ age }}</p>
<p>性别:{{ sex }}</p>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useUsersStore } from "../src/store/piniaStore";
const store = useUsersStore();
const { message, age, sex } = store;
</script>
4.3 修改 state 数据
我们在回想一下 vuex 怎么修改的
- 有人很暴力:直接 this.$store.state.全局数据名称 直接去修改,这种方式很难查看数据是被什么组件修改
- mutation 修改
① 只能通过 mutation 变更 store 数据,不可以直接操作 store 中的数据
② 通过这种方式虽然操作起来繁琐,但是可以集中监控所有数据的变化
看看 pinia
其实如果想要修改修改 store 中的数据,可以直接重新赋值
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<p>年龄:{{ age }}</p>
<button @click="changeAge">年龄不对</button>
</template>
<script setup lang="ts">
import child from './child.vue';
import { useUsersStore } from "../src/store/piniaStore";
const store = useUsersStore();
const { nage,} = store;
const changeAge = () => {
store.age = 26;
console.log(store);
};
</script>
打印可也看出。store 中 age 数据发生了改变,再看看,呦呵,页面没响应。
我们可能去监听 store 数据变化然后刷新页面,但有个更好的方法等着我们
pinia 的storeToRefs 方法把我们的 state 变得具有响应
import { storeToRefs } from 'pinia';
const store = useUsersStore();
const { message, age, sex } = storeToRefs(store);
4.4 初始化/重置 state 数据
store 的$reset()方法为我们提供了 state 数据重置的可能
<button @click="onResetData">重置store</button>
const onResetData = () => {
store.$reset();
};
4.5 store 的$patch 方法批量修改数据
- 全部调整:此方法需要一次性将 state 中的所有字段例举出。
store.$patch({
message: "批量搞事情",
age: 100,
sex: "女",
});
- 部分修改: $patch 方法接收一个回调函数,用来修改部分数据
store.$patch((state) => {
state.items.push({ message: 'shoes', quantity: 1 })
state.hasChanged = true
})
4.6 直接替换 state
store.$state = { counter: 666, name: 'yup' }
5、getter 属性
Getter 用于对 Store 中的数据进行加工处理形成新的数据
- Getter 可以对 Store 中已有的数据加工处理之后形成新的数据,类似 Vue 的计算属性,不会影响到原本的数据
- Store 中的数据发生变化,Getter 的数据也会跟着变化
5.1 添加 getter
export const useUsersStore = defineStore("pinia_id", {
state: () => {
return {
age: 25,
sex: "男",
};
},
getters: {
getAddAge: (state) => {
return state.age + 100;
},
},
});
5.2 调用 getter
- 直接在标签上使用 getter 定义的方法,这种方式是响应式的,可以直接监听到变化,其实 state 标签直接调用也是一样相应的
<template>
<p>新年龄:{{ store.getAddAge }}</p>
<button @click="patchStore">批量修改数据</button>
</template>
<script setup lang="ts">
import { useUsersStore } from "../src/store/piniaStore";
const store = useUsersStore();
// 批量修改数据
const patchStore = () => {
store.$patch({
age: 100,
sex: "女",
});
};
</script>
- getter 中调用其它 getter
这里需要注意一下,不要箭头函数
export const useUsersStore = defineStore("users", {
state: () => {
return {
age: 25,
sex: "男",
};
},
getters: {
getAddAge: (state) => {
return state.age + 100;
},
getNameAndAge(): string {
return this.name + this.getAddAge; // 调用其它getter
},
},
});
5.3 getter 传参
上文提到 getter 与计算属性差不多,想想计算属性怎么传递的呢?
computed:{
getNewName(){
function (str){
return str+this.name
}
}
}
看一下 getter 的
<p>新年龄:{{ store.getAddAge(1100) }}</p>
getters: {
getAddAge: (state) => {
return (num: number) => state.age + num;
},
getNameAndAge(): string {
return this.name + this.getAddAge; // 调用其它getter
},
},
6. actions 属性
对数据进行逻辑加工,完成默写特定的业务逻辑。和 vue 组件代码中的 methods 相似,存放一些处理业务逻辑的方法。
6.1 添加 actions
export const useUsersStore = defineStore("pinia_id", {
state: () => {
return {
message: "",
age: 25,
sex: "男",
name:'王'
};
},
getters: {
getAddAge: (state) => {
return (num: number) => state.age + num;
},
getNameAndAge(): string {
return this.name + this.getAddAge; // 调用其它getter
},
},
actions: {
saveName(name: string) {
this.name = name;
},
},
});
6.2 使用 actions
const saveName = () => {
store.saveName("我用来调用action内的方法");
};
至此文章结束!
23年用vuex进行状态管理out了,都开始用pinia啦!的更多相关文章
- 理解vuex的状态管理模式架构
理解vuex的状态管理模式架构 一: 什么是vuex?官方解释如下:vuex是一个专为vue.js应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证以一种可预测的 ...
- vuex vue状态管理
第一步安装vuex(安装在生产环境) npm install vuex 第二步 src下新建store文件夹 用来专门放状态管理,store文件夹下新建四个js文件 index.js actions ...
- Vuex实现状态管理
Vuex使用总结 1 Vuex简介 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,Vuex抽取了各个组件的共享部分,以全局单例模式进行状态的管理.在原生vue中各个组件之间传值使用的 ...
- vue2.0 仿手机新闻站(三)通过 vuex 进行状态管理
1.创建 store 结构 2.main.js 引入 vuex 3. App.vue 组件使用 vuex <template> <div id="app"&g ...
- Vuex,状态管理模式
对于 Vue 本人目前接触不深,只得浅层分析,Vue 是单向数据流, state,驱动应用的数据源: view,以声明方式将 state 映射到视图: actions,响应在 view 上的用户输入导 ...
- Vuex.js状态管理共享数据 - day8
VScode文件目录: amount.vue代码如下: <template> <div> <!-- <h3>{{ $store.state.count }}& ...
- vuex的状态管理模式
1.store.js Vuex 通过 store 选项,提供了一种机制将状态从根组件“注入”到每一个子组件中(需调用 Vue.use(Vuex)) state:存放数据. mutations:提交状态 ...
- 举个例子去理解vuex(状态管理),通俗理解vuex原理,通过vue例子类比
通俗理解vuex原理---通过vue例子类比 本文主要通过简单的理解来解释下vuex的基本流程,而这也是vuex难点之一. 首先我们先了解下vuex的作用vuex其实是集中的数据管理仓库,相当于数 ...
- 23 Flutter官方推荐的状态管理库provider的使用
加群452892873 下载对应21可文件,运行方法,建好项目,直接替换lib目录,在往pubspec.yaml添加上一下扩展. cupertino_icons: ^ flutter_swiper: ...
- Vuex 模块化实现待办事项的状态管理
前言 在vue里,组件之间的作用域是独立的,父组件跟子组件之间的通讯可以通过prop属性来传参,但是在兄弟组件之间通讯就比较麻烦了.比如A组件要告诉一件事给B组件,那么A就要先告诉他们的爸组件,然后爸 ...
随机推荐
- Transition 初步使用
Transition Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡: 条件渲染 (使用 v-if) 条件展示 (使用 v-show) 动态组件 ...
- 《Effective C++》资源管理章节
Item 13:以对象管理资源 关键的两个想法(这种方式其实在很多地方都可以看出影子,比如managing pool的模型): 1.获得资源后立刻放入管理对象(managing object):以对象 ...
- visualstudio2017 community版本,有点失去信心了,同样两行代码,外观看不出任何区别,但是一个报错
不多废话,先上代码 注意查看函数fputs_FILE,该函数的两行代码fopen_s是同样的,但事实上: 第一条fopen_s执行起来会报错,但是第二条就不会!!! /* 练习:获取用户键盘输入,写入 ...
- 根号分治简单笔记 | P3396 哈希冲突
简要题意 你需要维护一个长度为 \(n\) 的序列 \(v\),支持: A x y 求整个序列中,所有模 \(x\) 为 \(y\) 的下标的元素的值,即: \[\sum_{i=0}^{\lfloor ...
- centos搭建neo4j环境(含java)2021_12
限centos neo4j与java下载: 链接:https://pan.baidu.com/s/1ei15dROGy3OwJfbislxH7g 提取码:8B3A 下载后 1.在linux中建立文 ...
- 在Mac OS上将Node.js连接到XAMPP MySQL服务器一直报错error connecting: Error: connect ECONNREFUSED
以下為通過node.js連線本機mysql資料庫的方法: var mysql = require('mysql'); var connection = mysql.createConnection({ ...
- 新下载了一个框架,然后npm install时候报错npm ERR! Maximum call stack size exceeded
今天遇到这个npm ERR! Maximum call stack size exceeded报错 解决方案如下: 1.更新npm版本 //查看版本 npm -v //更新 npm install - ...
- ASP.NET Core RESTful学习理解
一.了解什么是REST REST是"REpresentational State Transfer"的缩写 ,表述性状态传递: REST是一种软件架构风格,用于构造简单.可靠.高性 ...
- Java基础1-1-1—java基础语法(数据类型及转换)
JAVA基础 1.数据类型及转换 1.1 注释 注释是在程序指定位置添加的说明性信息 简单理解:对代码的一种解释说明,方便我们程序员更好的去阅读代码 // 单行注释 /* 多行注释 */ /**文档注 ...
- 使用字节流丢读取中文的问题-Reader类
使用字节流丢读取中文的问题 当使用字节流读取文本文件时,可能会有一个小问题.就是遇到中文字符时,可能不会显示完整的字符,那是因为一个中文字符可能占用多个字节存储.所以Java提供一些字符流类,以字符为 ...