文章目录
一、Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方生态系统中,并且在开发大型、复杂单页应用(SPA)时尤其有用。
二、核心概念
-
state:定义应用程序状态的数据。(数据,类似data)
-
mutations:用于修改状态的方法。(执行,类似methods)
-
actions:用于触发 mutations 的方法。(事件,类似controller)
-
getters:用于获取 state 中的数据。(数据加工,类似computed)
-
modules:使用单一状态树,致使应用的全部状态集中到一个很大的对象,所以把每个模块的局部状态分装使每一个模块拥有本身的 state、mutation、action、getters、甚至是嵌套子模块;
三、Vuex 的工作流程
-
通过dispatch去提交一个actions,
-
actions接收到这个事件之后,在actions中可以执行一些异步|同步操作,根据不同的情况去分发给不同的mutations,
-
actions通过commit去触发mutations,
-
mutations去更新state数据,
-
state更新之后,就会通知vue进行渲染
四、什么情况下我应该使用 Vuex?
Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式 (opens new window)就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
五、Vuex 的使用
-
定义 state:定义应用程序的状态数据。
-
定义 mutations:定义修改 state 的方法。
-
定义 actions:定义触发 mutations 的方法,可以包含异步操作。
-
定义 getters:定义获取 state 中数据的方法。
-
创建 store:将 state、mutations、actions、getters 组合成一个 store 对象。
-
在应用程序中使用 store:在应用程序中使用 store 对象的 state、mutations、actions、getters。
Vuex 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:
-
应用层级的状态应该集中到单个 store 对象中。
-
提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
-
异步逻辑都应该封装到 action 里面。
只要你遵守以上规则,如何组织代码随你便。如果你的 store 文件太大,只需将 action、mutation 和 getter 分割到单独的文件。
对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。
六、使用示例
以购物车为例,介绍vuex的使用全过程。
// vuex的入口文件,封装了cart模块,直接引入使用
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import cart from './cart'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {cart}
})
// cart模块的首页,引入了getters,actions,mutations
// 以及state中模拟的数据
// store/cart/index.js
import getters from "./getters"
import actions from "./actions"
import mutations from "./mutations"
export default {
state:{
goods: [{
id:1,
name:'小米手机',
price: 2000,
count: 0,
},{
id:2,
name:'苹果手机',
price: 3000,
count: 0,
},{
id:3,
name:'华为手机',
price: 4000,
count: 0,
}],
},
getters,
actions,
mutations
}
// getters文件,计算购物车的总价及数量
// store/cart/getters.js
export default {
totalPrice(state){
return state.goods.reduce((total,item)=>{
total += item.price * item.count
return total
},0).toFixed(2)
},
count(state){
return state.goods.reduce((total,item)=>{
total += item.count
return total
},0)
}
}
// actions文件,用于提交商品数量的变化
// store/cart/actions.js
export default {
add({commit},payload){
commit('add',payload)
},
reduce({commit},payload){
commit('reduce',payload)
}
}
// mutations文件,用于改变state中商品的数量变化
// store/cart/mutations.js
export default {
add(state,index){
state.goods[index].count++
},
reduce(state,index){
if(state.goods[index].count>=1){
state.goods[index].count--
}
},
}
// 这里是使用vuex的页面,展示购物车页面
// app.vue
<template>
<div class="about">
<div v-for="(item, index) in goods" :key="index">
<div>{{ item.name }}</div>
<div>{{ item.price }}</div>
<div style="display: flex">
<button @click="reduce(index)">-</button>
<div>{{ item.count }}</div>
<button @click="add(index)">+</button>
</div>
</div>
<div style="display: flex;">
<div>总计:{{ count }}</div>
<div>结算:{{ totalPrice }}</div>
</div>
</div>
</template>
<script>
import { mapGetters,mapState } from 'vuex'
export default {
computed: {
...mapState({
goods(state) {
return state.cart.goods
},
}),
...mapGetters(['count', 'totalPrice'])
},
methods: {
add(index) {
this.$store.dispatch('add', index)
},
reduce(index) {
this.$store.dispatch('reduce', index)
}
}
}
</script>
七、状态持久化
vuex优势: 相比sessionStorage,存储数据更安全,sessionStorage可以在控制台被看到。
vuex劣势: 在F5刷新页面后,vuex会重新更新state,所以,存储的数据会丢失。(即刷新浏览器,vuex数据丢失)
1、手动利用HTML5的本地存储
vuex的state在localStorage或sessionStorage或其它存储方式中取值 在mutations定义的方法里对vuex的状态操作的同时对存储也做对应的操作。这样state就会和存储一起存在并且与vuex同步
2、利用vuex-persistedstate插件
2.1、安装
npm install vuex-persistedstate
2.2、配置
- vuex-persistedstate默认存储于localStorage
// 在store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import createPersistedState from 'vuex-persistedstate';
Vue.use(Vuex);
export default new Vuex.Store({
// ...
plugins: [createPersistedState()]
// ...
});
- 存储sessionStorage的情况
plugins: [
createPersistedState({
storage: window.sessionStorage
})
]
- 存储cookie的情况
import Cookies from 'js-cookie'
plugins: [
persistedState({
storage: {
getItem: key => Cookies.get(key),
setItem: (key, value) => Cookies.set(key, value, {
expires: 7
}),
removeItem: key => Cookies.remove(key)
}
})
]
- 指定需要持久化的state
在vuex-persistedstate中,如果你想要指定需要持久化的state(即只持久化Vuex store中的部分状态,而不是全部),你可以通过paths配置选项来实现。paths是一个数组,其中的每个元素都是一个字符串,表示Vuex store中需要被持久化的状态的路径。
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import cart from './cart'
import user from './user'
Vue.use(Vuex)
export default new Vuex.Store({
plugins: [
createPersistedState({
paths:['cart','userSettings','user.name']
// 持久化'cart'模块的全部状态
// 持久化全局状态中的'userSettings'
// 只持久化'user'模块中的'name'
})
],
state: {
// 你的全局状态
token: '',
userSettings: {
theme: 'dark',
notifications: true
}
},
// 你的模块
modules: {cart,user}
})
- 过滤需要持久化的state
在vuex-persistedstate中,reducer是一个可选的配置项,它的作用是对即将被持久化到存储(如localStorage或sessionStorage)中的Vuex状态进行过滤或转换。通过使用reducer,你可以控制哪些数据被保存,以及如何保存这些数据,从而实现更细粒度的状态持久化控制。
reducer通常是一个函数,它接收当前的state(或特定部分的state,取决于你的配置)作为参数,并返回一个新的对象,该对象包含了应该被持久化的数据。
plugins: [
createPersistedState({
storage: window.sessionStorage,
reducer(state) {
// 只返回需要被持久化的部分state
return {
// 假设我们只想持久化user模块中的name和avatar字段
user: {
name: state.user.name,
avatar: state.user.avatar
}
};
}
})
]
如果path和reducer同时存在则使用reducer, 忽悠paths属性。
- API 配置
createPersistedState([options])使用给定的选项创建插件的新实例。可以提供以下选项来配置您的特定需求的插件:
API | 参数类型 | 说明 | 默认值 |
---|---|---|---|
key | String | 用于存储持久状态的键。 | vuex |
paths | Array | 部分保持状态的任何路径的数组。如果没有给定路径,则完整状态将持久化。如果给定一个空数组,则不会持久化任何状态。如果使用模块,请包括模块名称。 | [] |
reducer | Function | 一个将被调用的函数,对即将被持久化到存储中的Vuex状态进行过滤或转换。 | 都包含这些值 |
subscriber | Function | 被调用以设置突变订阅的函数。 | store => handler => store.subscribe(handler) |
storage | String | 指定存储数据的方式。 | localStorage |
getState | Function | 用来重新补充先前持久状态的功能。 | storage |
setState | Function | 用以保持给定状态的函数。 | storage |
filter | Function | 一个将被调用以过滤setState最终将在存储中筛选过滤的函数。 | () => true |
注意,getState 和 setState 是高级选项,它们允许你完全控制状态的存储和恢复过程。然而,在大多数情况下,简单地使用 paths 或默认行为可能就足够了。
标签:持久,模块化,mutations,state,Vuex,import,vuex,store From: https://blog.csdn.net/shanghai597/article/details/140325438