Vuex概念
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。(响应式的状态管理模式 多个组件之间共享状态)
安装
npm install vuex --save
配置
新建store文件->index.js,进行如下配置,在mian.js中进行引入
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//数据,相当于data
state: {
},
getters: {
},
//里面定义方法,操作state方发
mutations: {
},
// 操作异步操作mutation
actions: {
},
modules: {
},
})
在 main.js 文件中挂载使用
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
核心概念
state
一个store来管理全部的状态
单一数据源
在vuex中state中定义数据,可以在任何组件中进行调用
<template>
<div id="app">
<h2>{{message}}</h2>
<h2>{{$store.state.counter}}</h2>
<button @click="counter++">+</button>
<button @click="counter--">-</button>
<hello-vuex :counter="counter"></hello-vuex>
</div>
</template>
<script>
import HelloVuex from "./components/HelloVuex";
export default {
name: "App",
components: {
HelloVuex,
},
data() {
return {
message: "我是app组件",
// counter: 0,
};
},
};
</script>
<template>
<div>
<h2>{{$store.state.counter}}</h2>
</div>
</template>
<script>
export default {
name: "HelloVuex",
// props: {
// counter: Number,
// },
};
</script>
main.js中
import store from "./store";
new Vue({
el: "#app",
store,
render: h => h(App)
});
import Vue from "vue";
import Vuex from "vuex";
// 1.安装插件
Vue.use(Vuex);
// 2. 创建对象
const store = new Vuex.Store({
state: {
counter: 1000
},
mutations: {},
actions: {},
getters: {},
modules: {}
});
// 3. 导出store独享
export default store;
Mutations
mutations携带参数
mutations状态更新
Vuex的store状态更新唯一方式:提交Mutations
Mutations包含:
- 字符串的事件类型
- 一个回调函数,该回调函数的第一个参数就是state
<button @click="addCount(5)">+5</button>
<button @click="addCount(10)">+10</button>
<button @click="addStudent">添加学生</button>
<script>
methods: {
addCount(count) {
// console.log("addCount...");
// payload: 负载
this.$store.commit("incrementCount", count);
},
addStudent() {
// payload是一个对象
const stu = { id: 114, name: "lisi", age: 22 };
this.$store.commit("addStudent", stu);
},
},
};
</script>
incrementCount(state, count) {
state.counter += count;
},
addStudent(state, stu) {
state.students.push(stu);
}
提交风格
使用一个对象来封装
mutations里面最好用一个payload来封装
incrementCount(state, payload) {
// console.log(count); // 第二种方式打印: Object { type: "incrementCount", count: 5 }
state.counter += payload.count;
},
// 1. 普通的提交封装
// this.$store.commit("incrementCount", count);
// 2. 特殊的提交封装
this.$store.commit({
type: "incrementCount",
count,
});
响应规则
一开始在state中被定义的值,都会被放在响应式系统中,当属性发生变化时,会通知所有用到的地方发生更新
新的属性,是不会被监听的
updateInfo(state) {
// state.info.name = "w"; // 是响应式的 旧属性
// state.info["address"] = "Guangzhou"; // 新的属性 虽然在store中被改变了 但是在界面上不是响应式的
// 必须要使用Vue的方法
// 参考之前的数组里面的操作
// Vue.set(state.info, "address", "Guangzhou"); // 这样才是响应式的
// delete state.info.age; // 也不是响应式的
Vue.delete(state.info, "age"); //是响应式的
}
类型常量
store下新建一个文件mutations-types.js
export const INCREMENT = "increment";
// index.js
import { INCREMENT } from "./mutations-types";
[INCREMENT](state) {
state.counter++;
},
// App.vue
import { INCREMENT } from "./store/mutations-types";
addition() {
this.$store.commit(INCREMENT);
},
actions
mutations里面进行异步操作,在devtools里面不会更新
使用actions替代mutations
使用actions嵌套使用mutations
// App.vue
updateInfo() {
// this.$store.commit("updateInfo");
// this.$store.dispatch("aUpdateInfo", "我是payload"); // 可以传递参数
// this.$store.dispatch("aUpdateInfo", () => {
// console.log("里面的操作已经完成了");
// });
// this.$store.dispatch("aUpdateInfo", {
// message: "我是携带的信息",
// success: () => {
// console.log("里面已经完成了");
// },
// });
this.$store
.dispatch("aUpdateInfo", "我是携带的信息") // index.js中返回的Promise返回到这里
// 通过actions做了中转,再返回到这里
.then((res) => {
console.log("里面完成了提交");
console.log(res);
});
},
// index.js
actions: {
// context上下文 理解为store
// 必须通过mutations来操作
// aUpdateInfo(context, payload) {
// setTimeout(() => {
// context.commit("updateInfo");
// // console.log(payload);
// // payload();
// console.log(payload.message);
// payload.success();
// }, 1000);
// }
aUpdateInfo(context, payload) {
// 这里的Promise返回到App.vue的方法中 可以进行then操作
return new Promise((resolve, reject) => {
setTimeout(() => {
context.commit("updateInfo");
console.log(payload);
// payload();
// console.log(payload.message);
resolve("11111");
}, 1000);
});
}
},
getters
类似于vue中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据
<template>
<div id="app">
<h2>------------App内容--------------</h2>
<h2>{{message}}</h2>
<h2>{{$store.state.counter}}</h2>
<button @click="addition">+</button>
<button @click="subtraction">-</button>
<h2>---------------App内容:getters相关信息------------------</h2>
<h2>{{$store.getters.powerCounter}}</h2>
<h2>{{$store.getters.more20stu}}</h2>
<h2>{{$store.getters.more20stuLength}}</h2>
<h2>{{$store.getters.moreAgestu(18)}}</h2>
<h2>-----------------------Hello Vuex内容---------------------------------</h2>
<hello-vuex />
</div>
</template>
const store = new Vuex.Store({
state: {
counter: 1000,
students: [
{ id: 110, name: "why", age: 18 },
{ id: 111, name: "kobe", age: 28 },
{ id: 112, name: "james", age: 19 },
{ id: 113, name: "curry", age: 39 }
]
},
mutations: {
// 方法
increment(state) {
state.counter++;
},
decrement(state) {
state.counter--;
}
},
actions: {},
getters: {
powerCounter(state) {
return state.counter * state.counter;
},
more20stu(state) {
return state.students.filter(s => s.age > 20);
},
// 调用其他的getters
more20stuLength(state, getters) {
return getters.more20stu.length;
},
// 传入自定义的参数
moreAgestu(state) {
// return function(age) {
// return state.students.filter(s => s.age > age);
// };
return age => {
return state.students.filter(s => s.age > age);
};
}
},
modules: {}
});
modules
当遇见大型项目时,数据量大,store就会显得很臃肿
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割
const moduleA = {
state: {
name: "zhangsan"
},
mutations: {
// 不能和store的mutations的函数名重复 优先在下面找
updateName(state, payload) {
state.name = payload;
}
},
actions: {
// 这里的context指的是 模块中的 mutations
console.log(context); //这里的context可以拿到很多东西的
aUpdateName(context) {
setTimeout(() => {
context.commit("updateName", "wangwu");
}, 1000);
}
},
getters: {
fullname(state) {
return state.name + 111;
},
// 嵌套调用getters
fullname2(state, getters) {
return getters.fullname + "222";
},
// 引用根state中的counter 添加一个参数rootState
fullname3(state, getters, rootState) {
return getters.fullname2 + rootState.counter;
}
}
};
const moduleB = {
state: {},
mutations: {},
actions: {},
getters: {}
};
// 可以进行抽离
modules: {
a: moduleA,
b: moduleB
}
// App.vue
<h2>----------App内容:modules里面的内容--------------</h2>
<!-- 模块 a 添加到了 state 中,所以需要先拿到a 在引用name -->
<h2>{{$store.state.a.name}}</h2>
<button @click="updateName">修改名字</button>
<!-- 也是可以直接调用 -->
<h2>{{$store.getters.fullname}}</h2>
<h2>{{$store.getters.fullname2}}</h2>
<h2>{{$store.getters.fullname3}}</h2>
<button @click="asyncUpdateName">异步修改名字</button>
updateName() {
this.$store.commit("updateName", "lisi");
},
asyncUpdateName() {
this.$store.dispatch("aUpdateName");
},
标签:counter,getters,mutations,state,Vuex,payload,store
From: https://www.cnblogs.com/uuujh/p/16736475.html