Vuex的全面用法总结

2022-12-22 0 1,078

(点选下方社会公众号,可加速高度关注)

1. vuex概要

vuex是专门针对用以管理工作vue.js应用领域程序中状况的两个应用领域程序。他的促进作用是将应用领域中的大部份状况都放到一同,封闭式来管理工作。须要新闻稿的是,这儿所言的状况指的是vue模块中data里头的特性。介绍vue的老师如果是知道data是咋的吧,假如要学不然,提议速成完vue的基本知识再看vuex。

2. vuex的共同组成内部结构左图

vuex的特征是把统计数据原则上隔绝,逐步形成一棵树状图。原则上隔绝就意味著它有自己的生态系。输入和输入,其中action做为统计数据的输入,state做为统计数据的输入。如下表所示图:

Vuex的全面用法总结

vuex里有那么两个准则:

根本无法在mutaions里修正state,actions无法间接修正state

mutations即变动,修正state的统计数据,因此根本无法是并行的,无法存有触发器的操作方式。假如须要触发器咋办呢?把触发器操作方式放到actions里,领到统计数据再透过mutations同步处置。vuex做的只不过是把行政权明晰了,职责行业龙头了。因此它文件格式里也说,小控制系统可以不必。状况统计数据少,没有行业龙头的必要性。

透过这个图,我们很难就对vuex的重要共同组成部分,以及vuex与模块(components)间的联络一清二楚。只不过这那哥,有点儿迷惑人,暂看要学也说实话,如果有两个简单的重新认识要是。这张叙述图就不必了Vuex的全面用法总结,大家请往下看。

3. vuex 的核心概念

3.1 store

vuex 中最关键的是store对象,这是vuex的核心。可以说,vuex这个应用领域程序只不过就是两个store对象,每个vue应用领域仅且仅有两个store对象。

3.1.1 创建store

const store = new Vuex.Store({});

可见,store是Vuex.Store这个构造函数new出来的实例。在构造函数中可以传两个对象参数。这个参数中可以包含5个对象:

1.state – 存放状况

2.getters – state的计算特性

3.mutations – 更改状况的逻辑,并行操作方式

4.actions – 提交mutation,触发器操作方式

5.mudules – 将store模块化

关于store,须要先记住两点:

1. store 中存储的状况是响应式的,当模块从store中读取状况时,假如store中的状况发生了改变,那么相应的模块也会得到更新;

2. 无法间接改变store中的状况。改变store中的状况的唯一途径是提交(commit)mutations。这样使得我们可以方便地跟踪每两个状况的变动。

3.1.2 两个完整的store的内部结构是这样的

const store = new Vuex.Store

({

 
state:

{

   

// 存放状况

 

},

 
getters:

{

   

// state的计算特性

 

},

 
mutations:

{

   

// 更改state中状况的逻辑,并行操作方式

 

},

 
actions:

{

   

// 提交mutation,触发器操作方式

 

},

 

// 假如将store分成两个个的模块不然,则须要用到modules。

  //然后在每两个module中写state, getters, mutations, actions等。

 
modules:

{

   
a: moduleA

,

   
b: moduleB

,

   

// …

 

}

});

3.2 state

state上存放的,说的简单一些就是变量,也就是所谓的状况。没有使用 state 的时候,我们都是间接在 data 中进行初始化的,但是有了 state 之后,我们就把 data 上的统计数据转移到 state 上去了。另外有些状况是模块私有的状况,称为模块的局部状况,我们不须要把这部分状况放到store中去。

3.2.1 如何在模块

由于vuex的状况是响应式的,因此从store中读取状况的的方法是在模块的计算特性中返回某个状况。

import store from store

;

const Counter =

{

 
template: `<div>{{ count }}</div>`

,

 
computed:

{

   
count

() {

     
return store.state.count

;

   }

 }

}

这样,模块中的状况就与store中的状况关联起来了。每当store.state.count发生变动时,都会重新求取计算特性,从而更新DOM。

然而,每个模块中都须要反复倒入store。可以将store注入到vue实例对象中去,

const app = new Vue

({

 
el: #app

,

 

// 把 store 对象注入到了

 
store

,

 
components: { Counter

},

 
template: `

`

});

