概念:
简单的来说,Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
vuex在项目中的应用(搭建的过程):
首先我们得先下载后配置。
用cnpm install vuex -S
1.首先在src文件夹中创建一个store文件夹 2.在store文件夹中
// 引入vue 和 vuex
import Vue from 'vue'
import Vuex from 'vuex'
然后使用 Vuex,
// 创建一个vuex的实例
let store = new Vuex.Store({
state:{
count:100, //这是state中的数据
},
// 引入模块(用到模块的时候引入)
modules:{
person, //模块名 在挂载之前需要引入模块的文件的地址
test,
},
// 一般在mutations中写一些方法来改变state中的值,
mutations:{
changeLoading(state,bool){
state.count=bool
},
},
//一般在getters中写一些计算属性,然后在组件中引入后直接使用(例如购物车中的计算总价)
getters:{
sum(state){
let sum = 0
state.shopArr.forEach((item)=>{
if(item.checked){
sum += item.number*item.price
}
})
return sum
}
},
//actions是vuex中的请求数据的地方(方式如下)
actions:{
listJson(context){
axios.get("../../static/zhoumo.json").then((res)=>{
context.commit("changeListArr",res.data)
})
}
},
plugins:[vuexLocal.plugin] //plugin插件 添加了长久存储插件
}
)
最后导出store
export default store
Vuex的五大核心:
1.state ==>基本数据
state即为vuex中的基本数据,可以放你请求到的任何数据
2.mutations,==>提交更改数据的方法,同步
mutations是更改vuex中store中的状态的唯一的方法,
mutations必须是同步的如果需要异步的话就需要使用action
每个mutations是一个对象,对象中写的是我们需要进行的操作,
它是有两个参数的,一个是state,另一个是你传的参数,可以是对象,
也可以是数组,获取state中的数据的时候用stete.count,
在组件中用store.commit("mutations中定义的方法",需要传的参数)
3.actions(异步)==>像一个装饰器,包裹mutations,使它可以异步 actions类似于mutation不同在于
- actions提交的是mutations,而不是直接变更状态
- actons可以包含任意异步操作
actions: {
listJson(context){
axios.get("../../static/zhoumo.json").then((res)=>{
context.commit("changeListArr",res.data)
})
}
}
注意的是actions函数需要接受一个store实例,具有相同方法和属性的context对象,因此你可以调用context.commit提交一个mutation,或者通过context.getters来获取state和getters actions在组件中式通过store.dispatch()来进行触发的
4.getters,==>从基本数据派生的数据
我们可以认为getters就是store的计算属性,也就是在与state同级下创建一个getters在getters中写自己需要写的逻辑
//购物车计算总价
getters:{
sum(state){
let sum = 0
state.shopArr.forEach((item)=>{
if(item.checked){
sum += item.number*item.price
}
})
return sum
}
},
在组件中通过this.$store.getters.sum来进行调用,在html中用{{ sum }}进行接收
5.modules ==>模块化vuex(便于后期的维护和管理代码) 如果我们在编写一个项目的时候如果要把stete,mutations,getters,actions,都写在一个index.js中是回出问题的,因为当一个项目有几个人在同时完成的时候,可能会出现相同的名命,这是就会起冲突,为了避免这种冲突,我们就会用到vuex中的模块化-->modules,在创建一个模块后,每个模块都拥有自己的state,mutations,getters,actions,
//创建的一个模块
export default {
namespaced:true, ////名命空间 该文件下的所有属性不再和其他vuex模块冲突
state:{
num:10,
},
mutations:{
NUM(state,val){
console.log("person.js")
state.num = val
}
},
}
导出这个模块然后在index.js中引入我导出的这个模块
在子组件中可以用以下方法来改变stete中的数据:
//写法一 : 这样写当页面刷新的时候会丢失增加的数据
// this.$store.state.num+=10
// 写法二 :这样写的话就不会再页面刷新的时候丢失数据了
this.$store.commit("NUM",10)
在使用模块化的时候会出现名命的冲突,这个时候就需要用到名命空间,使其成为带名命空间的模块,当模块 被注册后,它的所有的gette,actions,mutations都会自动根据模块注册的路径调整名命,当然这个时候就需要结合辅助函数来进行使用。
辅助函数
上面说到名命空间需要结合辅助函数来进行实现,通过辅助函数mapState,mapActions,mapMutations,把vuex.store中的属性映射到vue实例身上,这样在vue实例中就能访问到vuex.state中的属性了,对于操作vuex.store就很方便了
使用辅助函数 在组件中引用:
import {mapActions,mapState,mapMutations,mapGetters} from 'vuex'
在方法中使用,可以定义一个方法,在方法中调用, eq: @click = "jump" methods:{ ...mapMutations(["test"]), jump{ this.test() //调用方法 } } 也可以直接
@click = "test()"
methods:{
...mapMutations(["test"]),
}
以上是基本的用法,当你用到名命空间的时候
...mapMutations("模块的名称",{"自定义的方法名":"mutations中的方法名"}),
使用这种方法的时候就不会在使用模块化的时候出现冲突的问题了,而且也便于后期的维护。
plugins
我们可以用plugin插件,添加长久存储插件
首先我们需要在vue脚手架中安装一下vuex-persist,来实现vuex数据的长久存储
`cnpm install vuex-persist -S`
下载完成后再store文件夹中的index.js文件中引入
import Vuexpersistence from 'vuex-persist' //vuex的长久存储
const vuexLocal = new Vuexpersistence({
storage:window.localStorage
})
plugins:[vuexLocal.plugin] //plugin插件 添加了长久存储插件