vuex学习,详解state、getters、mutations、actions、modules

vuex简介

vuex是全局状态数据管理的模式;采用集中式存储管理应用的所有组件状态,并以相应的规则保证状态以一种可预测的方式发生改变,其包含state、getters、mutations、actions、modules!

流程图:

在这里插入图片描述


vuex是依赖于vuex的插件,采用集中式存储管理共享数据的一个插件

安装全局注入方式:

NPM:

//默认安装最新版本
npm install vuex --save
//也可以安装指定3.6.2版本
npm install vuex@3.6.2 --save

Yarn:

//默认安装最新版本
yarn add vuex  --save
//也可以安装指定3.6.2版本
yarn add vuex@3.6.2 --save

在src文件夹下新建store文件夹index.js文件

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})


在这里插入图片描述


在src文件夹下main.js文件注入

import store from './store'
new Vue({
  store,
  render: (h) => h(App),
}).$mount('#app')

在这里插入图片描述


核心概念

1.State

vuex是单一状态树,仅用一个对象就包含了全部的应用层级状态,所有需要集中管理的数据都要放到State中存储

在src\store文件夹下index.js文件,代码设置如下

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    //消息数量
    messageCount: 1,
  },
});

在vue页面里,通过三种方式获取

1.通过$store获取state数据:
 console.log(this.$store.state.messageCount)  //打印出来是1
  
2.通过computed选项中使用:
  computed:{
  	//console.log(this.messageCount) 出来的也是1
	messageCount(){
		return this.$store.state.messageCount
	}
  }
  
3.通过mapState辅佐函数:
 import { mapState } from 'vuex'
 //console.log(this.messageCount)打印出来也是1
 computed:{
	...mapState(['messageCount'])
 }

2.Getter

Getter是计算属性,返回对state数据的装饰,相当于vue中的computed。<例:返回格式化后的时间如:state里数据为2020-10-10经过getter装饰后可以变成2020年10月10日也可以返回多个state数据的计算结果>

在src\store文件夹下index.js文件,代码设置如下

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    //时间
    dateTimeNew: '2020-10-10',
  },
  getters: {
  //格式化时间,增加年月日
    dateTimeNew(state) {
      const list = state.dateTimeNew.split('-')
      const dateTimeFormatting = list[0] + '年' + list[1] + '月' + list[2] + '日'
      return dateTimeFormatting
    },
  },
})

在vue页面里,通过三种方式获取

1.通过$store获取state数据:
 console.log(this.$store.getters.messageCount)  //打印出来是2020年10月10日
  
2.通过computed选项中使用:
  computed:{
  	//console.log(this.messageCount) 出来的也是2020年10月10日
	messageCount(){
		return this.$store.getters.messageCount
	}
  }
  
3.通过mapState辅佐函数:
 import { mapGetters} from 'vuex'
 //console.log(this.messageCount)打印出来也是2020年10月10日
 computed:{
	...mapGetters(['getters'])
 }

3.Mutation

mutation是唯一提交更改stare中状态的方法,Vuex 中的 mutation 非常类似于事件

在src\store文件夹下index.js文件,代码设置如下

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    //消息数量
    messageCount: 1,
  },
  mutations: {
    //递增
    addMessageCount(state) {
      state.messageCount++
    },
    //当符合条件,则清空(附带入参isRead)
    addMessageCountRead(state, isRead) {
      //如果isRead为true,则messageCount赋值0
      if (isRead) state.messageCount = 0
    },
  },
})


在vue页面里,通过两种方式获取

1.通过$store直接使用
 this.$store.commit('addMessageCount')
 console.log(this.$store.state.messageCount) //打印出来是2

 this.$store.commit('addMessageCountRead', true)
 console.log(this.$store.state.messageCount) //打印出来是0

2.通过mapState辅佐函数:
 import { mapMutatuins} from 'vuex'
 methods:{
	...mapMutatuins(['addMessageCount','addMessageCountRead'])
 }
  //1.this.addMessageCount() 
 //2.console.log(this.$store.state.messageCount)打印出来也是2
 //3.this.addMessageCountRead(true)
 //4.console.log(this.$store.state.messageCount)打印出来是0

4.Action

Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态
Action 可以包含任意异步操作

在src\store文件夹下index.js文件,代码设置如下

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    //消息数量
    messageCount: 1,
    //人员数量
    userCount: 1,
  },
  mutations: {
    //递增
    addMessageCount(state) {
      state.messageCount++
    },
    //递增
    addUserCount(state, data) {
      state.userCount += data
    },
  },
  actions: {
    addMessage(context) {
      //一秒后执行addMessageCount方法
      setTimeout(() => {
        //context是vue的执行上下文,可以理解为this
        context.commit('addMessageCount')
      }, 1000)
    },
    addUserCount({ commit }, data) {
      //Action 通常是异步的
      return new Promise((resolve, reject) => {
        //两秒后执行addUserCount方法
        setTimeout(() => {
          commit('addUserCount', data)
          resolve()
        }, 2000)
      })
    },
  },
})



在vue页面里,通过两种方式获取

1.通过$store直接使用
  this.$store.dispatch('addMessage')
  console.log(this.$store.state.messageCount) //打印的是1
  setTimeout(() => {
    console.log(this.$store.state.messageCount) //打印的是2
  }, 2000)

  this.$store.dispatch('addUserCount', 100).then((res) => {
    console.log(this.$store.state.userCount) //打印的是101
  })

2.通过mapState辅佐函数:
 import { mapActions} from 'vuex'
 methods:{
	...mapActions(['addMessage','addUserCount'])
 }
  //1.this.addMessage() 
  //2.setTimeout(() => {
  //       console.log(this.$store.state.messageCount) //打印的是2
  //  }, 2000)
  //3.this.addUserCount(100)
  //4. this.addUserCount(100).then((res) => {
  //     console.log(this.$store.state.userCount) //打印的是101
  // })

5.Module

module是模块分割的功能,由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块,每个模块拥有自己的 state、mutation、action、getter等(仅在做大型单页面应用时才需要使用)。

在src\store文件夹下index.js文件,代码设置如下

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

Vue.use(Vuex)

const modulesFiles = require.context(`./modules`, true, /\.js$/)
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

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

export default store

在src\store\modules文件夹下新建user.js文件,user.js文件代码如下

const state = {
  token: '',
  info: {}, // 个人信息
}

const getters = {}

const mutations = {
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_INFO: (state, info) => {
    state.info = info
  },
}

const actions = {
 // 登出
  logout({ commit, state }) {
    return new Promise((resolve, reject) => {
      // 调取登出接口
      commit('SET_TOKEN', '') // 清除token
      commit('SET_INFO', {}) // 清除用户信息
      removeToken()
      resolve()
    })
  },
}

export default {
  namespaced: true, // 开启命名空间模块,避免注册在全局里
  state,
  getters,
  mutations,
  actions,
}

在vue页面里,通过一种方式调用

1.通过$store直接使用
 this.$store.dispatch('user/logout').then(() => {})

注意点:

1.在vue文件可以直接使用this.$store;
在js文件里需要先引入import store from ‘./store’,然后在store.dispatch(‘user/logout’).then(() => {})

2.vuex官方网站

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值