这样可以在子模块中使用this.$store.state.count访问到state里头的count这个状况

const Counter =

{

 
template: `<div>{{ count }}</div>`

,

 
computed:

{

   
count

() {

     
return this.$store.state.count

;

   }

 }

}

3.2.2 mapState

import { mapState } from  vuex

;

export default

{

 

// …

 
data

(){

   
localState:

1

 

}

 
computed: mapState

({

   

// 此处的state即为store里头的state

   
count: state => state.count

,

   

// 当计算特性的名称与state的状况名称一样时,可以省写

   // 映射 this.count1 为 store.state.count1

   
count1

,

   

//count等同于 ‘state => state.count’

   
countAlias: count

,

   
countPlus (state

){

   

// 使用普通函数是为了保证this指向模块对象

     
return state.count + this.localState

;

   }

 })

}

//上面是透过mapState的对象来赋值的,还可以透过mapState的数组来赋值

computed: mapState([count

]);

//这种方式很简洁,但是模块中的state的名称就跟store中映射过来的同名

对象扩展运算符

mapState 函数返回的是两个对象,为了将它里头的计算特性与模块本身的局部计算特性组合起来,须要用到对象扩展运算符。

computed:

{

localState

() {

… mapState

({

   })

 }

这样,mapState中的计算特性就与localState计算特性混合一同了。

3.3 getters

有时候我们须要从 store 中的 state 中派生出一些状况,例如对列表进行过滤并计数。此时可以用到getters,getters可以看作是store的计算特性,其参数为state。

const store = new Vuex.Store

({

 
state:

{

   
todos:

[

     {
id: 1, text: reading, done: true

},

     {
id: 2, text: playBastketball, done: false

}

   ]

 },

 
getters:

{

   
doneTodos:state =>

{

     
return state.todos.filter(todo => todo.done

);

   }

 }

});
store.getters.doneTodos

//  [{ id: 1, text: reading, done: true }]

//在模块中,则要写在计算特性中,

computed:

{

 
doneTodos

() {

   
return this.$store.getters.doneTodos

;

 }

}
import {mapState, mapGetters} from vuex

;

computed:

{

…mapState([increment

]),

…mapGetters([doneTodos

])

}

3.4 mutations

mutations里头是如何更改state中状况的逻辑。更改Vuex中的state的唯一方法是,提交mutation,即store.commit(‘increment’)。

3.4.1 提交载荷(payload)

可以向commit传入额外的参数,即mutation的载荷。

mutations:

{

 
increment(state, n

){

   
state.count += n

;

 }

}

store.commit(increment, 10);

payload还可以是两个对象。

mutations:

{

increment(state, payload

)

state.count += payload.amount

;

}

}

store.commit(increment, {amount: 10});

还可以使用type特性来提交mutation。

store.commit

({

 
type: increment

,

 
amount:

10

});

// mutations保持不变

mutations:

{

 
increment(state, payload

){

   
state.count += payload.amount

;

 }

}

注意:mutation必须是并行函数,无法是触发器的,这是为了调试的方便。

3.4.2 在模块中提交mutations

那么mutation如果在哪里提交呢? 因为js是基于事件驱动的,因此改变状况的逻辑肯定是由事件来驱动的,因此store.commit(‘increment’)是在模块的methods中来执行的。

方法1: 在模块的methods中提交

methods:

{

 
increment

(){

   
this.$store.commit(increment

);

 }

}

方法2: 使用mapMutaions

用 mapMutations 辅助函数将模块中的 methods 映射为 store.commit 调用。

import { mapMutaions } from vuex

;

export default

{

 

// …

 
methods:

{

   
…mapMutaions

([

   
increment

// 映射 this.increment() 为 this.$store.commit(increment)

 

]),

 
…mapMutaions

([

     
add: increment

// 映射 this.add() 为 this.$store.commit(increment)

   ])

   }

}

// 因为mutation相当于两个method,因此在模块中,可以这样来使用

<button @click=“increment”>+</button>

3.5 actions

