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

Vuex和Pinia

1、介绍

什么是store?

Store是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定,换句话说,它承载着全局状态。它有点像一个永远存在的组件,每个组件都可以读取和写入它。

Vuex

Vuex就是专为Vue应用程序开发的store。它用于管理Vue应用中的共享状态,使得多个组件能够方便地访问和修改相同的数据。Vuex的核心概念包含state,mutations,actions,getters等。

Pinia

Pinia是一个专为Vue3设计的Store。它是Vue3响应式API的基础上构建的,旨在提供一种轻量、灵活且直观的状态管理解决方案。与传统的Vuex不同,Pinia不依赖全局对象,而是通过创建独立的store实例来管理状态。State、getter和action是Pinia的三个重要概念。

2、安装

Vuex

yarn add vuex@next  –-save

或者使用npm

npm install vuex@next –save

Pinia

yarn add pinia

或者使用npm

npm install pinia

注意实际项目开发可不要既用vuex又用pinia,除非公司是你家开的

3、创建与使用

Vuex

在自己的项目中src目录下创建一个store目录,再创建一个index.js,在这里我们创建Vuex的store实例。

import { createStore } from ‘vuex’

const store = createStore({

         //需要管理的数据存放在这里

         state(){

   return{

     msg:’hello vuex’,

},

},

//唯一可以同步修改state的地方

mutatons:{

},

//异步修改state,本质还是用过mutations修改

actions:{

},

//类似于vue中的计算属性

getters:{

},

//如果需要vuex管理的数据多的话,可以拆分一个个模块

modules:{

},

})

export default store

在main.js中引入刚刚创建的实例

import { createApp } from ‘vue’

import App from ‘./App.vue’

import store from ‘./store’

