Open zhangzheng-zz opened 4 years ago
一个Vuex应用的核心就是store(仓库),包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:
Vuex
store
state
Vuex 的状态存储是响应式的。当Vue 组件从 store 中读取状态的时候,若store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。(和Vue组件中的data数据有着相同的响应式功能)
Vue
data
不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
commit
mutation
new Vue({ // state data () { return { count: 0 } }, // view template: ` <div>{{ count }}</div> `, // actions methods: { increment () { this.count++ } } })
这个状态自管理应用包含以下几个部分:
state,驱动应用的数据源;
view,以声明方式将 state 映射到视图;
actions,响应在 view 上的用户输入导致的状态变化。
但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
多个组件会共享状态时,组件间(兄弟组件、父子组件、无关系的组件)通信变的不容易。我们把共享状态抽取出来,用单向数据流的方式会变得更加方便。
应用层级的状态应该集中到单个 store 对象中。
提交mutation 是更改状态的唯一方法,并且这个过程是同步的。
异步逻辑都应该封装到 action 里面。
action
store ├── index.ts # 组装模块并导出 store 的地方 ├── initailState.ts # 初始化 store 数据的地方 ├── actions.ts # 根级别的 action ├── service.ts # 处理 axios 请求的地方 ├── mutations.ts # 根级别的 mutation └── mutationsTypes.ts # 导出 mutation 的类型的常量
Vuex 使用单一状态树——用一个对象就包含了全部的应用层级状态
// initailState.ts 导出了`default`数据 export default { count: 0 }
State 用来存状态, createStore函数创建了一个store并最终注册到Vue根实例中,之后在Vue的任何组件中可以通过 this.$store.state来访问state中的状态
State
createStore
this.$store.state
// index.ts import Vue from 'vue' import Vuex from 'vuex' import mutations from './mutations' import actions from './actions' import defaultState from './initailState' Vue.use(Vuex) export default function createStore (initailState = {}) { return new Vuex.Store({ state: { ...defaultState, ...initailState }, mutations, actions }) }
在前面说过,状态的改变必须遵循单向数据流思想,在任何地方想要改变State中的状态,只能通过提交(commit)Mutations, 来改变。需要注意的是,Mutations 里的修改状态的操作必须是同步的。 提交Mutations的方法:
Mutations
store.commit({ type: 'increment', amount: 10 })
type是Mutation事件类型,amount是提交至Mutation的形参,为了方便管理,一般在mutationsTypes.ts中统一定义type常量
type
Mutation
amount
mutationsTypes.ts
// mutationsTypes.ts export const INCREMENT = 'increment'
// mutations.ts import { INCREMENT } from './mutationsTypes.ts' export default { [INCREMENT] (state, amount: number) { // 在这里改变 state 的状态 state.count = amount } }
有时候,我们需要异步地去更改State的状态,例如通过axios请求得到数据更改state中的状态并更新到页面中,这时候我们需要actions,actions本质上与mution没有区别也是一个function, 只不过actions是通过dispatch来派发,并且是一个异步执行的操作,要最终更改State的状态,还需要在actions中通过调用 Mutations 来改状态。
axios
actions
mution
function
dispatch
使用dispatch派发action :
store.dispatch({ // actions 类型名称 type: 'querySomeThing', // 形参 param: 'ok' })
// service.ts 中保存了 axios 操作 export const getSomeThing = () => $axios.get('xxxx') .then( res => res.data ) .catch( e => console.error(e) )
// actions.ts import { getSomeThing } from './service' import { INCREMENT } from './mutationsTypes.ts' async querySomeThing ({ state, commit, dispatch }, { param }) { // 逻辑处理 示例 await res = getSomeThing() if( res.par === param ) { // 在 actions 中通过 commit mutaion 来改变 State 中的状态 commit(INCREMENT, res.count) } // ... // ... // 同样的,在 action 中也可以 dispatch 其他的 action dispatch({ type: 'queryAct' }) } async queryAct () { // ...... }
Vuex 是什么?
一个
Vuex
应用的核心就是store
(仓库),包含着你的应用中大部分的状态 (state
)。Vuex
和单纯的全局对象有以下两点不同:Vuex
的状态存储是响应式的。当Vue
组件从store
中读取状态的时候,若store
中的状态发生变化,那么相应的组件也会相应地得到高效更新。(和Vue
组件中的data
数据有着相同的响应式功能)不能直接改变
store
中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit
)mutation
。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。状态管理与单项数据流
从一个简单的 Vue 计数应用开始:
这个状态自管理应用包含以下几个部分:
state,驱动应用的数据源;
view,以声明方式将 state 映射到视图;
actions,响应在 view 上的用户输入导致的状态变化。
单向数据流指只能从一个方向来修改状态。
但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
多个组件会共享状态时,组件间(兄弟组件、父子组件、无关系的组件)通信变的不容易。我们把共享状态抽取出来,用单向数据流的方式会变得更加方便。
Vuex 集中式的状态管理模式
Vuex
规定了一些需要遵守的规则:应用层级的状态应该集中到单个
store
对象中。提交
mutation
是更改状态的唯一方法,并且这个过程是同步的。异步逻辑都应该封装到
action
里面。对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是
store
的项目结构示例:State
Vuex 使用单一状态树——用一个对象就包含了全部的应用层级状态
State
用来存状态,createStore
函数创建了一个store
并最终注册到Vue
根实例中,之后在Vue
的任何组件中可以通过this.$store.state
来访问state
中的状态Mutations
在前面说过,状态的改变必须遵循单向数据流思想,在任何地方想要改变
State
中的状态,只能通过提交(commit
)Mutations
, 来改变。需要注意的是,Mutations 里的修改状态的操作必须是同步的。 提交Mutations
的方法:type
是Mutation
事件类型,amount
是提交至Mutation
的形参,为了方便管理,一般在mutationsTypes.ts
中统一定义type
常量Actions
有时候,我们需要异步地去更改
State
的状态,例如通过axios
请求得到数据更改state
中的状态并更新到页面中,这时候我们需要actions
,actions
本质上与mution
没有区别也是一个function
, 只不过actions是通过dispatch
来派发,并且是一个异步执行的操作,要最终更改State
的状态,还需要在actions
中通过调用 Mutations 来改状态。使用
dispatch
派发action
:总结
Vuex的整体单向数据流程可以概括为:
组件中触发 Action,Action 提交 Mutations,Mutations 修改 State。
组件根据 State 响应式渲染页面