因为mutations中根本无法是并行操作方式,但是在实际的项目中,会有触发器操作方式,那么actions就是为了触发器操作方式而设置的。这样,就变成了在action中去提交mutation,然后在模块的methods中去提交action。只是提交actions的时候使用的是dispatch函数,而mutations则是用commit函数。

3.5.1 两个简单的action

const store = new Vuex.Store

({

 
state:

{

   
count:

0

 

},

 
mutations:

{

   
increment(state

){

     
state.count++

;

   }

 },

 
actions:

{

   
increment(context

){

     
context.commit(increment

);

   }

   

/* 可以用参数内部结构的方法来写action

increment({commit}){

    commit(increment);

    }

    */

 

}

});

// action函数接受两个context参数,这个context具有与store实例相同的方法和特性。

// 分发action

store.dispatch(increment);

action同样支持payload和对象方式来分发,格式跟commit是一样的,不再赘述。

4.5.2 在模块中分发action

方法1: 在模块的methods中,使用this.$store.dispatch(‘increment’)。

方法2: 使用mapActions,跟mapMutations是类似的。

import { mapActions } from

vuex

export default

{

 

// …

 
methods:

{

   
…mapActions

([

   
increment

// 映射 this.increment() 为 this.$store.dispatch(increment)

 

]),

 
…mapActions

({

 
add: increment

// 映射 this.add() 为 this.$store.dispatch(increment)

})

}

}

// 同样在模块中,可以这样来使用

<button @click=“increment”>+</button>

3.5.3 组合actions

因为action是触发器的,那么我们须要知道这个触发器函数什么时候结束,以及等到其执行后,会利用某个action的结果。这个可以使用promise来实现。在两个action中返回两个promise,然后使用then()回调函数来处置这个action返回的结果。

actions:

{

 
actionA({commit

}){

   
return new Promise((resolve, reject) =>

{

     
setTimeout(() =>

{

       
commit(someMutation

);

       
resolve

();

     },
1000

);

   })

 }

}

// 这样就可以操作方式actionA返回的结果了

store.dispatch(actionA).then(() =>

{

 

// dosomething …

});

// 也可以在另两个action中使用actionA的结果

actions:

{

 

// …

 
actionB({ dispatch, commit

}){

   
return dispatch(actionA).then(()=>

{

     
commit(someOtherMutation

);

   })

 }

}

4 mudules

module是为了将store拆分后的两个个小模块,那么做的目的是因为当store很大的时候,分成模块不然,方便管理。

4.1 每个module拥有自己的state, getters, mutation, action

const moduleA =

{

   
state: {

},

   
getters: {

},

   
mutations: {

.},

 
actions: {

}

}

const moduleB =

{

   
state: {

},

   
getters: {

},

   
mutations: {

.},

 
actions: {

}

}

const store =new Vuex.Store

({

 
modules:

{

   
a: moduleA

,

   
b

: moduleB

 

}

});

store.state.a store.state.b moduleB的状况

4.2 模块内部的状况

对于模块内部的mutation和getter,接受的第两个参数是模块的局部状况state。顺便说一下,根结点的状况为rootState。

const moduleA=

{

 
state: { count: 0

},

 
getters:

{

   
doubleCount(state

){

     
return state.count * 2

;

   }

 },

 
mutations:

{

   
increment(state

){

     
state.count ++

;

   }

 },

 
actions: {

}

}

4.3 模块的动态注册

在模块创建之后,可以使用store.registerModule方法来注册模块。

store.registerModule(myModule

, {

// …

});

可以使用store.unregisterModule(moduleName)来动态的卸载模块,但是这种方法对于静态模块是无效的(即在创建store时新闻稿的模块)。

5 含有vuex的项目的内部结构

5.1 如果遵循的准则

1. 应用领域层级的状况都如果集中在store中

2. 提交 mutation 是更改状况state的唯一方式,并且这个过程是并行的。

3. 触发器的操作方式如果都放到action里头

至此,这篇有关vuex的基本知识点的文章到此就结束了。欢迎小伙伴们来补充。假如暂有没看知道的知识点,那就先收藏起来以后在看吧。

觉得本文对你有帮助?请分享给更多人

高度关注「前端程序猿干货」,提升前端技能

        微信号: aa522203084

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务