Vuex快速上手
通俗的解释:是一种最好的非父子组件传值的一种方案。
官方解释:Vuex是一个公共状态管理(公共的内存对象),它把所有组件需要共有的状态放到了一个公共的内存空间里。并且给每一个状态做了一个数据劫持(给每一个状态添加了一个getter和setter方法);
一、Vuex安装使用
- 安装Vue CLI
cnpm install -g @vue/cli
- 创建项目名称
vue create 项目名称
- 选择下载的模式
有default默认和Manually手动配置,通常选择Manually。(通过上下键进行选择)
- 选择需要的配置
空格选中,回车跳过。可以先选择必要的配置,其他需要的时候再安装。

- 选择路由模式
Use history mode for router?(是否使用history路由)
- 是否需要保存当前的配置项(n)等操作(Y)
- 安装Vuex
cnpm install Vuex -S
- 引入并使用插件
import Vue from "vue"
import Vuex from "vuex";
Vue.use(Vuex);
- 创建公共的内存对象
const store = new Vuex().store({
})
export default stroe;
- 将Vuex在入口文件引入,挂载在Vue上
new Vue({
store,
render:h => h(app)
}).$mount('#app')
二、Vuex常用的配置项
-
state:存储公共状态
-
mapState辅助函数
当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用
mapState
辅助函数通过映射的关系将Vuex中的方法或者状态映射给组件的某一个属性注意:辅助函数的返回值都是一个对象。
语法:
-
数组
computed:mapState([“属性”,属性])
-
对象(可以简化类名,或在映射时做更改)
computed:{
...mapState({
name:state=>state.userName
})
}
-
-
mutations:修改公共状态(必须是同步函数,只处理数据,不做逻辑)
mutations里面包含两个参数:
参数1 :state
参数2 :传递的参数
-
mapMutations
import {mapState} from "vuex";
注意:mapState辅助函数必须映射到组件的methods上
语法:
1. methods:{
...mapMutations(["函数名称"])
}
- methods:{
...mapMutations({
新函数名称:"函数名称(必须是mutations里面的函数名称)"
})
}
-
-
actions:处理异步
actions里面包含两个参数:
参数1:一个对象{commit dispatch state getters ……}
参数2:传递的参数
-
mapActions
import {mapActions} from "vuex";
同样,必须映射到组件的methods身上
语法:
- methods:{
...mapActions(["函数名称"])
}
- methods:{
...mapActions({
新函数名称:"函数名称(必须是mutations里面的函数名称)"
})
}
注意:在不需要处理异步的时候,可以跳过actions,在组件中直接调用commit触发Mutations。
-
-
modules:公共状态私有化
modules里面存放的是小型的Vuex,可以理解成它是一个小型的状态管理仓库集合。
modules里面的每一个模块的配置项与store里面配置同样会有store/getters/actions/mutations
注意:
- 子模块在导出的时候切记一定要加
namespaced:true
, 以实现子模块私有化。 - 当设置了
namespaced:true
后访问子模块的方法,必须通过子模块名/方法名称
。
- 子模块在导出的时候切记一定要加
-
getters:公共状态计算属性
getter等价于computed,是一个计算属性。
getters中的函数,会有一个参数state,当前函数用来依赖state中的属性。当所依赖的state属性发生变化时会触发getters中的方法。
-
mapGetters
import {mapGetters} from "vuex"
注意:getters的辅助函数必须映射到computed上
语法:
-
…mapGetter([“函数名称”])
-
..mapGetters({
新名称 : "函数名称"
})
-
总结:mapMutions和mapActions是映射到methods上,mapState和mapGetter是映射到computed上
三、数据传递的流程
store中的数据通过辅助函数或
this.$store.state.属性
的方式渲染到组件上,组件需要通过this.$store.dispatch
来调用actions中的函数,actions函数通过commit方法调用mutations方法,修改state中的数据。因为数据是响应式的,因此组件视图也随之改变。

注意:基于这种数据传递的方式,所以,不能在组件内部使用v-model等来修改store中的数据。否则会导致错误难以理解。
通过提交 mutation 的方式,而非直接改变
store.state.count
,是因为我们想要更明确地追踪到状态的变化。
- 案例描述:
one和two两个组件共用state的数据:在one组件中修改state,会调用one组件中的dispatch,进入store中的actions,通过commit接收,传送到store中的mutation中修改state的值,重新渲染页面,one和two组件的值被更新
- one.vue
<template>
<div>
<h2>这是一个One组件</h2>
<p>{{$store.state.n}}</p>
<button @click="handleAdd">点击</button>
</div>
</template>
<script>
export default {
data(){
return {
message:"lxc"
}
},
created() {
console.log(this);
},
methods:{
handleAdd(){
this.$store.dispatch("handleActionsAdd","lxc")
}
}
}
</script>
- two.vue
<template>
<div>
<h2>这是一个Two组件</h2>
<p>{{$store.state.n}}</p>
</div>
</template>
- store中的index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
n: 10
},
actions: {
handleActionsAdd({ commit }, params) {
commit("handleMutationsAdd", params)
}
},
mutations: {
handleMutationsAdd(state) {
state.n++;
}
}
})
export default store;
-
运行结果
state.gif
四、Vuex的简易封装
let Vue;
function install(_Vue) {
//vue.use是找到install方法,给他传递一个vue
Vue = _Vue;
Vue.mixin({
//将store的实例挂在vue的实例身上 this.$store.state.属性
beforeCreate() {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store;
}
},
})
}
class Store {
//初始化
constructor(options) {
//将state中的状态转换为响应式状态
this.state = new Vue({
data: options.state
})
//初始化mutations
this.mutations = options.mutations || {};
//初始化actions
this.actions = options.actions || {};
//初始化getters
options.getters && this.handleGetters(options.getters)
}
commit(eventName, params) {
var fn = this.mutations[eventName];
fn(this.state, params);
}
dispatch(eventName, params) {
var fn = this.actions[eventName];
fn({ commit: this.commit.bind(this), dispatch: this.dispatch.bind(this), state: this.state }, params);
}
handleGetters(getters) {
var that = this;
this.getters = {};
Object.keys(getters).forEach(key => {
Object.defineProperty(that.getters, key, {
get: function () {
return getters[key](that.state);
}
})
})
}
}
网友评论