vuex学习实践笔记
2017.04.04
hzzly
Vuex是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
栗如(travel store):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| import * as types from '../types'
const state = { travelsList: [], searchKey: { page: 0, limit: 20 }, scroll: true }
const actions = {
getTravelsList({ commit }) { if(state.scroll) { commit(types.GET_TRAVELS_PAGE_NUM) commit(types.COM_LOADING_STATUS, true), commit(types.GET_TRAVELS_SCORLL_STATUS, false) api.TravelsList() .then(res => { console.log(res) commit(types.COM_LOADING_STATUS, false), commit(types.GET_TRAVELS_SCORLL_STATUS, true) commit(types.GET_TRAVELS_LIST, res) }) } },
joinTravel({ commit }, id) { ... } }
const getters = { travelsList: state => state.travelsList, travelListIndex: state => state.travelsList.slice(0,4) }
const mutations = { [types.GET_TRAVELS_LIST](state, res) { if(state.searchKey.page <= 1) { state.travelsList = res.data } else { state.travelsList = state.travelsList.concat(res.data) } }, [types.GET_TRAVELS_SEARCH_KEY](state, params) { state.searchKey = params }, [types.GET_TRAVELS_PAGE_NUM](state) { state.searchKey['page'] += 1 }, [types.GET_TRAVELS_SCORLL_STATUS](state, status) { state.scroll = status } }
export default { state, actions, getters, mutations }
|
每一个 Vuex 应用的核心就是 store(仓库)。”store” 基本上就是一个容器,它包含着你的应用中大部分的状态(state)数据。
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交(commit) mutations。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
用一张图来理解一下
客户端(Client) -> action -> mutations -> state -> 客户端
可以看出在vuex中数据是单一流向的:视图(view)触发action,action提交(commit)到mutations,mutations改变state(数据),state的改变,相应的组件也会相应的更新。
1.State
单一状态树,唯一数据源,能够直接清晰的读懂数据的结构。
1.1在 Vue 组件中获得数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const state = { travelsList: [], searchKey: { page: 0, limit: 20 }, scroll: true }
data () { return { scroll: this.$store.state.scroll } },
|
1.2mapState 辅助函数
1 2 3 4 5 6 7 8 9 10
| computed: mapState([ 'scroll' ])
computed: { ...mapState({ 'scroll' }) }
|
2.Getters
对state数据进行过滤或直接返回
2.1在 Vue 组件中获得Getters数据
1 2 3 4 5 6 7 8 9 10 11
| const getters = { travelsList: state => state.travelsList, travelListIndex: state => state.travelsList.slice(0,4) }
data () { return { travelListIndex: this.$store.getters.travelListIndex } },
|
2.2mapGetters 辅助函数
1 2 3 4 5 6 7 8 9 10
| computed: mapGetters([ 'travelListIndex' ])
computed: { ...mapGetters({ 'travelListIndex' }) }
|
3.Mutations
要更改 Vuex 的 store 中的数据,唯一方法是提交 mutation。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行数据更改的地方。
1 2 3 4 5 6 7 8 9 10 11
| const mutations = { [types.GET_TRAVELS_LIST](state, res) { if(state.searchKey.page <= 1) { state.travelsList = res.data } else { state.travelsList = state.travelsList.concat(res.data) } }, ... }
|
当我们在这改变数据时,其它引用此state数据的 Vue 组件也会自动得到更新。
4.Actions
用户的一些行为,来提交到mutations改变数据。可在这进行异步操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const actions = { getTravelsList({ commit }) { if(state.scroll) { commit(types.GET_TRAVELS_PAGE_NUM) commit(types.COM_LOADING_STATUS, true), commit(types.GET_TRAVELS_SCORLL_STATUS, false) api.TravelsList() .then(res => { console.log(res) commit(types.COM_LOADING_STATUS, false), commit(types.GET_TRAVELS_SCORLL_STATUS, true) commit(types.GET_TRAVELS_LIST, res) }) } }, joinTravel({ commit }, id) { ... } }
|
4.1分发 Action
1 2 3 4 5
| created() { if (this.travelListIndex.length == 0) { this.$store.dispatch('getTravelsList') } },
|
4.2mapActions 辅助函数
1 2 3 4 5
| methods: { ...mapActions([ 'getTravelsList' ]), }
|
5.Modules
当应用变得很大时,store 对象会变得臃肿不堪。为了解决这个问题,Vuex 允许我们将 store 分割到模块(module)。每个模块拥有自己的 state、mutation、action、getters
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a store.state.b
|
6.项目实践