一、Vuex是做什么的
状态管理工具:多个组件共享状态(可以先简单理解成变量)
所有的组件都继承自vue的原型:可以通过在prototype中加属性实现上述对象,但是通过这种方式,无法实现响应式。
二、vue需要管理什么状态呢
三、初认识Vuex
使用:
1、安装vuex。npm install vuex --save
2. 在src中创建store文件夹。在store文件夹中放index.js
import Vue from 'vue'
import Vuex from 'vuex'
// 1.安装插件
Vue.use(Vuex)
// 实际调用的vuex.install
// 2.创建对象
const store = new Vuex.Store({
state: {
counter
},
mutations: {
},
actions: {
},
getters: {
},
modules: {
}
})
// 3.导出
export default store
3.将vuex引入vue
写在vue中,才能在vue的原型上加上该对象,vue.prototype.$store = store。然后就可以使用了、
import store from './store/index'
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
// 写在此处,才能在vue原型上加上该属性。Vue.prototype.$store = store。然后就可以拿来用了。
store,
render: h => h(App)
})
四、如何修改state中的数据呢:
在页面使用数据时,可以用:{{this.$store.state.name}}来使用
修改页面。通过mutation来修改,在mutations中定义方法。该方法中会传入一个参数state.直接用在方法中使用 state.name = "nihao" 来修改即可。
调用页面。需要使用函数。在函数中,使用this.$store.commit("在mutation中定义的方法名")即可。
在mutations中定义方法:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
add(state){
state.count++;
},
minus(state){
state.count--;
}
},
})
export default store
在页面中调用:
methods: {
add(){
this.$store.commit("add");
},
minus(){
this.$store.commit("minus");
}
}
五、vuex的核心概念。
5.1state:
5.1.1 单一状态树:单一数据源。
整个app中,只创建一个store
5.2 Getters基本使用(类似于计算属性)
同时getters也可以传递参数getters。示例看more20stuLength .
如果getters中想要传递其他参数,不能直接传,是不允许的。需要返回一个函数,在函数中传递参数,再调用该函数。示例看moreAgeStu。 调用的时候使用$store.getters.moreAgeStu(18)来调用。一般的调用和计算属性一样,不需要加括号。
5.3 mutation
5.3.1 mutation的基本用法
5.3.2 使用mutation传递参数。
5.3.3 mutation的提交形式。
this.$store.commit()中可以传递对象。
this.$store.commit({type:"increase",
count: 2,
age: 18
})
//接收时。接收的也是一个对象,注意与直接传参进行比较
mutation:{
increase(state, payload){
this.payload.count++;
console.log(this.payload.age);
}
}
5.3.4 vuex的数据响应式原理
定义在state中的属性,都会被加入到响应式系统中,这些响应式系统会监听属性的变化,当属性发生变化时,会通知所有界面中用到该属性的地方,并让这些界面发生变化。
与之前数组的一些响应式方法做类比!!!!
5.3.5 mutations的类型常量。
在mutations中定义的type,在其他页面进行$.store.commit("")时会用到。在使用时,很有可能会写错。因此一般用类型常量的方式来写。
首先在store文件夹中新建一个mutaionsTypes.js文件。定义常量。比如:
export const INCREASEMENT = "increase"
在需要使用的页面中,首先导出常量,然后再$.store.commit("")中使用常量就可以了。
import {INCREASEMENT} from '.....'
$store.commit(INCREASEMENT)
同时,在mutations中,也可以使用常量,首先在该js中引入常量,然后加一个中括号[常量]即可。如下所示:
import {INCREASEMENT} from '.....'
mutations:{
[INCREASEMENT](){
....
}
}
5.4 vuex-actions的使用详解
mutataion中的方法必须是同步方法。如果异步方法使用vuex-actions进行提交,页面仍然可以响应式,但是vuex devtools工具无法检测到。
因此,如果是异步操作,需要用actions。
使用actions传递参数和mutation传递参数是一样的,传递一个参数,或者传递一个对象。
如果异步操作完,要告诉操作完成,可以用一下两种方式:
法1:传递一个函数。
组件中的methods:
methods: {
add(){
// this.$store.commit("add");//同步操作
this.$store.dispatch("aUpdataInfo",{
count: 10,
sucess(){
console.log("信息传递完成");
}
})//异步操作
}
}
store文件下的index.js
actions: {
// context上下文
aUpdataInfo(context,payload){
setTimeout(()=>{
context.commit("add");
console.log(payload.count);
payload.sucess();
},1000)
}
}
法2:使用Promise函数
组件中的methods:
methods: {
add(){
// this.$store.commit("add");//同步操作
this.$store
.dispatch("aUpdataInfo", 10)
.then(res=>{
console.log("里面完成了提交");
console.log(res);
})
}
}
store文件下的index.js
actions: {
aUpdataInfo(context,payload){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
context.commit("add");
console.log(payload);
resolve(11111);
},1000)
})
}
}
5.5 vuex modules模块
用法实例:
(1)在modules模块加入属性
modules: {
moduleA,
}
(2)定义moduleA
const moduleA = {
state: {
name: 'zhangsan'
},
getters: {
fullName(state){
return state.name+"123";
},
fullName2(state, getters) {
return getters.fullName+"123";
},
fullName3(state, getters, rootState) {
return getters.fullName+"123"+rootState.count;
}
},
mutations: {
updateName(state, payload) {
state.name = payload;
}
},
actions: {
//context上下文commit只提交到自己模块的mutations方法中
aUpdataName(context){
console.log(context)
setTimeout(()=>{
context.commit("updateName","lisi");
console.log("修改完成")
})
}
}
}
(3)在App界面使用
<h2>------------测试vuex的模块化------------</h2>
<h3>{{$store.state.moduleA.name}}</h3>
<h3>{{$store.getters.fullName}}</h3>
<h3>{{$store.getters.fullName2}}</h3>
<h3>{{$store.getters.fullName3}}</h3>
<button @click="updateName">更改名字</button>
<button @click="updateNameaaa">异步更改名字</button>
methods: {
updateName(){
this.$store.commit("updateName", "wangwu");
},
updateNameaaa(){
this.$store.dispatch("aUpdataName");
}
}
除了直接使用模块中的state中的属性时,需要指明哪个模块,其余均不用指明。相当于只是定义的时候分模块化了,实际还是放到一起使用。
另外,把actions的中context打印,显示如下,说明也可以通过context调用rootGetters等等。
5.6 vuex中context的写法2:
使用了对象的解构
六、vuex的文件布局