在vue开发中,每个组件都有自己的独立的数据,整个项目中的所有组件可以通过总线进行传值,
但是如果出现组件之间需要共用同一组数据时,数据管理就会非常麻烦。
vuex是vue的状态(数据)管理工具,它采取了一种集中管理数据的思想,将整个项目中所有的公共数据放在一个统一的仓库中,
然后任何组件都可以从这个仓库中读取数据,也可以通过仓库提供的方法修改数据。
new Vuex.Store({}) 创建一个store 对象 用来管理vue的数据; 并且可以在全局使用$store进行访问;
state 属性 定义仓库数据;
mutations 同步修改数据的函数,以后在其他组件想改变仓库的数据,必须调用仓库里面的修改方法进行修改;
actions:异步获取数据的方法,例如发网络请求数据需要在actions发起请求,目的吧响应
数据赋值给仓库state的数据,赋值时候还是通过moutations里面同步的修改方法进行修改
modules vuex的模块化写法,也就是如果仓库数据的比较多的时候,就可以通过module把一些数据分到其他模块里面
getters 相当于计算结果,一般会把数据过滤过程写在仓库里面,把满足条件的数据传递组件里面
怎么使用或者修改仓库里面的数据
方法一 使用 $store.state 获取数据,不推荐使用,
方法二 使用映射状态的函数进行按需导入
import {mapState} from “vuex” 推荐使用这个方式进行访问或者修改数据;
在计算结果中将mapState进行展开
…mapState([“数据名”]) 调用函数获取指定名的函数数据;
修改数据
可以直接在$store.state直接修改,这时不健康的,推荐使用 mapMutations进行映射修改函数进行修改;
在methods中进行调用函数并展开;
…mapMutations([“方法名”])
此时 组件中就映射了这些修改函数,可以直接在视图中使用;
方法三 使用$store.state.commit()进行提交
参数一 mutations 中的修改函数名,参数二 要修改数据;
mutations 定义修改方法( 必须是同步函数)
mutations:{
setName(state,v){ state对象,包含state里面所有的数据; v 调用函数传递的数据,修改属性值;
state.name = v;
}
}
当需要在对象上添加新属性时,你应该
使用 Vue.set(obj, ‘newProp’, 123),
actions 使用方法
Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
通俗点讲,我们可以使用action 定义一个异步的修改函数,只不过并不是直接变更状态,而是通过调用mutation变更状态;
并且可以异步操作一些数据,这也是mutations不具备的,比如我们需要使用axios获取数据动态改变state里面的数据,只能使用actions进行修改
Action 函数接受一个与 store 实例具有相同方法和属性的 context(上下文) 对象,因此你可以调用 context.commit 提交一个 mutation,
或者通过 context.state 和 context.getters 来获取 state 和 getters。当我们在之后介绍到 Modules 时,你就知道 context 对象为什么不是 store 实例本身了。
actions: {
increment (context,v) { //参数一 于store 具有相同方法和属性的上下文对象; 参数二 调用函数所传递的值;
context.commit('方法名') //将数据提交;
}
}
我们也可以在increment 定义一个promise 对象, 发送axios请求,在请请求成功之后,将数据提交,在返回一个状态,方便调用的时候进行判断是否成功;
调用actions进行派发
使用$store.dispatch(“事件名”,传递的参数);
Vue.prototype.axios = axios //把axios写进vue组件对象的原型类型里面,以后可以在组件里面直接使用axios即可
getters
vuex 中的计算属性,用来过滤返回状态,就像计算属性一样,返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
getters:{
todos(state,getters,rootState){ 参数一 state 对象, 参数二 getters对象,参数三 包含模板全部状态;
return //something
}
}
同计算结果一样,我们可以使用返回一个函数形式,给getters 进行传参,在函数中再将结果返回;
注意,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。
映射函数 mapGetters
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性
import { mapGetters} from “vuex”
computed:{
…mapGetters([“fulltName”])
…mapGetters({name:fulltName}) //使用对象的形式经fullName改名,在模块写法中比较常用;
}
modules
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
state 是一个返回对象的函数;
模块的局部状态
对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。
对于模块内部的 getter,根节点状态会作为第三个参数暴露出来
getter:{
fil(state,getter,rootState){ //rootState 根节点状态;
}
}
state(默认以模块名:{} 的方式进行存储,在设置命名空间于不设置都一样)
...mapState({
moduleA:moduleA, //将模块内的状态整个进行映射,也可以使用下面的方式
//将数据以箭头函数的形似返回, 返回单个数据,而不是将moduleA全部映射;
firstName: state=>state.modulA.firstName;
})
模块内 getters
设置命名空间之后
...mapGetters({
fullName:'moduleA/fullName' //getters名变成路径形式
})
$store.getters['moduleA/fullName'] //不用映射函数直接使用
不设置命名空间
getters 会与 根仓库产生变量冲突,并报错,但实际使用的时根仓库的数据
actions
设置命名空间之后
…mapActions({
getData:‘moduleA/getData’ //需要修改成路径;
})
dispatch(‘moduleA/login’)
getData(store,v){ //store {commit,dispatch,getters,rootGetters,rootGetters,state} 组成的对象
//也可以使用结构进行单独操作;
}
命名空间
namespaced: true //使用命名空间
默认情况下 在不使用命名空间,模块内的mutations 和 getters 和 actions 会使用模块内的名称
渲染到仓库内,如果重名的话,则会形成一个数组,这样使得多个模块能够对同一 mutation 或 action 作出响应。
如果你希望你的模块具有更高的封装度和复用性,可以使用命名空间,此时模块内的属性
会路径的方式渲染到仓库中, (state默认使用命名,不是路径), ‘mymoduleA/setName’:function()
这样就完成了命名空间的使用;
如果你希望使用全局 state 和 getter,rootState 和 rootGetters 会作为第三和第四参数传入 getter,也会通过 context 对象的属性传入 action。
若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。
vuex 持久化存储
1 可以使用 storage 对象进行持久化存储,
详情访问js 对象
2 使用 vuex-persist 插件进行持久化存储,
3 使用 vuex-persistedstate 插件进行持久化存储;
使用 vuex-persist 进行持久化保存
导入
import VuexPersist from 'vue-persist'
创建实例化对象
let vuexStorage = new VuexPersist({
key:"vuex", //配置storage的key
storage:window.localStorage //选中存储方式 sessionStorage...
})
在vuex中引入插件 在仓库对象配置插件
https://blog.csdn.net/weixin_34234721/article/details/91419432
plugins: [vuexLocal.plugin] //使用插件字段;
使用 vuex-persistedstate 插件进行持久哈保存
import vuexPersistDstate from 'vuex-persistedstate'
plugins: [vuexPersistDstate({
storage:window.sessionStorage
})]