zhangzheng-zz / blog

1 stars 0 forks source link

Vuex学习 #2

Open zhangzheng-zz opened 4 years ago

zhangzheng-zz commented 4 years ago

Vuex 是什么?

一个Vuex应用的核心就是store(仓库),包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:

多个组件会共享状态时,组件间(兄弟组件、父子组件、无关系的组件)通信变的不容易。我们把共享状态抽取出来,用单向数据流的方式会变得更加方便。

Vuex 集中式的状态管理模式

Vuex规定了一些需要遵守的规则:

对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是store的项目结构示例:

 store
    ├── index.ts                       # 组装模块并导出 store 的地方
    ├── initailState.ts                # 初始化 store 数据的地方
    ├── actions.ts                     # 根级别的 action
    ├── service.ts                     # 处理 axios 请求的地方
    ├── mutations.ts                   # 根级别的 mutation
    └── mutationsTypes.ts              # 导出 mutation 的类型的常量    

State

Vuex 使用单一状态树——用一个对象就包含了全部的应用层级状态

// initailState.ts 导出了`default`数据
export default {
  count: 0
}

State 用来存状态, createStore函数创建了一个store并最终注册到Vue根实例中,之后在Vue的任何组件中可以通过 this.$store.state来访问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
    })
}

Mutations

在前面说过,状态的改变必须遵循单向数据流思想,在任何地方想要改变State中的状态,只能通过提交(commitMutations, 来改变。需要注意的是,Mutations 里的修改状态的操作必须是同步的。 提交Mutations的方法:

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

typeMutation事件类型,amount是提交至Mutation的形参,为了方便管理,一般在mutationsTypes.ts中统一定义type常量

// mutationsTypes.ts
export const INCREMENT = 'increment'
// mutations.ts
import { INCREMENT } from './mutationsTypes.ts'
export default {
   [INCREMENT] (state, amount: number) {
      // 在这里改变 state 的状态
      state.count = amount
   }
}

Actions

有时候,我们需要异步地去更改State的状态,例如通过axios请求得到数据更改state中的状态并更新到页面中,这时候我们需要actionsactions本质上与mution没有区别也是一个function, 只不过actions是通过dispatch来派发,并且是一个异步执行的操作,要最终更改State的状态,还需要在actions中通过调用 Mutations 来改状态。

使用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的整体单向数据流程可以概括为:

组件中触发 Action,Action 提交 Mutations,Mutations 修改 State。

组件根据 State 响应式渲染页面

Vuex-state