vuex
是一个专为 Vue.js
应用程序开发的状态管理模式
+ 库
。它采用集中式存储管
理应用的所有组件的状态
,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余
的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store
模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
在脚手架 创建项目时勾选vuex的选项系统会自动创建
vue默认vue3版本,vuex默认vuex4版本,vuex4只能在vue3中使用,在vue2中能使用vuex3,那么不能默认下载最新的版本
npm install vuex@3 --save
// src/store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
//数据,相当于data
state: {
name: "张三",
age: 12,
count: 0,
},
getters: {
name: (state) => state.name,
age: (state) => state.age,
count: (state) => state.count,
},
//里面定义方法,操作state方发
mutations: {
addCount(state, num) {
state.count = state.count + num;
},
reduce(state) {
state.count--;
},
},
// 操作异步操作mutation
actions: {
asyncAdd({ commit }, num) {
setTimeout(() => {
commit("addCount", num);
}, 1000);
},
},
modules: {
module1: {
namespaced: true,
state: {
name: "module1",
age: 12,
},
getters: {
name: (state) => state.name,
age: (state) => state.age,
},
mutations: {
changeName(state, name) {
state.name = name;
},
},
actions: {
asyncChangeName({ commit }, name) {
setTimeout(() => {
commit("changeName", name);
}, 1000);
},
},
},
},
});
import Vue from 'vue';
import App from './App.vue';
import store from './store';
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App)
}).$mount('#app');
提供唯一的公共数据源
,所有共享
的数据统一放到store
的state
进行储存,类似于data
。
$store.state.xx
调用mapState
函数,从vuex
中按需
导入<template>
<div>
<p>{{ $store.state.name }} - {{ age }} - {{ count }}p>
div>
template>
<script>
import { mapState } from "vuex";
export default {
name: "AT",
data() {
return {};
},
computed:{
...mapState(['age']),
count(){
return this.$store.state.count;
}
},
methods: {},
};
script>
类似于vue
中的computed
,进行缓存,对于Store
中的数据进行加工处理形成新的数据。
mapGetters
函数,从vuex
中按需
导入<template>
<div>
<p>{{ name }}p>
div>
template>
<script>
import { mapGetters } from "vuex";
export default {
name: "AT",
data() {
return {};
},
computed: {
...mapGetters(["name"]),
},
methods: {},
};
script>
更改
Vuex
的 store
中的状态的唯一
方法是提交 mutation
。Vuex 中的 mutation 非常类似于事件
:每个 mutation 都有一个字符串的事件类型
(type)和一个回调函数
(handler)。这个回调函数就是我们实际
进行状态更改的地方,并且它会接受 state
作为第一个参数。
commit
触发Mutation
操作mapMutations
函数,从vuex
中按需
导入<template>
<div>
<p>{{ $store.state.count }}p>
<button @click="addCount1">addCount1button> | <button @click="reduce1">reduce1button><br/>
<button @click="addCount2">addCount2button> | <button @click="reduce2">reduce2button>
div>
template>
<script>
import { mapMutations } from "vuex";
export default {
name: "AT",
data() {
return {}
},
methods: {
...mapMutations(['addCount', 'reduce']),
addCount1() {
this.$store.commit('addCount', 10);
},
reduce1(){
this.$store.commit('reduce');
},
addCount2() {
this.addCount(10);
},
reduce2(){
this.reduce();
}
},
};
script>
Action和Mutation相似,一般不用Mutation 异步操作,若要进行异步操作,使用Action
原因:为了方便devtools打个快照存下来,方便管理维护。所以说这个只是规范,而不是逻辑的不允许,只是为了让这个工具能够追踪数据变化而已
dispatch
触发Action
函数mapActions
函数,从vuex
中按需
导入<template>
<div>
<p>{{ $store.state.count }}p>
<button @click="addCount1">addCount1button><br />
<button @click="addCount2">addCount2button>
div>
template>
<script>
import { mapActions } from "vuex";
export default {
name: "AT",
data() {
return {};
},
methods: {
...mapActions(["asyncAdd"]),
addCount1() {
this.$store.dispatch("asyncAdd", 10);
},
addCount2() {
this.asyncAdd(10);
},
},
};
script>
当遇见大型项目时,数据量大,store
就会显得很臃肿
。为了解决此问题,Vuex
允许我们将store
分割成模块(module)
。每个模块拥有自己的 state
、mutation
、action
、getter
、甚至是嵌套子模块
。
默认情况下,模块内部的action
和mutation
仍然是注册在全局命名空间
的,这样使得多个模块能够对同一个action
或mutation
作出响应。
如果希望你的模块具有更高的封装度
和复用性
,你可以通过添加namespaced: true
的方式使其成为带命名空间
的模块。当模块被注册后,它的所有state
、getters
、mutations
、actions
都会自动根据模块注册的路径调整命名。
<template>
<div>
<p>{{ name }}p>
<p>{{ age }}p>
<p><button @click="changeName('lalal')">changeNamebutton>p>
<p>
<button @click="asyncChangeName('lalalalalal')">asyncChangeNamebutton>
p>
div>
template>
<script>
import { createNamespacedHelpers } from "vuex";
const { mapState, mapGetters, mapMutations, mapActions } =
createNamespacedHelpers("module1");
export default {
name: "AT",
data() {
return {};
},
computed: {
...mapState(["name"]),
...mapGetters(["age"]),
},
methods: {
...mapMutations(["changeName"]),
...mapActions(["asyncChangeName"]),
},
};
script>