vuex
官网:Vuex
Vuex 是为了保存组件之间共享数据而诞生的,如果组件之间有要共享的数据,可以直接挂载到 Vuex 中,而不必通过父子组件之间传值了,如果组件之间的数据不需要,这些不需要共享的私有数据,没有必要放到 Vuex 中
注意:
- 只有共享的数据,才有权利放到 Vuex 中;
- 组件内部私有的数据,只要放到组件的 data 中即可;
- props 、 data 和 vuex 的区别:props 是父组件向子组件传值;data 是组件内部私有数据;vuex 相当于一个全局的共享数据存储区域,就是一个公共数据仓库
操作案例:
- 安装:
cnpm i vuex -S
操作:
main.js
// 入口文件
import Vue from 'vue';
// 配置 vuex 的步骤
// 2. 导入包
import Vuex from 'vuex';
// 3. 注册 vuex 到 vue 中
Vue.use(Vuex);
// 4. new Vue.Store() 实例,得到一个数据仓储对象
let store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
},
subtract(state, obj) {
state.count -= (obj.c + obj.d);
}
},
getters: {
// 注意:这里的 getters ,只负责对外提供数据,不负责
// 修改数据,如果想要修改 state 中的数据,请去找 mutations
optCount(state) {
return '当前最新的 count 值是:' + state.count;
}
},
actions: {
SUBTRACT({ commit }, obj) {
// 可以在这里对 obj 进行处理或异步操作
setTimeout(() => { // 一秒后减去
commit('subtract', obj)
}, 1000)
}
}
});
import App from './App.vue';
const vm = new Vue({
el: '#app',
render: c => c(App),
// 5. 将 vuex 创建的 store 挂载到 VM 实例上,只要挂在到了 VM 上
// 任何组件都能使用 store 来存储数据
store
});
两个组件:
amount.vue
<template>
<div>
<!--<h3>{{ '当前数量为:'+$store.state.count }}</h3>-->
<h3>{{ $store.getters.optCount }}</h3>
</div>
</template>
counter.vue
<template>
<div>
<input type="button" value="减少" @click="remove">
<input type="button" value="增加" @click="add">
<br>
<input type="text" v-model="$store.state.count">
</div>
</template>
<script>
export default {
data() {
return {
// count: 0
};
},
methods: {
add() {
// 虽然可以实现,但不要这么用,后期维护困难
// this.$store.state.count++;
this.$store.commit('increment');
},
remove() {
// mutations 方式
this.$store.commit('subtract', {c: 3, d: 2});
// actions 方式
this.$store.dispatch('SUBTRACT', {c: 3, d: 2});
}
}
};
</script>
总结:
- state 中的数据,不能直接修改,如果想要修改,必须通过 mutations
- 如果组件想要直接从 state 上获取数据:需要 this.$store.state.***
- 如果组件,想要修改数据,必须使用 mutations 提供的方法,需要通过 this.$store.commit(‘方法的名称’,唯一的一个参数)
- 如果 store 中 state 上的数据,在对外提供的时候,需要做一层包装,那么,推荐使用 getters,如果需要使用 getters,则用 this.$store.getters.***
附加:
- 应用场景:商城购物车的商品个数添加
- 映射:
import { mapState, mapActions, mapGetters, mapMutations } from "vuex"
// state
computed: {
// 使用对象展开运算符将 setter 混入 computed 对象中
...mapState('mark', [
'markData',
'pageData',
]),
}
// getter
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
// mutation
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
// action
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
// `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
以上面 state 为例
import mark from './mark'
export default new Vuex.Store({
state,
mutations,
modules: { mark }
})
computed: {
// 使用对象展开运算符将 setter 混入 computed 对象中
...mapState('mark', [
'markData',
'pageData',
]),
}
// 使用
const data = this.markData
Vuex 持久化插件(vuex-persistedstate)
页面刷新后,想保存页面未保存的数据。我们总是习惯于放在浏览器的sessionStorage和localStorage中。但是用了vue后,vuex便可以被应用了。
- vuex优势:相比sessionStorage,存储数据更安全,sessionStorage可以在控制台被看到。
- vuex劣势:在F5刷新页面后,vuex会重新更新state,所以,存储的数据会丢失。
解决方法:vuex-persistedstate
安装
npm install vuex-persistedstate -S
用法
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState()]
})
想要存储到sessionStorage,配置如下(想使用 cookie 或 localStorage 同理 )
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage
})]
})
vuex-persistedstate默认持久化所有state,指定需要持久化的state,配置如下:
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage,
reducer(val) {
return {
// 只储存state中的user
user: val.user
}
}
})]
实例:
let store = new Vuex.Store({
plugins: [
createPersistedState({
storage: window.localStorage,
reducer(val) {
return {
token: val.token,
}
}
}),
createPersistedState({
storage: window.sessionStorage,
reducer(val) {
return {
footer: val.footer,
}
}
}),
],
state: {
footer: 1,
token: '',
},
mutations: {
footer(state, str) {
state.footer = str;
},
token(state, str) {
state.token = str;
}
},
});
更多请看:vuex-persistedstate