Vuex是一个专为Vue.js应用程序开发的状态管理模式和库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。下面我用通俗易懂的方式为您讲解Vuex:
1. 为什么要使用Vuex?
- 解决组件间通信问题:在Vue.js中,随着组件数量的增加,组件之间的通信和状态管理变得复杂。Vuex提供了一个全局的、集中的状态管理方案,使得任何组件都可以访问和修改应用的状态。
- 单向数据流:Vuex强制使用单向数据流,即状态变更必须通过明确的、可预测的方式来执行,这有助于减少错误和调试难度。
2. Vuex的核心概念
- State(状态):存放应用的所有共享数据,作为单一数据源。这类似于全局变量,但Vuex提供了更严谨的规则和工具来管理它。
- Getters(计算属性):从State中派生一些状态,类似于Vue中的计算属性。它允许你对State中的数据进行加工和获取。
- Mutations(变更):用于修改State的唯一合法方式,是同步的。每个Mutation都有一个字符串类型的名字,并通过commit来触发。
- Actions(动作):用于处理异步操作,可以包含任意异步操作,并通过提交Mutation来间接更新State。
- Modules(模块):当应用变得复杂时,可以将store分割成模块,每个模块拥有自己的state、mutation、action、getter甚至是嵌套子模块。
3. Vuex的基本用法
- 工作流程:
- 通过dispatch去提交一个actions(异步)。
- Actions接收到这个事件之后,在actions中可以执行一些异步或同步操作,根据不同的情况去分发给不同的mutations。
- Actions通知commit去触发mutations。
- Mutations去更新state数据,state更新之后,就会通知Vue进行渲染。
4. Vuex的优点
- 集中管理:所有组件的状态都集中在一个地方管理,方便查找和修改。
- 可预测性:由于状态变更必须通过明确的、可预测的方式来执行,因此可以减少错误和调试难度。
- 模块化:支持将store分割成模块,每个模块拥有自己的状态管理逻辑,方便管理和维护。
5. Vuex的注意事项
- 不要滥用:对于小型应用来说,使用Vuex可能会显得过于繁琐。在决定是否使用Vuex时,需要根据项目的实际情况来权衡利弊。
- 避免直接修改State:只能通过Mutation来修改State,避免直接修改State导致的不可预测性。
总之,Vuex是一个强大的状态管理库,它可以帮助我们更好地管理Vue.js应用程序的状态,提高开发效率和代码质量。
vuex实战:
首先,我们需要安装Vuex。
npm install vuex
# 或者
yarn add vuex
创建一个Vuex store文件(例如store.js
)
// 引入Vue和Vuex
import Vue from 'vue';
import Vuex from 'vuex';
// 使用Vuex插件
Vue.use(Vuex);
export default new Vuex.Store({
// 状态管理
state: {
count: 0 // 初始化一个名为count的状态,值为0
},
// 同步修改状态的方法(mutations)
mutations: {
INCREMENT(state) {
// 修改状态中的count值
state.count++;
}
},
// 异步操作或包含任意异步操作的方法(actions)
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
// 使用commit方法来触发一个mutation
commit('INCREMENT');
}, 1000);
}
},
// 从state中派生出一些状态(getters)
getters: {
doubleCount(state) {
return state.count * 2;
}
}
});
在你的Vue组件中,你可以使用this.\$store
来访问Vuex store。
也可以使用Vuex的mapState
、mapMutations
、mapActions
和mapGetters
辅助函数
<template>
<div>
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="increment">Increment</button>
<button @click="incrementAsync">Increment Async</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex';
export default {
computed: {
// 使用mapState辅助函数将Vuex state映射到组件的计算属性
...mapState(['count']),
// 使用mapGetters辅助函数将Vuex getters映射到组件的计算属性
...mapGetters(['doubleCount'])
},
methods: {
// 使用mapMutations辅助函数将Vuex mutations映射到组件的方法
...mapMutations(['INCREMENT']),
increment() {
this.INCREMENT(); // 调用INCREMENT mutation来修改count状态
},
// 使用mapActions辅助函数将Vuex actions映射到组件的方法
...mapActions(['incrementAsync']),
incrementAsync() {
this.incrementAsync(); // 调用incrementAsync action来异步修改count状态
}
}
};
</script>
Module模块使用
在大型项目中,需要管理的状态会比较多,如果全部状态在同一个文件内,不利于管理。此时我们就可以使用module把各个功能的状态独立开来。
├── store
├── index.js
└── modules # 模块文件夹
├── moduleA.js # 模块moduleA
└── moduleB.js # 模块moduleB
index.js
// 页面路径:store/index.js
import {createStore} from 'vuex'
import moduleA from '@/store/modules/moduleA'
import moduleB from '@/store/modules/moduleB'
export default createStore({
modules: {
moduleA,
moduleB
}
})
moduleA.js
// 子模块moduleA路径:store/modules/moduleA.js
export default {
state: {
text:"我是moduleA模块下state.text的值"
},
getters: {
},
mutations: {
},
actions: {
}
}
moduleB.js
// 子模块moduleB路径:store/modules/moduleB.js
export default {
state: {
timestamp: 1608820295//初始时间戳
},
getters: {
timeString(state) {//时间戳转换后的时间
var date = new Date(state.timestamp);
var year = date.getFullYear();
var mon = date.getMonth()+1;
var day = date.getDate();
var hours = date.getHours();
var minu = date.getMinutes();
var sec = date.getSeconds();
var trMon = mon<10 ? '0'+mon : mon
var trDay = day<10 ? '0'+day : day
return year+'-'+trMon+'-'+trDay+" "+hours+":"+minu+":"+sec;
}
},
mutations: {
updateTime(state){//更新当前时间戳
state.timestamp = Date.now()
}
},
actions: {
}
}
页面引用
<!-- 页面路径:pages/index/index.vue -->
<template>
<view class="content">
<view>{{text}}</view>
<view>时间戳:{{timestamp}}</view>
<view>当前时间:{{timeString}}</view>
<myButton></myButton>
</view>
</template>
<script>
import {mapState,mapGetters} from 'vuex'
export default {
computed: {
...mapState({
text: state => state.moduleA.text,
timestamp: state => state.moduleB.timestamp
}),
...mapGetters([
'timeString'
])
}
}
</script>
评论: