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')
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) //打印出来是12.通过computed选项中使用:computed:{//console.log(this.messageCount) 出来的也是1messageCount(){return this.$store.state.messageCount}}3.通过mapState辅佐函数:import { mapState } from 'vuex'//console.log(this.messageCount)打印出来也是1computed:{...mapState(['messageCount'])}
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'])}
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赋值0if (isRead) state.messageCount = 0},},
})
在vue页面里,通过两种方式获取
1.通过$store直接使用this.$store.commit('addMessageCount')console.log(this.$store.state.messageCount) //打印出来是2this.$store.commit('addMessageCountRead', true)console.log(this.$store.state.messageCount) //打印出来是02.通过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
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的执行上下文,可以理解为thiscontext.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) //打印的是1setTimeout(() => {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// })
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.defaultreturn 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', '') // 清除tokencommit('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官方网站