Vuex 个人学习总结

62 阅读2分钟

Vuex官方文档

1.简单看图理解

2.状态管理模式,它是集中式存储所有组件的状态的小仓库

  • 把各个组件都需要依赖的同一个状态抽取出来,在全局使用单例模式进行管理。
  • 在这种模式下,任何组件都可以直接访问到这个状态,或者当状态发生改变时,所有的组件都获得更新。
  • 但是刷新会丢失,可以参考 状态持久化 解决方式

3.Vuex安装

npm install vuex --save

配置 vuex,使其工作起来:在src路径下创建store文件夹,然后创建index.js文件

import Vue from 'vue';
import Vuex from 'vuex';
import getters from './getters'
import app from './modules/app'

Vue.use(Vuex);

const store = new Vuex.Store({
  modules:{app},
  getters
})

export default store;

修改main.js:

import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store'; // 引入我们前面导出的store对象

Vue.config.productionTip = false;

new Vue({
  el: '#app',
  router,
  store, // 把store对象添加到vue实例上
  components: { App },
  template: '<App/>',
});

4. Module 按功能拆分

以上面 modules:{app}为例

const state = {
  name: "xxx", 
}
const mutations = {
  SET_Name: (state, payload) => {
    state.name = payload.name
  }
}
const actions = {
  setName({ commit }, payload) {
    commit('SET_Name', payload)
  }
}

export default {
  namespaced: true,//命名空间namespaced:true
  state,
  mutations,
  actions
}

namespaced:true 命名空间 因为Module 按功能拆分 会有多个不同模块

export default {
  mounted() {
    console.log(this.getName);
  },
  computed: {
    getName() {
      //不添加namespaced:true 在组件中调用是
      return this.$store.state.name;//没有明确的模块区分
      //添加namespaced:true 在组件中调用是
      return this.$store.state.app.name;//他会对应到app模块下的xxx 指向更明确
    },
  },
};

使用方式

1.官方建议我们以上操作this.$store.state.XXX最好放在计算属性中

export default {
  mounted() {
    console.log(this.getName);
  },
  computed: {
    getName() {
      return this.$store.state.app.name;
    },
  },
};

或者...mapState

export default {
  mounted() {
    console.log(this.name);
    console.log(this.aliasName);
  },
  computed: {
   ...mapState('app',['name']),//this.name
   ...mapState('app',{ aliasName: 'name' }), //也可以在解构的时候起别名 this.aliasName
  },
};

5.Getter修饰器

在获取某个状态时需要增加或者增加特殊处理

const getters = {
  //就会在使用getter调用前面增加 hello 
  //组件调用 this.$store.getters.name 就会得到 加了hello 的name了
  'name': state => `hello${state.app.name}`,
}
export default getters

官方提供了 ...mapGetters

export default {
  mounted() {
    console.log(this.xxx);
    console.log(this.aliasName);
  },
  computed: {
   ...mapGetters(['name']),//this.xxx 
   ...mapGetters({ aliasName: 'name' }), //也可以在解构的时候起别名 this.aliasName
    //此处getters 因为是公用的 所以不需要区分模块
  },
};

6.Mutation:修改值

重要原则:Mutations里面的函数必须是同步操作,不能包含异步操作!

export default {
  mounted() {
    this.$store.commit('app/SET_Name', { name: '张三' }); // 调用的时候也需要传递一个对象
  },
};

或者 ...mapMutations

export default {
  mounted() {
    this.SETNAME({ name: '张三' });
    this.SET_Name({ name: '张三' });
    this.SetName({ name: '张三' });
  },
  methods: {
    SETNAME() {
      this.$store.dispatch('app/SET_Name')
    },
    // 注意,mapMutations是解构到methods里面的,而不是计算属性了
    ...mapMutations('app',['SET_Name']),
    ...mapMutations('app',{ SetName: 'SET_Name' }),
  },
};

7.Action:修改值

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。
export default {
  mounted() {
    this.$store.dispatch('app/setName',{ name: '张三' }); //调用的时候也需要传递一个对象
  },
};

或者 ...mapMutations

export default {
  mounted() {
    this.SETNAME({ name: '张三' });
    this.SET_Name({ name: '张三' });
    this.SetName({ name: '张三' });
  },
  methods: {
    SETNAME() {
      this.$store.dispatch('app/SET_Name')
    },
    // 注意,...mapActions是解构到methods里面的,而不是计算属性了
    ...mapActions('app',['SET_Name']),
    ...mapActions('app',{ SetName: 'SET_Name' }),
  },
};