vuex

# Vuex基本结构

> State中的数据 -render-> 渲染到组件上 -进行操作 dispatch-> action -commit-> mutation -mutate-> state

***如果使用Vuex,代码量会更多,代码逻辑会更加清晰***

## state (状态)

> state中保存了数据,可以放在各个组件中的数据,组件想要获取到数据,有两种方式

### 1. 直接使用

```HTML

{{$store.state.state属性名}}

```

### 2. 利用计算属性

```HTML

```

## getters (从state中获取新数据)

> getter的作用可以从state中动态获取数据,当state数据改变时,对应的getter也一样会改变。getter中有两个参数,一个是state,第二个是getter

```javascript

const store = new Vuex.Store({

  state: {

  },

  getters: {

    getter (state, getter) {

      // 根据相关操作获取state以及其他getter中的数据

    },

    getterFn (state) {

      // 返回一个函数体

      return function (参数) {

        // 返回数据

        return 相关操作的到的数据

      }

    }

  }

})

```

### 1. 直接使用

```HTML

{{$store.getters.getter名字}}

```

### 2. 利用计算属性

```HTML

```

### mutations

> mutation只做纯粹的state数据修改操作,mutation需要被提交(commit)才能执行

***一般情况,state对应的都有mutation,有些不止一个***

```javascript

const store = new Vuex.Store({

  state: {

  },

  mutations: {

    mutation (state, payload) {

      // 因为mutation是对state操作,所以有state属性,在commit时,可以提交数据,所以payload就是commit时提交的数据,可以是任意名字

    }

  }

})

```

### 在组件中 'commit' mutation (不是很符合规范)

```javascript

export default {

  methods: {

    clickHandler () {

      this.$store.commit('mutation名字', '数据')

    }

  }

}

```

## actions

> action可以进行异步请求,将数据commit给mutation。action中还可以进行数据处理,将数据处理成mutation可以直接使用的数据

```javascript

const store = new Vuex.Store({

  state: {

    msg: "消息"

  },

  mutations: {

    setMsg (state, msg) {

      state.msg = msg

    }

  },

  actions: { 

    getMsg (context, payload) {

      // 根据相关的数据传递,将获取到payload发送给mutation

      context.commit('setMsg', payload)

    },

    getMsg ({commit}, payload) {

      commit('setMsg', payload)

    }

  }

})

```

> 在组件中 'dispatch' action

```javascript

export default {

  methods: {

    clickHandler () {

      this.$store.dispatch('action名字')

    }

  }

}

```

### 获取到action异步是否执行完成

> 我们只需要在对应的action中return一个promise对象 (action执行结束后就是一个promise对象,有.then方法)

```javascript

{

  actions: {

    async action名字 () {

      // return axios请求

      try {

        const res = await axios()

        对结果进行处理

      } catch (err) {

      }

    }

  }

}

```

## 在vue-cli中使用Vuex

### 1. 在创建项目时选择Vuex组件即可

### 2. 自己创建环境

1. 创建一个项目

2. 安装Vuex

3. 在项目中src里新建文件夹store/index.js

4. 在index.js中写以下内容

```javascript

// 1 引入Vue及Vuex

import Vue from 'vue'

import Vuex from 'vuex'

// 2 调用Vue.use

Vue.use(Vuex)

// 3 创建Store的实例

const store = new Vuex.Store({

  state: {},

  getters: {},

  mutations: {},

  actions: {}

})

// 4 将store作为模块导出

export default store

```

5. 在main.js中引入store

```javascript

import store from './store/index'

new Vue({

  store

})

```

# 辅助函数

> 解耦代码,可以让代码变得更简洁,只能在支持模块化的地方使用

* mapState

* mapGetters

* mapMutations

* mapActions

## mapState

```javascript

import { mapState } from 'vuex'

export default {

  computed: mapState(), // 这样写不能添加新的针对该组件的computed

  computed: {

    ...mapState(['state属性名', 'state属性名2']),

    ...mapState({

      自定义名字: 'state属性名',

      'state属性名': 'state属性名'

    }),

    // 相当于

    自定义名字 () {

      return this.$store.state.属性名

    }

  }

}

```

