VUEX总结

1.概念

专门在vue中实现集中式状态(数据)管理的一个vue插件,对vue应用中多个组件的共享状态进行集中的管理(读/写),

也是组件间的通信方式,且适用于任意组件间通信

2.什么时候用vuex:(共享)

多个组件依赖于同一状态

来自不同组件的行为需求变更同一状态

3.搭建vuex环境

(1).创建文件:src/store/index.js

// 引入vue
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'

// 使用vuex
Vue.use(Vuex)

// 准备actons--用于响应组件中的动作
const actions = {
    // jia(context,value){
    //     console.log('actions被调用',context,value);
    //     context.commit('JIA',value)
    // },
    // jian(context,value){
    //     console.log('actions被调用',context,value);
    //     context.commit('JIAN',value)
    // },
    jianOdd(context,value){
        console.log('actions被调用',context,value);
        if(context.state.sum % 2){
            context.commit('JIA',value)
        }
    },
    jianWait(context,value){
        console.log('actions被调用',context,value);
       setTimeout(() =>{
        context.commit('JIA',value)
       },1000)
    },
    
}
// 准备mutations--用于操作数据(state)
const mutations = {
    JIA(state,value){
        console.log('mutations被调用',state,value)
        state.sum += value
    },
    JIAN(state,value){
        console.log('mutations被调用',state,value)
        state.sum -= value
    }
}
// 准备state--用于存储数据
const state = {
    sum:0 //当前的求和
}

// 创建 并 暴露store
export default new Vuex.Store({
    // actions:actions,
    // mutations:mutations,
    // state:state
    // 简写
    actions,
    mutations,
    state
})

(2).在main.js中创建vm时传入store配置项

// 引入store
            import store from './store/index'
            new Vue({
                el:'#app',
                render: h => h(App),
                store,
                beforeCreate(){
                    Vue.prototype.$bus = this //安装全局事件总线
                }
            })

4.关系图

state

顾名思义,所有状态都将被存放在 State 中,类似 Vue 组件中的 data 属性,只不过 State 是面向整个应用,而 data 针对的是单个组件。在 Vue 入口页构造 Vue 实例的时候引入 store 之后,可以在组件中通过 this.$store.state 拿到。

getter

它类似于 Vue 组件中的 computed 计算属性,计算一些需要二次改造的数据。举个例子,我在 Vue 组件中通过 this.$store.state 拿到 State 中的某个数据,但是我需要对这个数据过滤,一个 filter 方法就能拿到过滤后的数据,但是我在很多地方都要使用这个 filter 过滤条件,那么我不断的去复制粘贴(CV 大法),或者将这个 filter 方法抽离到公用函数再引入组件,两种方法都很鸡肋。Getter 为我们解决了这个难题,你可以在 store 中定义 getter 属性,state 数据可作为参数被传入,代码大致如下:

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false },
    ],
  },
  getters: {
    doneTodos: (state) => {
      return state.todos.filter((todo) => todo.done);
    },
  },
});

在 Vue 组件中便可以通过如下方式进行访问:

this.$store.getters.doneTodos; // [{ id: 1, text: '...', done: true }]

Getter 也可以接收其他的 getters 作为第二个参数:

getters: {
  // ...
  doneTodosCount: (state, getters) => {
    return getters.doneTodos.length;
  };
}
// 使用
store.getters.doneTodosCount; // -> 1

可以通过 mapGetter 将 store 中的 getter 属性映射到局部计算属性内:

import { mapGetters } from 'vuex';

export default {
  // ...
  computed: {
    // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ]),
  },
};

在 Vue 组件中便可以直接用 this.doneTodosCount 取到你想要的过滤后的数据。

Mutation

我们修改 State 状态,需要触发一些方法,这些方法就放在 mutations 属性中,mutations 属性中的方法接受 2 个参数,第一个参数是state,内部包含所有状态值。第二个参数为提交载荷(Playload),也就是在外部通过 store.commit 方法触发 mutations 时额外带入的值。代码如下所示:

const store = new Vuex.Store({
  state: {
    count: 1,
  },
  mutations: {
    increment(state) {
      // 变更状态
      state.count++;
    },
  },
});

// 触发
store.commit('increment'); // 参数名称必须对应 mutations 的方法属性值。

//
const store = new Vuex.Store({
  state: {
    count: 1,
  },
  mutations: {
    increment(state, n) {
      state.count += n;
    },
  },
});

// 带载荷触发
store.commit('increment', 10);

Action

其实 Action 很好理解,它与 Mutation 类似,只不过 Action 是提交 mutation 而不是直接改变状态,并且 Action 被赋予异步的能力,也就是能在里面请求异步数据之后再触发状态的更新。

const store = new Vuex.Store({
  state: {
    count: 0,
  },
  mutations: {
    increment(state, data) {
      state.count += data.length;
    },
  },
  actions: {
    async increment(ctx) {
      const data = await getData();
      ctx.commit('increment', data);
    },
  },
});

// 分发 Action
store.dispatch('increment');

mapActions 帮我们更好的在页面中分发 Actions(在此之前需要在入口页注入 store):