createApp(App).use(store).mount(‘#app’)

在App.vue中使用

<template>

         <div>

   {{store.state.msg}}

</div>

</template>

<script setup>

         import { useStore }  from ‘vuex’

         let store = useStore()

</script>

如果页面成功显示hello vuex,恭喜你,已经创建一个vuex store实例

Pinia

同理,在src目录下创建一个store目录,在index.js中创建Pinia的store实例:

import { defineStore } from ‘pinia’

export const store = defineStore(‘store’,{

         state: ()=>{

   return {

     msg:’hello pinia’

}

},

getters:{

},

actions:{

},

})

在main.js中引入创建的pinia实例

import {createApp} from ‘vue’

import App from ‘./App.vue’

import {createPinia } from ‘pinia’

const pinia = createPinia()

createApp.use(pinia).mount(‘#app’)

在App.vue中使用

<template>

         <div>

   {{storeA.msg}}

</div>

</template>

<script setup>

Import {store} from ‘./store’

let storeA = store()

</script>

如果页面成功显示hello pinia,恭喜你Pinia实例创建成功

4、修改状态

在组件中直接修改

<template>

         <div>

         {{store.state.msg}}

</div>

</template>

<script setup>

         import {useStore} from ‘vuex’

let store = useStore()

store.state.msg = ‘hello juejin’ //直接赋值修改

</script>

方法可行,但是这样直接修改会绕过vuex的mutation操作,破坏了单向数据流的概念,vuex还是推荐通过mutations来修改状态,以确保状态的变化可追踪的。

在mutstions中修改

import {createStore} from ‘vuex’

const store = createStore({

         //需要管理的数据存放在这里

         state(){

   return {

            msg:’hello vuex’

}

},

//唯一可以同步修改state的地方

mutations:{

   changeMsg(state,data){

     state.msg = data

}

},

…..

})

export default store

在组件中用commit触发状态变更:

<template>

         <div>{{store.state.msg}}</div>

</tamplate>

<script setup>

import {useStore} from ‘vuex’

const store = createStore({

         state(){

   return {

     msg:’hello vuex’,

}

},

mutations:{

   changeMsg(state,data){

     state.msg = data

}

},

//异步通过mutations修改state

actions:{

   async getMsg({commit},newMsg){

            setTimeout(()=>{

        commit(‘changeMsg’,newMsg)

},100)

}

}

…..

})

export default store

</script>

在组件中使用dispatch进行分发actions

<template>

         <div>

   {{store.state.msg}}

   <!—hello juejin-->

</div>

</template>

<script setup>

         import {useStore} from ‘vuex’

         let store = uesStore()

         store.dispatch(‘getMsg’,’hello juejin’) //dispatch分发

</script>

这里我们在actions中设置了一个一秒的定时器,来模拟异步操作,使得一进入页面,显示的是hello vuex,但一秒后就变成hello juejin了。

下图是vuex的数据流程,简单描述一下:就是组件通过dispatch触发一个Action,Action的处理函数执行一些异步操作,然后提交一个Mutation,Mutation的处理函数修改State,State的变化触发视图更新。

 

Pinia

在组件中直接修改

<template>

         <div>{{}storeA.msg}</div>

</template>

<script setup>

import {store} from ‘./store’

let storeA = store()

storeA.msg = ‘hello juejin’

console.log(storeA.msg)

</script>

使用$.patch方法

使用$patch方法可以修改一个或多个状态

import {defineStore} from ‘pinia’

export const store = defineStore(‘store’,{

         state: () = >{

   return {

     msg:’hello pinia’,

     name:’yangyangyang’

}

},

getters:{},

actions:{}

})

在组件中进行修改

<template>

         <div>

   {{storeA.msg}}

</div>

</template>

<script setup>

         import {store} from ‘.store’;

         let storeA  = store()

         console.log(storeA.msg.name)

         storeA.$patch({

         msg:’hello juejin’,

         name:’miemiemie’

})

console.log(storeA.msg,storeA.name)

</script>

在actions中进行修改

与vuex的actions不同,Pinia中的actions既可以是同步也可以是异步,由于Pinia中没有mutations,所以工作都交给了actions。

import {defineStore} from ‘pinia’

export const store = defineStore(‘store’,{

         state:()=>{

   return {

     msg:’hello pinia’,

     name:’yangyangyang’

}

},

actions:{

   changeMsg(data){

     this.msg = data

}

},

getters:{},

})

直接在组件中调用changeMsg方法,而不用像Vuex一样dispatch进行分发。

<template>

         <div>

{{storeA.msg}}

</div>

</tempkate>

<script setup>

         import {store} from ‘./store’;

         let storeA = store()

         storeA.changeMsg(‘hello juejin’)

</script>

重置state

使用选项式API时,可以通过调用store的$reset()方法将state重置为初始值。

<script setup>

         import {store} from ‘./store’

         let storeA = store()

         storeA.changeMsg(‘hello juejin’)

         console.log(storeA.msg)

         storeA.$reset()

         console.log(storeA.,msg)

</script>

5、模块化

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂是,store对象就有可能变得相当臃肿。为了解决以上问题,对vuex或pinia进行模块化开发至关重要,尤其是对于大型项目。

Vuex允许我们将store拆分成多个模块(module),每个模块都有自己的state、mutation、action和getter

一般项目开发中,我们将每个module单独存放在一个文件中,然后再引入总入口store/index.js中

在src目录下创建modules文件夹,然后创建你的模块文件

模块A

//modules/moduleA.js

const moduleA = {

         state:()=>({

   msg:’hello moduleA’

}),

mutations:{},

actions:{},

getters:{}

}

export default moduleA

模块B

//modules/module.js

const moduleB = {

state: () => ({

msg:'hello moduleB'

}),

mutations: {},

actions: {},

getters: {}

}

export default module

将各模块引入主模块

//store/index.js

import { createStore } from 'vuex';

import moduleA from '../modules/moduleA';

import moduleB from '../modules/moduleB';

const store = createStore({

modules: {

moduleA,

moduleB

}

})

export default store;

在组件中使用moduleA和moduleB

<template>

<div>

{{store.state.moduleA.msg}}

<br>

{{store.state.moduleB.msg}}

</div>

</template>

<script setup>

import { useStore } from 'vuex'

let store = useStore()

</script>

为了防止各模块中mutations或者actions中的方法重名,modules提供了命名空间的方法(namespaced:ture)

以moduleA为例:

//modules/moduleA.js

const moduleA = {

namespaced: true,

state: () => ({

msg:'hello moduleA'

}),

mutations: {

changeMsg(state,data){

state.msg = data

}

},

actions: {},

getters: {}

}

export default moduleA

为了避免其他模块中也有相同命名的changeMsg方法,我们可以通过“模块名/方法名”的方式调用。

import { useStore } from 'vuex'

let store = useStore()

console.log(store.state.moduleA.msg);

store.commit('moduleA/changeMsg','hello juejin')

console.log(store.state.moduleA.msg);

Pinia

Pinia每个状态本身就是一个模块。Pinia没有modules,如果想使用多个store,直接定义多个store传入不同的ID(defineStore()的第一个参数)即可

import { defineStore } from 'pinia'

export const useModuleA = defineStore('storeA',{

state: () => (),

actions: {},

getters: {}

});

export const useModuleB = defineStore('storeB',{

state: () => (),

actions: {},

getters: {}

});

在组件中,要使用哪个模块就引入哪个模块

import { useModuleA } from './store';

let storeA = useModuleA()

console.log(storeA.msg);

storeA.changeMsg('hello juejin')

console.log(storeA.msg);

最后

如果你的项目是基于Vue2可以选择vuex,如果你的项目基于Vue3,喜欢使用组合式API,使用TS,那么更推荐使用Pinia。当然,以上仅供参考,具体根据个人和团队的具体情况来选择

http://www.jsqmd.com/news/618828/

相关文章:

  • uniapp map组件进阶:动态标记点与交互式气泡弹窗实战
  • DOM操作是JavaScript与网页交互的核心
  • DeepMind 研究:AI Agent 存在安全漏洞,恶意网页可实现远程劫持
  • 用Claude Agent SDK构建CLI工具
  • 中小企业优选!2026素材网站推荐排行 高效创作/正版商用 - 极欧测评
  • AI开发-python-langchain框架(--自定义Tool )桌
  • Windows优化神器Winhance:3分钟让你的电脑飞起来![特殊字符]
  • 从POC到规模化落地断层频发?——AI原生供应商评估漏掉这4个“非功能刚需”,成本超支将不可逆(含金融/医疗双行业基线对照表)
  • 终极指南:如何用MouseClick鼠标连点器实现高效自动化点击,解放你的双手!
  • 用OpenSearch实现电商语义搜索
  • 寻找长期合作伙伴?这份2026年GEO优化服务商深度评测指南请收好 - 品牌推荐大师1
  • 分析九号标识设计行业口碑排名,看看它的服务体验究竟如何 - 工业设备
  • Python金融数据分析深度解析:AKShare架构设计与实战应用体系
  • [Python3高阶编程] - 描述器之__set_name__
  • FastAPI子应用挂载:别再让root_path坑你一夜案
  • 信誉调查:ROHS2.0测试设备厂商客户口碑与行业评价 - 品牌推荐大师
  • AI原生研发倒逼组织重构:3大职能裂变、4类岗位消亡、5个先行企业实战路径
  • 比PPT更好用!用Mentimeter词云+投票打造高互动培训(附真实会议案例)
  • 2026 年 4 月最新幼猫离乳期喂养指南:从0到4月龄的最佳主食罐选择策略 - 科技焦点
  • 大润发购物卡线上回收的那些事:必读回收心得,让你轻松变现! - 团团收购物卡回收
  • js内建对象
  • Jetson设备密码恢复避坑指南:从镜像克隆到system.img替换的全流程解析
  • 国产品牌崛起:2026 年 4 月最新5款国产猫主食罐的技术实力与性价比对比 - 科技焦点
  • 哥本哈士奇(aspnetx)诓
  • 创新实训个人工作-初步搭建(二)
  • 思源宋体CN:7种字重免费开源字体终极指南与实战应用
  • LLM中的情感机制深度解析
  • 二分查找力扣题(leetcode)掏
  • 浏览器被劫持
  • 京东E卡回收流程详解,闲置卡变现秘籍 - 购物卡回收找京尔回收