vuex入门教程

对于vuex的基本API去vuex官网上讲的很详细(比vue稍强 哈哈~~)https://vuex.vuejs.org/zh/api/#vuex-store
直接进入正题

目录结构

创建一个store的文件夹,如果项目比较庞大,建议将每个项目所使用到的数据按照模块分出来,将所有的都放在统一的一个文件夹(modules)中。modules文件同级创建一个index,在这index中导入vue,vuex,使用Vuex store 注册store。
文件结构
index.js 文件

import Vue from 'vue'
import Vuex from 'vuex'

import user from './modules/user'
import common from './modules/common'
import test from './modules/test'

Vue.use(Vuex)//为vue 添加vuex的功能

export default new Vuex.Store({ 
  modules: {
    user,
    common,
    test
  }
})

state:数据仓库

Mutation:改变VueX的state中状态的唯一方法提交mutation

export default {
  namespaced: true,
  //分模块化管理,为了解决不同模块的命名冲突问题,将不同模块的namespaced:true,之后再不同页面中引入getter,action,mutations的时候,需要加上所属模块的模块名
  state: {
    name: '张三',
    age: 10,
    twoName: '张三'
  },
  mutations: {
    // 第一个参数是state,第二个参数是传递的参数
    updateName(state, data) {
      state.name = data.name;
    },
    updateAge(state, data) {
        state.age = data.age
    }
  },
}

// test.vue
<template>
  <div>
    <span>{{age}}</span>
    <button @click="addAge">++增加++</button>
  </div>
</template>

<script>
export default {
  methods: {
    addAge() {
      //这里的commit只能传递两个参数,参数1:path,参数2:object
      this.$store.commit("test/updateAge", {
        age: this.age + 1
      });
    }
  },
  // computed具有缓存的功能
  computed: {
    age() {
      return this.$store.state.test.age;
    },
  }
};
</script>
Mutation 必须是同步函数?
<template>
  <div>
    <span>{{age}}</span>
    <button @click="addAge">++增加++</button>
  </div>
</template>

<script>
export default {
  methods: {
    addAge() {
      //这里的commit只能传递两个参数,参数1:type,参数2:object
      this.$store.commit("test/updateAge", {
        age: this.age + 1
      });
    }
  },
};
</script>

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述当我们点击一次增加按钮之后,我们发现mutation中的age变化了,但是state中的age没有变化,当我们第二次点击的时候state中更新的是上一次的age,但是mutataion中的还是罪行的age。
引用官网的解说:我们正在 debug 一个 app 并且观察 devtool 中的 mutation 日志。每一条 mutation 被记录,devtools 都需要捕捉到前一状态和后一状态的快照。然而,在上面的例子中 mutation 中的异步函数中的回调让这不可能完成:因为当 mutation 触发的时候,回调函数还没有被调用,devtools 不知道什么时候回调函数实际上被调用——实质上任何在回调函数中进行的状态的改变都是不可追踪的。所以这里出现了延迟,也就是说用了异步回掉函数操作数据,数据的状态改变是不可追踪的。 注意:状态并不是不会生效,而是不可追踪。
当我们多次操作的时候,如果出现报错的情况,我们参考的数据是有问题的,就会造成我们调试的时候误判。

actions:异步状态更新

mutation只能进行同步的状态更新,当我们要使用异步的状态更新的时候我们就需要用到actions,Action使用的时候是直接提交一个commit到mutations中,所以最终的更新状态也是在mutations中进行的。

export default {
  namespaced: true,
  state: {
    name: '张三',
    age: 10,
    twoName: '张三'
  },
  mutations: {
    // 第一个参数是state,第二个参数是传递的参数
    updateName(state, data) {
      state.name = data.name;
    },
    updateAge(state, data) {
      state.age = data.age
    }
  },
  actions: {
    changeName(context, data) {
      setTimeout(() => {
        context.commit('updateName', {
          name: data.name
        })
      }, 1000);
    },
    changeAge(context, data) {
      setTimeout(() => {
        context.commit('updateAge', {
          age: data.age
        })
      }, 1000);
    }
  },
}

// test.vue
<template>
  <div>
    <span>{{age}}</span>
    <button @click="addAge">++增加++</button>
  </div>
</template>

<script>
export default {
  methods: {
    addAge() {
      this.$store.dispatch("test/changeAge", {
        age: this.age + 1
      });
    }
  },
  computed: {
    name() {
      return this.$store.state.test.name;
    },
    age() {
      return this.$store.state.test.age;
    },
  }
};
</script>

getters

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

export default {
  namespaced: true,
  //分模块化管理,为了解决不同模块的命名冲突问题,将不同模块的namespaced:true,之后再不同页面中引入getter,action,mutations的时候,需要加上所属模块的模块名
  state: {
    name: '张三',
    age: 10,
    twoName: '张三'
  },
  // 和computed一样,带有缓存,以来对象变换的时候会重新计算
  getters: {
    twoName(state) {
      let statusText = '失恋了'
      if (state.name === '张三') {
        return state.name + statusText
      }
    }
  }
}

// test.vue
<template>
  <div>
    <span>{{twoName}}</span>
  </div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
  computed: {
    ...mapGetters('test',['twoName'])
  }
};
</script>

辅助函数

当我们需要操作的数据或者方法很多的时候是可以使用辅助函数。

// test.js 文件
export default {
  namespaced: true,
  //分模块化管理,为了解决不同模块的命名冲突问题,将不同模块的namespaced:true,之后再不同页面中引入getter,action,mutations的时候,需要加上所属模块的模块名
  state: {
    name: '张三',
    age: 18,
    msg: ''
  },
  mutations: {
    updataName(state, data) {
      state.name = data.name;
    },
    updataAge(state, data) {
      state.age = data.age;
    }
  },
  actions: {
    changeAge(context, data) {
      context.commit('updataAge', {
        ...data
      });
    }
  },
  // 和computed一样,带有缓存,以来对象变换的时候会重新计算
  getters: {
    msg(state) {
      return state.name + state.age
    }
  }
}

// test.vue 文件
<template>
  <div>
    <div>{{name}}</div>
    <div>{{age}}</div>
    <div>{{msg}}</div>
    <button @click="handleName">改名</button>
    <button @click="handleAge">该年龄</button>
  </div>
</template>

<script>
import { mapActions, mapState, mapMutations, mapGetters } from "vuex";
export default {
  computed: {
    ...mapState({
      name: state => state.test.name,
      age: state => state.test.age,
      msg: state => state.test.msg
    }),
    ...mapGetters("test", ["msg"])
  },
  methods: {
    ...mapMutations("test", ["updataName"]),
    ...mapActions("test", ["changeAge"]),
    handleName() {
      this.updataName({ name: "李四" });
    },
    handleAge() {
      this.changeAge({ age: 99 });
    }
  }
};
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值