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官方网站