Vuex
2023-02-03 本文已影响0人
欢西西西
Vuex是专门为Vuejs应用程序设计的状态管理工具,可以全局共享数据
能够高效的实现组件之间的通信,而且state也是响应式的
一、属性
1. State
存放全局对象,它的修改由mutation触发
const state = {
showImg: false
};
2. Getters
计算属性,利用的就是vue的computed计算属性
const getters = {
isHideImg: state => !state.showImg
};
3. Mutations
存放同步方法,用来更新state
const mutations = {
setImgVisible(state, v) {
state.showImg = v;
}
};
4. Actions
存放异步操作,提交mutation,而不是直接变更状态(commit触发mutation,dispatch触发action)
const actions = {
async setImgCfg({commit, state, getters, dispatch}) {
let data = await fetch(url).then(res => res.json());
commit('setImgVisible', data.visible === 1)
}
};
5. 辅助函数
import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
export default {
computed: {
...mapState(['showImg']),
...mapGetters(['isHideImg']),
},
methods: {
...mapMutations(['setImgVisible']),
...mapActions(['setImgCfg']),
onReload() {
this.setImgCfg();
},
handleClick() {
this.setImgVisible(true);
}
}
}
6. Modules
用来模块化管理store,每个模块拥有自己的state、getters、mutations、actions
const system = {
namespaced: true,
state: {},
getters: {},
mutations: {},
actions: {},
};
const login = {
namespaced: true,
state: {},
getters: {},
mutations: {},
actions: {},
};
const store = new Vuex.Store({
modules: {
system,
login
}
})
二、操作
store.state.system // module system的state
store.state.login // module login的state
// 触发system module的mutations中的updateA方法
store.commit("system/updateA");
// 触发system module的actions中的updateB方法
store.dispatch("system/updateB");
使用辅助函数
mapState("system/", ["expireDate"])
mapActions("system/", ["onLoginSuccess"])
可以使用createNamespacedHelpers创建基于命名空间的辅助函数
import {
createNamespacedHelpers
} from 'vuex';
const {
mapState,
mapGetters,
mapMutations,
mapActions
} = createNamespacedHelpers('system');
export {
mapState,
mapGetters,
mapMutations,
mapActions
};
三、问题
① mutation和action有什么区别?
action 提交的是 mutation,而不是直接变更状态,action可以包含异步操作。
② mutations为什么只能是同步的?可以做异步操作吗?为什么还要再设计一个action?
mutation可以写异步代码,但是不规范。定义它只写同步任务的意义在于:每个mutation执行完后都能相应地得到一个新的状态,以便devTools跟踪状态,便于调试
③ 怎么处理页面刷新后vuex数据丢失的问题?
vuex数据保存在内存中,并不是持久化存储,需要借用localStorage
方式1:可以使用vuex-persist插件
方式2:监听刷新事件,网页刷新前把state存到localStorage,在app created钩子中优先取localStorage中的数据并调用replaceState
created() {
const STORE_KEY = "GT-O0";
// 在页面刷新时保存vuex里的信息
// beforeunload事件在页面刷新时先触发
window.addEventListener("beforeunload", () => {
localStorage.setItem(
STORE_KEY,
JSON.stringify({
data: this.$store.state,
expire: Date.now() + 1000 * 5, // 设置过期时间
})
);
});
// 优先读storage
let saveStateData = localStorage.getItem(STORE_KEY);
if (!saveStateData) {
return this.initState();
}
try {
saveStateData = JSON.parse(saveStateData);
if (Date.now() > saveStateData.expire) {
// 如果已过期
this.initState();
return;
}
// 未过期则使用之前的store
this.$store.replaceState(
Object.assign({}, this.$store.state, saveStateData.data)
);
} catch (err) {
this.initState();
} finally {
localStorage.removeItem(STORE_KEY);
}
}
④ vuex是单向数据流还是双向数据流?
单向,我们无法在组件中直接修改state的数据,必须通过vuex提供的mutations或actions去修改