- Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
(还不明白?通俗点说,就是全局变量,每个组件都可以用到~并且可以随时改变和计算等)
- 核心概念
state // 它是储存全局变量名(定义变量)
mutations // 它是处理同步,并修改 state 里的数据
actions // 它是处理异步,或者多个同步的区域,调用dispatch 执行mutations 函数改变state
getters // 它就像Vue组件里的computed 计算属性,有的时候后台返回来的数据,并不是我们想要的数据,我们需要处理或者拼接后使用,多个组件使用的时候我们会用到。(注意:getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。)
modules // 这个是模块区分
- 代码
- store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
// 引入Vuex 拆分文件
import state from "./state/state";
import mutations from "./mutations/mutations";
import actions from "./actions/actions";
import getters from "./getters/getters";
import modules from "./modules/modules";
Vue.use(Vuex)
var storeData = {
//strict: true,开启后,外部无法直接修改state,限制开发人员从外部改变 (切记正式环境把它给关了 可以通过process.env.NODE_ENV 判断,这样维护起来方便)
state, // 它是Vuex要定义的变量
mutations, // 它是处理同步区域
actions, // 它是处理异步
getters, // 使用来计算的(computed 同理)
modules // 这个是模块区分
};
/**
* 这里主要解决了,页面刷新,数据丢失问题。
* 思路:页面刷新的时候将store里state的值存到sessionStorage中,然后从sessionStorage中获取,再赋值给store。
* 然后再把session里面存的删除即可,相当于中间件的作用。
*/
//在页面加载时读取sessionStorage里的状态信息
if (sessionStorage.getItem("store")) {
// console.log('刷新后')
storePublics.state = JSON.parse(sessionStorage.getItem("store"))
sessionStorage.removeItem("store")
}
//在页面刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener("beforeunload", () => {
// console.log('刷新前')
sessionStorage.setItem("store",JSON.stringify(storePublics.state))
});
export default new Vuex.Store(storeData)
- store/state/state.js
export default {
name: '小鸡',
name2: '啄米',
isLogin: 1 // 1为登录 2为未登录
}
- store/mutations/mutations.js
/**
* 1、参数说明
* @state 定义好的变量(要修改的变量名,通过.XXX来获取)
* @value 传递过来的参数(要改变的值)
* 2、注意事项
* 不接受第3个参数,所以传多个参数的时候,把第二个写成对象传入
* */
export default {
// 修改名称
setNameFn(state, value) {
state.name = value
},
// 修改登录状态
setLoginFn(state, value){
state.isLogin = value
console.log(state.isLogin)
}
}
- store/actions/actions.js
/**
* 1、参数说明
* @store 是store对象,可以通过store.commit来调用mutations函数(简洁化:可以通过{}来解构出来使用)
* @value 传递过来的参数(要改变的值)
* */
export default {
// 改变登录状态函数
changeLoginFn ({commit},that) {
console.log(that)
// 代替请求后台
setTimeout(() => {
commit('setLoginFn',2)
}, 2000)
}
}
- store/getters/getters.js
/**
* 1、参数说明
* @state 指定义好的变量(要修改的变量名,通过.XXX来获取)
* @getters 可以调用所有getters方法
* */
export default {
// 拼接名称(以方法形式调用)
getTodoById (state) {
return (id) => {
return state.name + state.name2 + id
}
},
// 拼接名称(以变量名称来使用)
setSpliceFn (state, getters,) {
return state.name + state.name2
}
}
- store/modules/modules.js
/**
* 1、属性说明
* @namespaced 设置为true 的时候,模块的就是私有区域,(因为Vue 默认mutations,actions,getters 是全局作用域)
* 2、注意事项
* 使用actions,想获取全局的mutations方法 参数上添加{root: true}属性 通过this['a/aFn']()来获取值 '/'来区分哪个模块
* 可以拿到全局的state, 就是第3个参数rootState
* (详情说明,请参考:https://vuex.vuejs.org/zh/guide/modules.html)
* */
export default {
a: {
namespaced: true,
state: {
num: 1
}
},
b: {
state: {
num: 1
}
}
}
- 模板使用说明
// 引入要展开的名称
import {mapState,mapMutations,mapActions,mapGetters} from 'vuex'
computed: {
// 数组里面写的是变量名 (也可以写对象,键值,也可以接收的是函数)
...mapState(['name','isLogin']),
// ...mapState({ // 对象使用
// newName: 'name',
// loginState:'isLogin'
// }),
// ...mapState({
// // 为了能够使用 `this` 获取局部状态,必须使用常规函数
// newName: (state) { // 函数使用
// return state.count + this.localCount
// }
// }),
// 注意,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。
...mapGetters([
'setSpliceFn',
'getTodoById'
]),
},
// 方法使用
methods: {
...mapMutations([
'setNameFn', // 将 `this.setNameFn()` 映射为 `this.$store.commit('setNameFn')`
'setLoginFn'
]),
...mapActions([
'changeLoginFn'
]),
}
this.$store.commit()
commit: 同步操作
this.$store.commit('方法名',值)【存储】
this.$store.state.方法名【取值】
this.$store.dispatch()
dispatch: 异步操作
this.$store.dispatch('方法名',值)【存储】
this.$store.getters.方法名【取值】
当操作行为中含有异步操作:
比如向后台发送请求获取数据,就需要使用action的dispatch去完成了。
其他使用commit即可。
其他了解:commit=>mutations,用来触发同步操作的方法。
dispatch =>actions,用来触发异步操作的方法。
在store中注册了mutation和action,在组件中用dispatch调用action,然后action用commit调用mutation,
- store其他API
// 自定义插件(跟state 同级)
// plugins: [
// (store)=>{
// console.log(store)
// console.log('每次加载就回执行一次,可以做你想做的事情')
// }
// ]
store.watch((state)=>{
state.name + state.name1
console.log('当state值发生改变就会触发回调函数')
},()=>{
console.log('回调函数')
})
store.subscribe((mutation,state)=>{
console.log(mutation)
console.log(mutation.payload) // 每次传的参数
console.log('每次调用mutations 都会执行这个函数')
})
store.subscribeAction((action, state) => {
console.log(action)
console.log(action.payload)
console.log('监听action')
})