Vue.js是国内当下十分流行的一个前端Web框架,具有丰富的组建和库支持,其中Vuex可以说是最为重要的一个了,但是,在一些项目中,我们甚至都不会用到Vuex,所有Vue开发者有时候就会忽略掉这样一个重要的组建,今天我就结合自己的学习过程,对Vuex做一个总结。
用官网的话解释:
Vuex是一个专门为Vue.js应用程序开发的状态管理模式。
由这句话可得,Vuex是专门的为Vue开发的组建,不可以应用到别的应用程序当中。那么什么是状态管理呢?在使用Vue进行开发的时候,我们会在data定义一个个变量,那么这每一个变量都可以是一个状态,Vuex则就是用来管理这些状态的。所以,当Vue这个应用程序比较庞大的时候,他的组件比较多,为了方便地管理某一些状态,我们需要把一些状态(变量)抽取出来,通过Vuex进行集中管理。
这个最主要的是取决于我们的项目,当我们构建一个中大型的单页应用的时候,Vuex可以更好地帮助我们在组件的外部统一管理状态。比如说,我们在做一个商场界面的时候,很多页面都会有一个购物车的图标,这个图标会一直记录你的商品数目,如下图所示,如果采用不断传参的方法进行商品数目获取,那么将会非常麻烦,而且不方便修改管理,如果使用Vuex就会很轻松。
所以你其实可以把Vuex理解成是一个windows全局变量,方便我们去使用。
上面我们说过,在每个Vue文件中的data内的变量,都可以说是一个状态(state),statue也是Vue的核心概念,它告诉开发者,Vue就是这样一个渐进式框架,使用状态管理DOM。
State是唯一的数据源,所有的数据都会抽取到State中进行管理。
State是单一的状态树。
const Counter = {
template: `{{ count }}`,
computed:{
count(){
return this.$store.state.count
}
}
}
当$store.state.count发生变化时,computed中的count()函数就会实时计算,最后渲染到试图中。
this是当前Vue的实例。
this.$store就是我们的Vuex对象(只要import Vuex,并且use,就可以通过这个api进行调用)
count就是我们Vuex对象下挂载的属性。
通过这种方式我们就可以使用Vuex下的状态。
通过Getters可以派生出一些新的状态。
const store = new Vuex.Store({
state:{
todos:[
{id:1,text:'...',done:true},
{id:2,text:'...',done:false}
]
},
getters{
doneTodos:state => {
return this.state.todos.filter(todo => todo.done)
}
}
})
通过new Vuex.Store就可以创建一个Vuex对象。
把状态抽取除开放到了state当中。
假如state中todes[]这个数组在每个页面中都会使用。
但恰巧有一个页面并不想完全使用这个数组,只想用done属性为true的,这个时候就可以通过getters进行过滤,或者一些替换操作。
更改Vuex的store中的状态的唯一的方法是提交mutations
const store = new Vuex.Store({
state:{
count:1
},
mutations: {
increment(state){
//变更状态
state.count++;
}
}
})
这个时候如果我们希望把state中count改成2,我们只能通过mutations这个方法来执行,重要的事情说三遍,只能只能只能通过mutations,不能像Vue文件中通过this.count修改。
那么我们怎么去调用它呢?
store.commit('increment')
通过这样的命令,我们就可以触发这个修改,从而实现我们的目标。
Actions提交的是mutations,而不是直接变更状态。
Actions可以包含任意的异步操作。
const store = new Vuex.Store({
state:{
count:0
},
mutations: {
increment(state){
//变更状态
state.count++;
}
},
actions:{
increment(context){
context.commit('increment')
}
}
})
通过全局定义的context对象,来提交我们的increment方法 。
我们可以在Vue组件的method当中提交修改,也可以在Vuex下的actions中提交修改。
大家可能会觉得actions有些多余,但是,在一些场景下他还是有用的,如果mutations当中的必须是同步的方法,而actions可以包含任意异步操作。
面对复杂的应用程序,当管理的状态比较多的时候,我们需要将Vuex的store对象分割成模块(modules)
const moduleA = {
state:{...},
mutations:{...},
actions:{...},
getters:{...}
}
const moduleB = {
state:{...},
mutations:{...},
actions:{...},
getters:{...}
}
const store = new Vuex.Store({
modules: {
a:moduleA,
b:moduleB
}
})
上面这张图是来自官网的说明图,简单做一个讲解,上面的Backend API是我们后端的接口,左边,当我们的Vue组件发生变化时,通过Dispatch方法去提交actions,而action需要提交commit改变我们的mutations,而mutations是改变状态的唯一途径,进而改变Vuex中的状态,最后实时渲染组件中的状态。其实就是把组件中的状态提取出来,可以供全局进行使用,和修改。
那么当项目相对复杂的时候我们就需要对Vue项目目录做一个简单的修改,当然如果Vue项目并没有那么庞大,可以直接在main.js中进行Vuex的构建。
src目录
|--index.html
|--main.js
|--api
--...#抽取出API请求
|--components
--App.vue
--...
|--store
--index.js #我们组装模块并且导出store的地方
--actions.js #根级别的action
--mutations.js #根级别的mutations
--modules
--cart.js #购物车模块
--products.js #产品模块