vuex
// npm i vuex -S
// store.js 【 通过返回一个实例的形式避免内存溢出 】
export default () =>{
return new Vuex.Store({
// 当然这里我们可以单独将数据对象放到一个模块中,这样便于管理【只要返回的格式跟下面对象格式一致就可以】
state: {
count: 0,
},
// 这里的通用型数据管理方法也可以单独拆分模块
mutations: {
updateNum(state, num) {
state.count = num;
},
},
});
}
// index.js
import createStore from "store.js"
const store = createStore();
// app.vue
mounted(){
console.log(this.$store)
},
computed:{
count(){
return this.$store.state.count
}
}
methods:{
update(){
this.$store.commit("updateNum",newNum)
}
}
getter
// getter.js
export default {
someInfo(state) {
return ` 可以通过 state 组装数据`;
},
};
// store.js
import getters from "getters.js";
export default () => {
return new Vuex.Store({
getters,
state: {
count: 0,
},
});
};
// app.vue
computed:{
// 直接通过 state 拿出数据
count(){
return this.$store.state.count;
}
byGetter(){
return this.$store.getters.xxx
}
}
// getter.js
export default {
someInfo(state) {
return `组装数据`;
},
};
// store.js
import getters from "getters.js";
export default () => {
return new Vuex.Store({
getters,
state: {
count: 0,
},
});
};
// app.vue
import {
mapState,
mapGetters
} from 'vuex';
//
computed:{
// 通过 mapState
...mapState(["count"]) // 如果语法不支持,可以考虑配置 .babelrc
/*
...mapState({
newName:'count'// 这样页面上就可以使用 {{newName}} 了
})
// 或者你需要做计算
...mapState({
newName:(state)=>{
// return ...
}
})
*/
// count(){
// return this.$store.state.count;
// }
// mapGetters 的用法跟上面一样
...mapGetters(["byGetter"])
// byGetter(){
// return this.$store.getters.xxx
// }
/*
...mapGetters({
newName: "byGetter"//也可以自定义方法名
mod:"moduA/fn" // 或者分模块命名
})
*/
}
// npm i babel-preset-stage-1 -D
/*
// .babelrc
{
"presets":["env","stage-1"]
}
*/
异步更改数据
// actions.js
export default {
fnAsync(store, data) {
setTimeout(() => {
store.commit("updateData", {
num: 123,
});
}, 1000);
},
};
// store.js
return new Vuex.Store({
actions,
});
// app.vue
mounted(){
this.$store.dispatch("fnAsync",{/* data */})
}
模块化
// store.js
export default () => {
return new Vuex.Store({
modules: {
moduA: {
state: {},
// 默认情况下vuex会将所有的 mutations 放置到全局的 mutations 中,所以这样很容易造成命名冲突
// namespaced:true, // 这样据可以就可以将 mutations 限制在模块内
mutations:{
// 在这里面 state 是当前这个模块的 state
fn(state,data){
}
}
getters:{
// 分别是当前模块的 state,所有的getters,全局的 state
nData(state,getters,rootState) {
}
}
actions:{
fn({state,commit,rootState}){
commit("fn",/* data */,/*{root:true} 用于配置在全局寻找 fn 否则在本模块寻找*/)
}
}
},
moduB: {
state: {},
actions:{
tFn({state,commit,rootState}){
// 模块间的调用
commit("moduA/fn",/*data*/,{root:true})
}
}
},
},
});
};
// app.vue
computed:{
testA(){
return this.$store.state.moduA.xxx
}
}
mounted:{
this.fn("newVal")
// this["moduA/fn"]("newVal") // 如果是分模块使用
}
methods:{
...mapMutations(["fn"])
// 如果是加了命名空间
// ...mapMutations(["moduA/fn"])
}
动态注册模块
store.registerModule("moduC", {
state: {},
});
启用 watch
store.watch(
(state) => state.xxx,
(xxx) => {
// 这是当 state.xxx 值有变化的时候才会调用这里的方法
}
);
监听 mutation 和 action 的调用
// 只要调用了 mutation 都会调用这里的回调函数
store.subscribe((mutation, state) => {});
// 只要调用了 action 都会调用这里的回调函数
store.subscribeAction((action, state) => {});
vuex 的插件用法
new Vuex.Store({
plugins: [
// 插件顺序会依次执行【每个插件都是一个 function】
// 当然在这里面可以监听 mutation 和 action 的调用,然后有针对性的处理数据
(store) => {},
(store) => {},
],
});
Vuex 启用热更替
其实方法跟之前在 webpack 中监听某模块的变更是一样的
// store.js
export default () => {
const store = new Vuex.Store({
/* ... */
});
if (module.hot) {
// 配置需要热更替的模块
module.hot.accept(["./state/state", "./actions/actions"], () => {
const newState = require("./state/state");
const actions = require("./actions/actions");
store.hotUpdate({
state: newState,
actions: actions,
});
});
}
return store;
};
版权声明:本文为qq_32466937原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。