vuex是做什么的
vue组件之间进行数据传递还是比较麻烦的,所以我们使用一个vuex仓库,统一管理数据和状态
通俗来说vuex就是专门为vue应用程序开发的状态管理模式,采用了集中式储存管理应用中所有组件状态,并且以应用的规则保证状态以一种可预测的方法发生变化
安装vuex npm i vuex@版本号,然后在main.js中进行引入
import Vue from "vue"; import App from "./App.vue"; Vue.config.productionTip = false; /** * 下载完毕以后先引入vuex * 然后调用vuex中的方法Vue.use(Vuex) * 然后注册store * 最后在Vue中进行store的声明 */ import Vuex from "vuex"; // 1 Vue.use(Vuex); // 2 const store = new Vuex.Store({}); // 3 new Vue({ store, // 4 render: (h) => h(App), }).$mount("#app");
定义state
state是放置公共状态的属性,如果有公共状态的数据,可以定义在state对象中,然后我们在别的组件中调用公共数据或者方法
this.$store.state.属性名进行获取
我们在main.js中放置我们的state公共数据
const store = new Vuex.Store({ /** * 定义state,state是放置公共状态的属性,如果有公共状态的数据,可以定义在state对象中 * 如何获取到state? * 我们在组件中可以使用this.$store获取到vuex中的store对象,可以通过state属性,属性获取到name * 跳转到App.vue进行获取 */ state: { name: `王路飞`, }, });
我们在App.vue中进行数据的获取
<h1>{{ this.$store.state.name }}</h1>
我们还可以将state属性定义在计算属性中,这样我们使用属性名就可以直接获取
<h1>{{ name }}</h1> /** * 我们可以将state属性定义在计算属性中 */ computed: { name() { return this.$store.state.name; }, },
辅助函数mapState
首先我们导入maoState,然后再computed中使用展开运算符获取到其中的数据
<template> <div> <h1>{{ this.$store.state.name }}</h1> <h1>{{ name }}</h1> <h1>{{ this.$store.state.age }}</h1> <h1>{{ age }}</h1> </div> </template> <script> // 1,导入mapState import { mapState } from "vuex"; export default { name: "App", /** * 我们可以将state属性定义在计算属性中 */ computed: { // 2,然后使用延展运算符,将导出的状态映射给计算属性 ...mapState(["name", "age"]), // name() { // return this.$store.state.name; // }, }, }; </script> <style lang="less"></style>
定义mutations
state数据的数据只能通过mutations进行修改,并且mutations必须是同步更新,形成数据快照,数据快照,一次mutations的执行,立刻得到一种视图状态,因为是立刻,所以必须是同步
首先我们main.js进性mutaions定影
const store = new Vuex.Store({ /** * 定义mutations,mutations是进行state进行数据修改的,必须是同步更新,目的是形成数据快照 * 数据快照,一次mutations的执行,立刻得到一种视图状态,因为是立刻,所以必须是同步 * mutations是一个对象,对象中存放修改state的方法 */ mutations: { /** * 注意点,方法里面参数,第一个参数是当前store的state属性 * payload载荷 进行运输参数 调用mutations的时候,可以传递参数 传递载荷 */ addCount(state) { state.age += 1; }, }, }); // 3
然后我们再App.vue组件中事件调用,来修改数据
创建点击按钮,点击事件使用store中mutations,进行数据修改,使用,commit调用mutations方法
<button @click="Jia">点击age+1</button> methods: { Jia() { /** * 掉用store中的mutations 提交给mutations * commit('定义的名称',传递的参数) */ this.$store.commit("addCount"); // 调用方法 }, },
传递给mutations参数获取参数进行修改
首先我们在App.vue中添加传递的参数,然后我们在自己定义的方法中接收参数,这里第一个参数是state,第二个参数是我们传递过来的参数
<button @click="Jia">点击age+1</button> methods: { Jia() { /** * 掉用store中的mutations 提交给mutations * commit('定义的名称',传递的参数) */ this.$store.commit("addCount"); // 调用方法 }, },
main.js中进行接收
mutations: { /** * 注意点,方法里面参数,第一个参数是当前store的state属性 * payload载荷 进行运输参数 调用mutations的时候,可以传递参数 传递载荷 */ addCount(state, pay) { state.age += pay; }, },
辅助函数mapMutations
首先我们在App.vue中引入mapMutations,然后再methods中映射,最后在点击事件中进行参数传递
<button @click="Jia">点击age+10</button> import { mapState, mapMutations } from "vuex"; methods: { ...mapMutations(["addCount"]), Jia() { /** * 掉用store中的mutations 提交给mutations * commit('定义的名称',传递的参数) */ // this.$store.commit("addCount", 10); // 调用方法 this.addCount(10); }, },
注意点,在mutations中不能写异步代码,也就是我们ajax请求不能写在这里
定义actios
state是存放数据的,mutations是同步更新数据的,actios则负责进行异步操作的
actios的规则,首先我们要知道,actios是不能对数据进行修改的,是通过mutations进行修改的。所以他会接受一个参数,state的参数,然后开启异步函数。使用接收到的state.commit进行参数向上传递。先获取到mutatios的事件,然后传递给mutatios,进行异步操作。
代码操作,我们在main.js中进行定义,获取到state数据,然后获取到mutations的事件,最后传递给他参数,进行异步操作
actions: { /** * 获取异步数据,context表示当前的store的实例,可以通过context.state获取数据状态 * 也可以通过context.commit来提交给mutations数据,让他进行修改 * 也可以 context.diapatch调用其他的action */ async(context) { setTimeout(function () { // 一秒钟之后, 给一个参数,修改state,这个参数会被pay接收到,进行修改 context.commit("addCount", 100); }, 1000); }, },
我们去App.vue中进行事件绑定
<button @click="xiu">点击异步修改age</button> methods: { xiu() { this.$store.dispatch("async"); }, },
actios传递参数
我们再App.vue中传递参数
<button @click="xiu">点击异步修改age</button> methods: { xiu() { this.$store.dispatch("async"); }, },
然后我们在main.js中接收参数,并且传递给mutations中进行修改
mutations: { /** * 注意点,方法里面参数,第一个参数是当前store的state属性 * payload载荷 进行运输参数 调用mutations的时候,可以传递参数 传递载荷 */ addCount(state, pay) { state.age += pay; }, }, actions: { /** * 获取异步数据,context表示当前的store的实例,可以通过context.state获取数据状态 * 也可以通过context.commit来提交给mutations数据,让他进行修改 * 也可以 context.diapatch调用其他的action */ async(context, pay) { setTimeout(function () { // 一秒钟之后, 给一个参数,修改state,这个参数会被pay接收到,进行修改 context.commit("addCount", pay); }, 1000); }, },
辅助函数mapActios
首先在App.vue中引入mapActios进行映射,然后进行修改
<button @click="xiu(200)">点击异步修改age</button> import { mapState, mapMutations, mapActions } from "vuex"; methods: { ...mapMutations(["addCount"]), ...mapActions(["async"]), Jia() { /** * 掉用store中的mutations 提交给mutations * commit('定义的名称',传递的参数) */ // this.$store.commit("addCount", 10); // 调用方法 this.addCount(10); }, xiu() { this.$store.dispatch("async", 200); }, },
定义getters
除恶了state之外,有时候我们还需要从state中派生出一些状态,这些状态是依赖state的,此时我们用到getters
列入我们state中有一个数组,然后我们只需要获取数组中大于5的数组,也就是说组件中,需要显示大于5的数据,需要进一步的对数据进行一个处理,getters可以帮助我们实现
首先我们在main.js中进行定义
state: { name: `王路飞`, age: 18, list: [1, 2, 3, 4, 5, 6, 7, 8, 9], }, getters: { /** * 有时候我们还需要从state中派生出来一些状态,这些状态都是依赖state的,此时会用到getters */ List: (state) => state.list.filter((i) => i > 5), },
然后我们在App.vue中进行数据的展示
<h1>{{ $store.getters.List }}</h1>
vuex中的模块化思想Modules
由于使用单一的状态树,应用的所有状态会集中到一个比较大的对象,当应用变得非常复杂的时候,store对象会变得非常臃肿
也就是说,所有的状态都放在state中,当项目变得越来越大的时候,Vuex就会变得非常难以维护,所以有了Vuex的模块化
模块化应用
我们定义两个模块user和setting。user中管理永华的状态和数据(token);setting中管理应用的状态和数据名称(name)
首先我们创建自己存放数据的文件夹store,里边创建index文件,进行注册Vuex和存放数据
store/index.js
// 1,引入vuex import Vue from "vue"; import Vuex from "vuex"; // 2,注册vuex Vue.use(Vuex); // 3,创建仓库 const store = new Vuex.Store({ state: { name: `王路飞`, age: 18, list: [1, 2, 3, 4, 5, 6, 7, 8, 9], }, mutations: { addCount(state, pay) { state.age += pay; }, }, actions: { async(context, pay) { setTimeout(function () { context.commit("addCount", pay); }, 1000); }, }, getters: { List: (state) => state.list.filter((i) => i > 5), }, }); export default store; // 导出,然后使用main.js进行接收
main.js进行接收和注入
import Vue from "vue"; import App from "./App.vue"; Vue.config.productionTip = false; // 1,引入store文件 import store from "@/store"; new Vue({ // 2,注入store文件 store, render: (h) => h(App), }).$mount("#app");
定义Mdoules模块
在store中创建Mdoules文件,然后再里边添加模块,添加一个user和setting模块,user中管理用户状态和数据,setting中管理应用的状态和数据,我们进行分割管理
我们在Mdoules/index.js文件中进行模块引用,然后暴漏模块数据和方法,页面进行调用和使用
首先我们再store文件下边创建mdoules文件,然后创建user.js和setting.js文件,把数据放在他们两个中,然后使用mdoules文件中index.js文件进行引入,最后再页面中进行数据和方法的调用
store/modeules/user.js&&setting.js中放入数据和方法
user.js
export default { namespaced: true, state: { token: `123456`, }, mutations: { // 定义一个方法,传递过来新的数据,进行修改 changeToken(state, pay) { state.token = pay; }, }, };
setting.js
export default { namespaced: true, state: { name: `时不我待`, }, mutations: { // 定义一个方法,传递过来新的数据,进行修改 changeName(state, pay) { state.token = pay; }, }, };
namespaced
其中namespaced的作用是确保数据和方法的私密性,不让外部可以直接调用方法进行修改数据
在modules/index中进行引入,user.js和setting.js。
然后将他们暴漏出去import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex); // 1,引入我们注册的组件 import user from "@/store/modules/user"; import setting from "@/store/modules/setting"; const store = new Vuex.Store({ // 2,把数据放在模块化中进行管理 modules: { user: user, settings: setting, },}); export default store;
我们在App.vue中进行调用,其中有3中方法
推荐使用这种方法,非常简单,直接使用点击事件,然后调用方法,传递参数,进行修改
<template> <div> <h1>用户token:{{ $store.state.user.token }}</h1> <button @click="cToken">点击修改用户token</button> </div> </template> <script> // 基于某个命名空间的命名函数createNamespacedHelpers export default { name: "App", computed: {}, methods: { cToken() { this.$store.commit("user/changeToken", "路漫漫其修远兮"); }, }, }; </script> <style lang="less"></style>
第二种方法,引入mapMutations,解构mapMutations,然后this调用方法传递参数
<template> <div> <h1>用户token:{{ $store.state.user.token }}</h1> <button @click="cToken">点击修改用户token</button> </div> </template> <script> // 基于某个命名空间的命名函数createNamespacedHelpers import { mapMutations } from "vuex"; export default { name: "App", computed: {}, methods: { ...mapMutations(["user/changeToken"]), cToken() { this["user/changeToken"]("路漫漫其修远兮"); }, }, }; </script> <style lang="less"></style>标签:actios,getters,mutations,js,state,参数,vuex,store From: https://www.cnblogs.com/hgng/p/17092451.html