1, 为什么要用 vuex
在 vue 组件通信的过程中, 我们通信的目的往往就是在组件之间传递数据或组件的状态 (这里将数据和状态统称为状态), 进而更改状态. 但可以看到如果我们通过最基本的方式来
进行通信, 一旦需要管理的状态多了, 代码就会变得十分混乱. 对所有状态的管理便会显得力不从心, 尤其是多人合作的时候. 此时 vuex 出现了, 他就是帮助我们把公用的状态全抽出来放
在 vuex 的容器中, 然后根据一定的规则来进行管理.
2, 概念
概念: vuex 是一个状态管理工具, 每一个 Vuex 应用的核心就是 store(仓库);"store" 基本上就是一个容器, 它包含着你的应用中大部分的状态 (state), 它的实例是唯一的 ----- 单例模式; 一般把需要共享的数据放到 store 中;
功能: 存数据, 取数据, 改数据;
出现场景:
涉及到非父子关系的组件, 例如兄弟关系, 祖孙关系, 甚至更远的关系组件之间的联系;
在大型单页应用中, 考虑如何更好地在组件外部管理状态;
注意: vuex 的数据处理流程是一个 "单向" 的数据流 ;
vuex 的核心:
state: 存放数据 (状态); 取数据 this.$store.state. 变量名
mutations: 存放如何更改状态, 同步方法放到 mutations(同步) 里面; 调用方法 this.$store.commit("方法名","参数")
getters: 相当于计算属性, 从 state 中派生出状态, 比如将 state 中的某个状态进行过滤然后获取新的状态; this.$store.getters. 方法名 (sum)
actions:mutations 的加强版, 异步方法放在了 actions(动作) 里面; 调用方法 this.$store.dispatch("方法名"), 异步方法则会调用 mutations 里面的同步方法
modules: 就是当用这个容器来装这些状态还是显得混乱的时候, 我们就可以把容器分成几块, 把状态和管理规则分类来装. 这和我们创建 JS 模块是一个目的, 让代码结构更清晰.
3, 基本使用
vuex 的安装
cnpm i vuex --save
安装成功后,
新手入门
新建 store 文件夹, 内容如下
在 App.JS 里面进行引入
- import store from './store'
- new Vue({
- router,
- I18N,
- store,
- el: '#app',
- render: h => h(App)
- })
store 文件夹中 index.JS 的内容为
- import Vue from 'vue'
- import Vuex from 'vuex'
- import state from './state'
- import actions from './actions'
- import mutations from './mutations'
- Vue.use(Vuex)
- export default new Vuex.Store({
- state,
- actions,
- mutations
- })
在 state.JS 中定义状态
- export default {
- count: 1,
- }
在 mutations.JS 里面定义同步方法
- export default {
- // 改变状态的执行者 用于同步更改状态
- stateMutationsAdd(state, payLoad) {
- // 第一个参数是 state 第二个参数是调用 mutations 时传入的参数
- state.count += payLoad;
- },
- stateMutationsReduce(state, payLoad) {
- state.count -= payLoad;
- }
- }
在 actions.JS 里面定义异步操作
- export default {
- // actions 并不直接更改状态 而是发起 mutations 来更改状态
- stateAsyncReduce(context) {
- // context 是一个与 store 实例具有相同方法和属性的 context 对象
- // 这个异步操作 我们可以发送 http 请求, 定时器,
- setTimeout(() => {
- context.commit("stateMutationsReduce", 5)// 不能用 this.$store, 为 undefined
- }, 1000)
- }
- }
在 vue 组件中使用 (将 state 与 getters 结合进组件需要使用计算属性, 将 mutations 与 actions 结合进组件需要在 methods 里面进行调用)
- <template>
- <div class="home">
- <div class="block">
- <h1>vuex 的基本使用 </h1>
- <el-button size="mini" type="primary" @click="reduceNumber">-</el-button>
- {{count}}
- <el-button size="mini" type="primary" @click="addNumber">+</el-button>
- <h1>vuex 练习结束 </h1>
- </div>
- </div>
- </template>
- <script>
- export default {
- name: "home",
- data() {
- return {};
- },
- computed: {
- count() {
- return this.$store.state.count;
- }
- },
- methods: {
- /**
- * [addNumber 对 count 数据进行增加操作 采用同步方式]
- * @return {[type]} [description]
- */
- addNumber() {
- // 第一个参数是同步方法的名称 第二个参数是传递给方法的数据
- this.$store.commit("stateMutationsAdd", 10);
- },
- /**
- * [reduceNumber 对 count 数据进行减少操作 采用异步方式]
- * @return {[type]} [description]
- */
- reduceNumber() {
- // dispatch 返回的是 actions 执行的结果, 是一个 promise 对象, 如果异步操作之后还需要其他操作, 可以使用. then/.catch 等
- this.$store.dispatch("stateAsyncReduce");
- }
- },
- mounted() {}
- };
- </script>
- View Code
效果图
点击 + 进行同步增加
点击 - 进行异步减少, 每隔 1s 减少 5
新手入门之后, 我们可以尝试将 mutations 里面的一些方法名称提取出来, 从而提高代码维护性;
state.JS
- export default {
- count: 1,
- }
- mutation-types.JS
- export const STATE_MUTATIONS_ADD = 'stateMutationsAdd'
- export const STATE_MUTATIONS_REDUCE = 'stateMutationsReduce'
mutations.JS
- import { STATE_MUTATIONS_ADD, STATE_MUTATIONS_REDUCE } from './mutation-types'
- export default {
- // 改变状态的执行者 用于同步更改状态
- [STATE_MUTATIONS_ADD](state, payLoad) {
- // 第一个参数是 state 第二个参数是调用 mutations 时传入的参数
- state.count += payLoad;
- },
- [STATE_MUTATIONS_REDUCE](state, payLoad) {
- state.count -= payLoad;
- }
- }
- View Code
actions.JS
- import { STATE_MUTATIONS_ADD, STATE_MUTATIONS_REDUCE } from './mutation-types'
- export default {
- // actions 并不直接更改状态 而是发起 mutations 来更改状态
- stateAsyncReduce(context) {
- // context 是一个与 store 实例具有相同方法和属性的 context 对象
- // 这个异步操作 我们可以发送 http 请求, 定时器,
- setTimeout(() => {
- context.commit(STATE_MUTATIONS_REDUCE, 5)// 不能用 this.$store, 为 undefined
- }, 1000)
- }
- }
- View Code
vue 组件中的使用
- <template>
- <div class="home">
- <div class="block">
- <h1>vuex 的基本使用 </h1>
- <el-button size="mini" type="primary" @click="reduceNumber">-</el-button>
- {{count}}
- <el-button size="mini" type="primary" @click="addNumber">+</el-button>
- <h1>vuex 练习结束 </h1>
- </div>
- </div>
- </template>
- <script>
- import {
- STATE_MUTATIONS_ADD,
- STATE_MUTATIONS_REDUCE
- } from "../store/mutation-types";
- export default {
- name: "home",
- data() {
- return {};
- },
- computed: {
- count() {
- return this.$store.state.count;
- }
- },
- methods: {
- /**
- * [addNumber 对 count 数据进行增加操作 采用同步方式]
- * @return {[type]} [description]
- */
- addNumber() {
- // 第一个参数是同步方法的名称 第二个参数是传递给方法的数据
- this.$store.commit(STATE_MUTATIONS_ADD, 10);
- },
- /**
- * [reduceNumber 对 count 数据进行减少操作 采用异步方式]
- * @return {[type]} [description]
- */
- reduceNumber() {
- // dispatch 返回的是 actions 执行的结果, 是一个 promise 对象, 如果异步操作之后还需要其他操作, 可以使用. then/.catch 等
- this.$store.dispatch("stateAsyncReduce");
- }
- },
- mounted() {}
- };
- </script>
- View Code
为了方便起见, 利用 vuex 提供的 mapState,mapGetters,mapMutations 以及 mapActions 四个方法将这些功能结合进组件
其他文件跟上述保持一致
vue 组件中的使用
4, 遇到的问题
来源: http://www.bubuko.com/infodetail-3316744.html