对于状态管理,有现成的vuex
和redux
等框架,能方便我们的开发,但在使用这些框架的时候,还是有必要先了解下什么是状态管理。简单来说状态管理就是对应用中各变量的增删改查进行的管理,随着 SPA (单页面应用)被广泛使用,整个应用的数据,状态都散落在不同的变量中,有时候同一变量将在不同的组件中展示,当某个页面中修改了该变量后,同时需要修改该变量在其它组件上的值,修改后将重新渲染其它视图组件。通过flux
也能快速的理解状态管理,flux
的核心就是一个简单的约定,视图层不允许直接修改应用的状态,需要通过触发action
,然后将action
流到store
上,由于应用的状态是通过store
来管理的,当action
流到store
后,store
再对状态进行更改,然后store
再触发组件进行修改。
状态管理框架
前端状态管理框架用的最多的主要是vuex
和redux
,这两种框架的思想都差不多,下面对这两种框架进行简单的介绍。
redux
Redux
是javascript
的一个状态管理容器,通过Redux
可提供可预测性的状态管理。先看下Redux
的流程,然后再通过流程图来看Redux
中的一些核心概念和使用流程。
由图片可看出,主要由
Action
,Store
,Reducers
组成。组件端将Action
转发到Store
,Store
再将状态值和Action
传递给Reducers
进行处理,处理完成后,将新的状态值再传递给Store
,再对组件进行重新渲染。
Action
Action
是将数据从应用传递到Store
,并且action
是store
数据的唯一来源。一般需要使用store.dispatch()
将数据从action
传递到store
,如下所示:
let action = {
type: 'ADD_TODO',
text: 'Build my first Redux app'
}
dispatch(action)
Action
一般传递的类型为对象,将出要更改的数据封装成对象后,然后再通过dispatch
来发送数据。
Reducers
Reducers
指定了应用状态的变化如何响应actions
并发送到store
,只是记录了actions
有事件要发生,并没有描述应用如果更新到store
。reducer
是一个纯函数,用于接收旧的action
和state
,返回新的state
。如下所示:
function todoApp(state, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter
})
default:
return state
}
}
这里Object.assign
的第一个参数为一个空对象,是为了防止修改state
,使用assign
直接将两个对象的值合并到空对象上。
Store
Store
的作用是将Reducers
和Actions
关联到一起,Store
的主要职责如下所示:
- 维持应用的
state
,相当于保存一个全局变量。- 提供
getState()
获取state
。- 提供
dispatch(action)
更新action
。- 通过
subscribe(listener)
注册监听。- 通过
subscribe(listener)
返回的函数注销监听器。
vuex
vuex
是一个专门为vue.js
设计的一个状态管理框架,它采用集中式存储管理应用所有组件的状态,并以相应的规则保证状态以一种可预测的方式改变状态。概念跟redux
差不多,都是提供可预测性的状态管理方式。其流程图如下所示:
如图所示,vuex
的核心主要包括actions
,mutations
, state
三部分,由图也可以看出整个流程中的数据是单向流动的,组件派发actions
后,将actions
提交给mutations
,通过mutations
再对状态进行修改,修改完状态后再重新渲染组件。在整个过程中,只能通过mutations
来修改state
的值,不能手动修改state
的值。
state
vuex
中是使用单一的状态树来管理种状态值的。每个应用只包含一个 store 实例,相当于一个顶层的单例模式。然后将应用的各个状态保存在state
上,如果要获取一个状态,使用下面的方式进行获取:
this.$store.state.xxx
getter
在vuex
中可以使用getter
来过滤一些状态值。如下所示,在getters
中添加了一个doneTodos
函数,来获取todos
数组中done
属性值为true
的。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
其后再通过store.getters.doneTodo
来获取。
Mutation
更改store
中状态的唯一方法是提交mutation
。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,如下所示:
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
只能通过store.commit('increment')
来调用。
Action
Action
类似于 mutation
,不同在于:
Action
提交的是mutation
,而不是直接变更状态。Action
可以包含任意异步操作。
如下所示:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
Action
通过store.dispatch
方法触发:
store.dispatch('increment')
通过简单的对比了vuex
和redux
的状态管理,其核心思想都差不多,都是借助于flux
的思想用于管理数据的状态。
个人博客
网友评论