VUEX是什么?能干什么?为什么要用VUEX?
VUE页面其实是由各个组件构成的,组件之间通信传值不可避免,父子组件之间传值相对容易,但是兄弟组件之间传值就不那么容易了,为了实现兄弟组件之间的传值,我们可能会写很多冗余的代码,也不太好维护。
一切困难的出现,也是代表新技术的革新~~~
不错,VUEX就是为了解决组件之间传值而诞生的。
VUEX的核心思想就是把数据放到一个公共的仓库里,然后用规定的方法去调用和维护这些数据

如上图,state的变化可以引起视图View的更新,视图View上可以触发一些事件(如客户的点击等)调用Actions方法,Actions方法的执行可以引起State的变化,这样就形成了闭环
说到VUEX,很多人认为已经学习了很多次了,甚至在工作中也使用了很多次,但是再次使用还得查资料,究其原因还是没有掌握真正的学习方法。由于人类的记忆是会时间遗忘的,这不可避免。所以造成 大多数人吸收知识的过程是“进-出”,真正的过程应该是“进-吸收-出” 只有真正的掌握学习一门新技术的正确姿势,才会有越来越多的知识储备,越来越牛逼~~~
那怎么样才是正确的学习方法呢?
来了解一个词 “学以致用”,先学再用,而我们很多时候就是没有真正的学会就去用了,这样就造成了用多少次还是不了解。
怎么样才是正确的了解方法呢?
正如我们了解人的本能作用不凡先看看人的结构,人的部位包含耳朵,鼻子,眼睛,嘴巴,手脚,大脑等;耳朵可以听声音,鼻子可以闻味道;眼睛可以看东西;嘴巴可以吃东西;手脚可以干活走路;大脑可以思考;这些部位的作用构成了人的作用,人可以听、闻、看、吃、工作、走路、思考等。我们用这种 先分解在组装合并;从内到外逐层了解的思想 去学习,就可以彻底了解并学会一门新技术。
今天我们讲的主角是vuex,要想彻底学会VUEX,我们需要先分解
vuex分为什么部分?

State是存储数据的 仓库
Getters是把state的值计算后得到的新值,我们可以理解为 计算属性;
Mutations 是 改变state 的唯一方式,利用 commit mutations 的方式,修改仓库数据
Actions 通过触发mutations来修改仓库数据,利用 dispatch actions 的方式调用actions,然后在actions里commit mutations 达到改变仓库数据的目的。
Modules字面意思就是模块,这个适合在大型项目中多人开发使用,如果项目小没有必要使用;
可能不太好理解mutations和actions,我们可以这么认为,要改变state数据mutations和actions都需要,mutations用于直接修改仓库数据,但是什么时候触发呢,actions用于触发mutations
不好理解就举个栗子🌰

如上图我们点击➕,应该通过dispatch触发actions里的submitSetCount,然后在submitSetCount里通过commit触发mutations里的setCount,这是一个连贯的过程,就跟我们走路,膝关节动起来,步子就迈开了,膝关节就好比actions,迈开步子就好比mutations。
mutations: {
setCount (state, payload) {
state.count += payload
}
},
actions: {
submitSetCount(context, payload) {
context.commit('setCount', payload)
}
}
这样我们在actions方法里要做的就是commit一个mutations里定义的方法,并把需要的值传给mutations里对应的方法
可以理解为由客户调用,就跟上面这个设置步长的图,客户可以点击加号或减号,点击的过程我们就可以触发actions,这样我们对VUEX就有一个完整的理解了,仓库的里的数据由mutations改变,mutations由actions触发,actions由客户触发。
掌握了基本的思路后,我们接下来就开始使用了,相信这样的使用方式一定是 有思想的使用
VUEX的使用步骤
第一步安装vuex
npm install vuex --save
第二步,根目录下建store文件夹,文件夹里建index.js,引入vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
第三步,在main.js中,引用上一步新建的index.js,并全局引用store
import store from '../store/index'
new Vue({
store,//置入vue中,全局引用vuex
render: h => h(App),
}).$mount('#app')
第四步,在store/index.js中写仓库数据
改变state的唯一方法是通过commit提交mutations方法,官方建议修改state数据都要通过dispatch一个actions方法,然后在actions方法里commit一个mutations方法,这样看起来就是下面这个过程
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex)
const store = new Vuex. Store({
state: {
count: 1,
},
getters: {
changeCount (state, getters) {
return store.state.count*2 + 1
}
},
mutations: {
setCount (state, payload) {
state.count += payload
}
},
actions: {
submitSetCount(context, payload) {
context.commit('setCount', payload)
}
}
})
export default store
我们注意到,上面
getters的参数([state] [,getters]) state是vuex的state的值,getters是仓库中定义的所有getters属性