## mapGetters

```javascript

import { mapGetters } from 'vuex'

export default {

  computed: mapGetters(), // 这样写不能添加新的针对该组件的computed

  computed: {

    ...mapGetters(['getter名字']),

    ...mapGetters({

      自定义名字: 'getter名字'

    }),

    // 相当于

    自定义名字 () {

      return this.$store.getters.getter名字

    }

  }

}

```

## mapMutations

> mapMutation和mapActions放在methods中,会被映射成一个方法

```javascript

import {mapMutations} from 'vuex'

export default {

  methods: {

    ...mapMutations(['mutation名字']),

    ...mapMutations({

      自定义名字: 'mutation名字'

    }),

    // 相当于

    自定义名字 (data) {

      this.$store.commit('mutation名字', data)

    },

    // 如果在提交前需要进行其他操作

    自定义名字 () {

      // 其他操作

      this.mutation名字()

    }

  }

}

```

## mapActions

```javascript

import {mapActions} from 'vuex'

export default {

  methods: {

    ...mapActions(['action名字']),

    ...mapActions({

      自定义名字: 'actions名字'

    }),

    // 相当于

    自定义名字 (data) {

      this.$store.dispatch('action名字', data)

    },

    // 如果需要有其他操作

    自定义名字 () {

      // 其他操作

      this.action名字()

    }

  }

}

```

***如果不理解,就先不要去看,学会如果使用this.$store***

# 模块

```javascript

const store = new Vuex.Store({

  modules: {

    module名字: {

      // 每个模块都有自己独立state mutations actions getters 甚至还有modules

      state: {},

      getters: {},

      actions: {},

      mutations: {}

    }

  }

})

```

## 命名空间

> 我们可以给模块对象上添加namespaced: true

```javascript

const store = new Vuex.Store({

  modules: {

    module名字: {

      namespaced: true

    }

  }

})

```

*命名空间: 可以给我们的模块的getter mutation action上添加前缀 ‘模块名/’ 便于和其他模块以及root进行区分*

## state

> 模块中的state放在rootState下的模块名中 this.$store.state.模块名.属性名

```javascript

const store = new Vuex.Store({

  modules: {

    module名字: {

      namespaced: true,

      state: {

        msg: '模块中的数据'

      }

    }

  }

})

// this.$store.state.module名字.msg namespaced属性对state没有任何影响

```

## getters

> 所有模块的getter都放置在一起,为了区分,我们添加namespaced: true,这个时候,对应模块的getter就变成了 ‘模块名/getter名字’ 使用时 `this.$store.getters['模块名/getter名字']`

```javascript

const store = new Vuex.Store({

  modules: {

    module名字: {

      namespaced: true,

      getters: {

        getter (state, getters, rootState) {

          // 只有在模块中的getter中才有第三个参数,rootState可以只从其他模块获取数据 state指的是当前模块的state

        }

      }

    }

  }

})

```

## mutations

> 所有模块的,mutation都放置在一起,为了区分,我们添加namespaced: true,这个时候,对应模块的,mutation就变成了 ‘模块名/,mutation名字’ 使用时 `this.$store.commit('模块名/mutation名字')`

如果是在action中使用

1. 当前模块的action

  commit('mutation名字')

2. 其他模块的action

  commit('模块名/mutation名字', null, {root: true})

## actions

> 所有模块的,action都放置在一起,为了区分,我们添加namespaced: true,这个时候,对应模块的,action就变成了 ‘模块名/,action名字’ 使用时 `this.$store.dispatch('模块名/action名字')`

## 辅助函数写法

```

const store = new Vuex.Store({

  state: {

    a: 1

  },

  modules: {

    moduleA: {

      state: {

        b: 2,

        c: 3

      }

    }

  }

})

export default {

  computed: {

    ...mapState(['a', 'moduleA/b', 'moduleA/c']),

    ...mapState('moduleA', ['b', 'c'])

  }

}

```

你可能感兴趣的:(vuex)