Vuex总结
2019-03-18 本文已影响5人
李牧敲代码
【应用场景】
简单来说就是状态管理,存放一些全局参数,供各个组件调用,并且这是响应式的。这里补充下,个人认为Vuex持久化很重要,不然这些参数存在内存中,一个页面刷新就回到解放前,那有什么用。
【本文主要几个内容】(本文所有例子都是基于Vue/cli 3.4的脚手架)
- state
- mutation
- action
- module
- Vuex持久化
state
[例子]
<template>
<div class="home">
{{$store.state.age}}
{{count}}
{{countAlias}}
{{countAge}}
<button
@click="changeAge"
>changeAge</button>
</div>
</template>
<script>
import {mapState} from 'vuex'
// @ is an alias to /src
export default {
name: "home",
computed: mapState({//用mapState的好处是不用每个参数一个函数
count: state => state.age,//直接取需要的参数即可
countAlias: "count", //给count取了个别名,应用场景不明
countAge() {//用这种方式监听state,并且可以调用组件的this
return this.$store.state.age;
}
}),
methods: {
changeAge() {
this.$store.commit("increaseAge", 2); //官网推荐这种方式,实际上在非严格模式可以直接赋值,但不可追踪
}
}
};
</script>
//store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
age: 1
},
mutations: {
increaseAge(state, num) {
state.age += num; //这里的state指向了前面的state,所以修改了这里就会导致前面的state发生了变化
}
},
actions: {
}
})
效果:
1.gif
getters
[应用场景]
getters更像一个过滤器,将原始state中的值处理过后再送给调用者。
可以通过以下3种形式访问
- 属性形式
- 函数形式
- mapGetters(和mapState一样)
看代码:
//store.js
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
name: 'wcx',
age: 12
},
mutations: {
increaseAge(state, obj) {
this.state.age = this.state.age + obj;
}
},
actions: {
},
getters: {
dealName: (state) => {//属性形式的写法
return 'getters' + state.name;
},
dealAge: (state) => (id) => { //函数形式对应的写法
if(state.age % 2 === 0) {
return false
}else {
return true
}
}
}
})
<template>
<!-- Home.vue -->
<div>
欢迎进入首页
<!-- 属性形式 -->
{{$store.getters.dealName}}
<!-- 函数形式 -->
{{dealAge(123)}}
<button @click="changeAge">changeAge</button>
</div>
</template>
<script>
// import {mapGetters} from 'vuex';
const {mapGetters} = require('vuex');
// @ is an alias to /src
export default {
methods: {
changeAge() {
this.$store.commit('increaseAge', 11)
}
},
computed: {
...mapGetters([ //mapGetters形式
'dealAge'
])
},
}
</script>
Mutations
这是官网推荐的修改state的方式,虽然直接在子组件里修改state也可以生效。Mutations里面放一些方法,每个方法接受2个参数,第一个是state,第二个是一个对象,里面可以放多个需要的参数。记住Mutations里面指接受同步方法,异步要用Actions,例子可以看官网。
Actions
和 mutations类似,不同的是Actions是处理异步函数的,然后子组件里,mutations通过commit
来提交修改,而actions通过dispatch
来提交修改。看代码:
//store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
age: 12
},
mutations: {
increaseAge(state) {
state.age++;
}
},
actions: {
getAge(context, param) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('param', param)
context.commit('increaseAge');
resolve();
}, 1000)
});
}
}
})
<template>
<div class="home">
home
<button @click="f2">f2</button>
</div>
</template>
<script>
// @ is an alias to /src
export default {
data() {
return {
age: 12
}
},
methods: {
f2() {
this.$store.dispatch('getAge', Math.random()).then(() => {
console.log(this.$store.state.age)
});
}
}
};
</script>
<style scoped>
.home {
background-color: pink;
}
</style>
test.gif
Module:
为了防止store过于臃肿,可以通过Module的方式分割模块,看代码:
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
Vuex持久化
【应用场景】
之前在写项目的时候发现vuex是没有做持久化的,那我浏览器一个刷新,所有状态都被重置,这不shit了么?后来通过localstorage的方式解决,但是总感觉应该有现成的方法,不然每次手动控制,岂不是很麻烦。这里介绍下插件vuex-persistedstate
官网地址
接着之前的例子代码:
//store.js
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedState' //引入插件
Vue.use(Vuex)
export default new Vuex.Store({
state: {
age: 12
},
plugins:[createPersistedState({//将插件传入vuex
storage: window.localStorage
})],
mutations: {
increaseAge(state) {
state.age++;
}
},
actions: {
getAge(context, param) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('param', param)
context.commit('increaseAge');
resolve();
}, 1000)
});
}
}
})
效果:
test.gif