mutations的参数([state] [,payload])
state代表仓库数据,payload代表commit的时候传的参数
actions的参数([context] [,payload])
[context]参数下面会讲到,payload同样是调用的时候传的参数
第五步,在页面中使用仓库中数据,页面中操作改变数据
<template>
<div id="app">
<p>{{this.$store.state.count}}</p>
<br>
<p>{{this.$store.getters.changeCount}}</p>
<button @click="changeCount">点击一下</button>
</div>
</template>
<script>
export default {
name: 'App',
methods: {
changeCount() {
this.$store.dispatch('submitSetCount',3)
}
}
}
</script>
大家可以执行这些例子,会发现VUEX是如此的简单
读到这里,我们已经掌握了VUEX的基本使用,可以在项目中大显身手了,但是如果要达到炉火纯青的地步,接着往下读,相信你会得到更多的收获~~~
简短的页面调用方式
上面操作仓库数据的方法太长,有没有简短的方式呢?
vuex提供了mapState,mapGetters,mapMutations,mapActions方法,分别对应state,getters,mutations,actions;
首先我们要导入这些方法
import { mapState, mapGetters, mapActions } from 'vuex'
computed: {
...mapState([
'count'
]),
...mapGetters([
'changeCount'
])
}
对于mapState和mapGetters我们可以理解为计算属性,要放入computed里 对于mapMutations和mapActions我们可以理解为方法,要放入methods中
我们看下面经过改造的例子
<template>
<div id="app">
<p>{{count}}</p>
<br>
<p>{{changeCount}}</p>
<button @click="clickCount">点击一下</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex'
export default {
name: 'App',
computed: {
...mapState([
'count'
]),
...mapGetters([
'changeCount'
])
},
methods: {
...mapActions([
'submitSetCount'
]),
clickCount() {
this.submitSetCount(3)
}
}
</script>
对于mapState,mapGetters,mapMutations,mapActions我们可以理解为封装好的函数,直接调用这些会精简我们的项目
如果大型项目,我们需要更加精简项目,这时候modules就派上用场了
modules是什么?怎么用?
当项目庞大,多人参与开发的时候,我们上面写的VUEX文件将会非常庞大,维护起来难度也加大, 一切困难的出现,也是代表新技术的革新~~~ ,modules就是来解决这个问题的,modules的字面意思是“模块”,它的思路就是把vuex分为各个模块,每个模块处理一类事情,每个模块写在单独的文件里,然后在一个总的文件里导入这些模块,每个模块都包含state,getters, mutations, actions,甚至包含子模块。
废话说多了难理解,举个🌰
store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex)
import login from './login'
import order from './order'
export default new Vuex.Store({
modules: {
login,
order
}
})
store/login.js
const login = {
state: {
name: 'Lili'
},
getters: {
changeName (state, getters) {
return '我是' + login.state.name
}
},
mutations: {
setName (state, payload) {
state.name = payload
}
},
actions: {
submitSetName(context, payload) {
console.log(context,'79')
context.commit('setName', payload)
}
}
}
export default login
store/order.js
const order = {
state: {
id: 1
},
getters: {
changeId (state, getters) {
return order.state.id*2 + 1
}
},
mutations: {
setId (state, payload) {
state.id += payload
}
},
actions: {
submitSetId(context, payload) {
context.commit('setId', payload)
}
}
}
export default order
我们分开模块了,接下来就需要思考怎么调用这些模块中的state,getters, mutations, actions?
<template>
<div id="app">
<p>{{name}}</p>
<br>
<p>{{changeName}}</p>
<p>{{id}}</p>
<br>
<p>{{changeId}}</p>
<button @click="clickName">点击改变名字</button>
<button @click="clickId">点击改变订单ID</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex'
export default {
name: 'App',
computed: {
...mapState([
'name',
'id'
]),
...mapGetters([
'changeName',
'changeId'
])
},
methods: {
...mapActions([
'submitSetName',
'submitSetId'
]),
clickName() {
this.submitSetName("TOM")
},
clickId() {
this.submitSetId("22")
}
}
}
</script>
通过这个例子,我们看到调用方式几乎是一模一样的
仔细思考,如果A模块和B模块之间想互相取值怎么办
我们看一下下面例子,参数context是什么
actions: {
submitSetName(context, payload) {
console.log(context,'79')
context.commit('setName', payload)
}
}
"context"打印出来是

原来context参数是一个对象,包含了很多属性,比如可以通过rootState,取到所有模块中store中数据
到这里我们的VUEX课程就讲完了,觉得好的话,记得给我点赞鼓励一下~~~