import { mapActions } from 'vuex';

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`

      // `mapActions` 也支持载荷:
      'incrementBy', // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment', // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    }),
  },
};

5.基本使用

(1).初始化数据、配置actions、配置mutations,操作文件store.js

// 引入vue
            import Vue from 'vue'
            // 引入Vuex
            import Vuex from 'vuex'

            // 使用vuex
            Vue.use(Vuex)

            // 准备actons--用于响应组件中的动作
            const actions = {
                 jia(context,value){
                     console.log('actions被调用',context,value);
                     context.commit('JIA',value)
                 },
            }
            // 准备mutations--用于操作数据(state)
            const mutations = {
                JIA(state,value){
                    console.log('mutations被调用',state,value)
                    state.sum += value
                },
            }
            // 准备state--用于存储数据
            const state = {
                sum:0 //当前的求和
            }

            // 创建 并 暴露store
            export default new Vuex.Store({
                // actions:actions,
                // mutations:mutations,
                // state:state
                // 简写
                actions,
                mutations,
                state
            })

(2).组件中读取vuex中state的数据:

$store.state.sum

(3).组件中修改vuex中的数据:

this.$store.dispatch('action中的方法名',数据)

或 

$store.commit('mutations中的方法名',数据)

备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接写commit

5.getters的使用

(1).概念:当state中的数据需要经过加工后再使用时,可以使用getters加工

(2).在store.js中追加getters配置

//准备getters 用于将state中的数据进行加工
        const getters = {
            bigSum(state){
                return state.sum * 10
            }
            // 创建 并 暴露store
            export default new Vuex.Store({
               。。。。。
                getters
            })
            }

(3).组件中读取数据:

$store.getters.bigSum

6.四个map方法的使用

(1).mapState方法:用于帮助我们映射state中的数据为计算属性

computed:{
                 // 借助mapState生成计算属性,从state中读取数据(对象写法)
                 ...mapState({he:'sum',name:'name',xueke:'subject'}),

                // 借助mapState生成计算属性,从state中读取数据(数组写法)
                ...mapState(['sum','name','subject']),
            }

(2).mapGetters方法:用于帮助我们映射getters中的数据为计算属性

computed:{
                 // 借助mapGetters生成计算属性,从Getters中读取数据(对象写法)
                // ...mapGetters({bigSum:'bigsum'})

                // 借助mapGetters生成计算属性,从Getters中读取数据(数组写法)
                ...mapGetters([bigSum])
            }

(3).mapActions方法:用于帮助我们映射actions中的数据为计算属性 即:包含$store.dispath(xxx)函数

methods: {
                /*  addOdd(){
                this.$store.dispatch('jianOdd',this.n)
                    
                },
                addWait(){
                this.$store.dispatch('jianWait',this.n)
                } */

                 // 借助mapActions生成对应的方法,方法中会调用dispatch去联系action(对象方法)
                ...mapActions({addOdd:'jianOdd',addWait:'jianWait'}),
                // 借助mapActions生成对应的方法,方法中会调用dispatch去联系action(数组方法)
                // ...mapActions(['jianOdd','jianWait']) 两个名字相同
                },

  (4).mapMutations方法:用于帮助我们映射mutations中的数据为计算属性 即:包含$store.commit(xxx)函数

methods: {
                /*  increment(){
                    // this.$store.dispatch('JIA',this.n)

                    this.$store.commit('JIA',this.n)
                },
                subtract(){
                //  this.$store.dispatch('JIAN',this.n)

                this.$store.commit('JIAN',this.n)
                }, */
                
                // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutation(对象方法)
                ...mapMutations({increment:'JIA',subtract:'JIAN'}),
                // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutation(数组方法)
                // ...mapMutations(['JIA','JIAN']),
             }

7.模块化+命名空间

(1).目的:让代码更好维护,让多种数据分类更加明确

(2).修改store.js

const countAbout={
                namespaced:true, //开启命名空间
                actions:{},
                mutations:{},
                state:{},
                getters:{}
            }
            const personAbout={
                namespaced:true, //开启命名空间
                actions:{},
                mutations:{},
                state:{},
                getters:{}
            }

            // 创建 并 暴露store
            export default new Vuex.Store({
                modules:{
                    countAbout:countOptions,
                    personsAbout:peronsOptions
                }
    
            })

(3).开启命名空间后,组件中读取state数据

方式一:自己直接读取
this.$store.state.personAbout.list
方式二:借助mapState读取
...mapState('countAbout',['sum','name','subject'])

(4).开启命名空间后,组件中读取getters

方式一:自己直接读取
this.$store.getters[personAbout/firstPersonName]
方式二:借助mapGetters读取
...mapGetters('personsAbout',['firstPersonName'])

(5).开启命名空间后,组件中调用dispatch

方式一:自己直接dispatch
this.$store.dispatch('personsAbout/addPersonWang',personObj)
方式二:借助mapActions
...mapActions('countAbout',{addOdd:'jianOdd',addWait:'jianWait'})

(6).开启命名空间后,组件中调用commit

方式一:自己直接commit
this.$store.commit('personsAbout/ADD_Persons',personObj)
方式二:借助mapMutations
...mapMutations('countAbout',{increment:'JIA',subtract:'JIAN'})

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值