仓库vuex
为了方便实现组件之间的数据共享,Vuex用来实现vue组件全局状态(全局状态也就是数据)管理的一种机制。
vuex特点:
能够在vuex中集中管理共享的数据,易于开发和后期维护
能够高效地实现组件之间的数据共享,提高开发效率
存储在 vuex中的数据都是响应式的,能够实时保持数据与页面的同步
一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;对于组件中的私有数据,依旧存储在组件自身的data中即可。
引入vuex
//main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
把仓库挂载到vm对象:
new Vue({
router,
//挂载以后,所有的组件就可以直接从store中获取全局数据
store,
render: h => h(App)
}).$mount('#app')
//引入vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
//用于保存所有组件的公共数据的对象
},
getters: {
},
mutations: {
// 用来修改state和getters里面的数据
},
actions: {
},
modules: {
}
})
仓库 store的5个属性
state
state对象类型,类似于组件实例的 data属性,用于保存所有组件的公共数据的对象
export default new Vuex.Store({
state: {
msg:'我就是所有共享的数据'
},
getters: {
// 相当于计算属性
},
mutations: {
// 用来修改state和getters里面的数据,相当于methods
},
actions: {
// vuex中用于发起异步请求
},
modules: {
// 拆分模块
}
})
组件中访问数据
this.$store.state.msg
getters
getters对象类型,类似于实例的计算属性 computed,也就是计算属性。vuex的官方文档也是说到可以将getter理解为store的计算属性,getters的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。它会传入state对象供我们操作,传入的state是最后一次被修改的state对象。
export default new Vuex.Store({
state: {
msg:'我就是所有共享的数据',
products: [
{name: '鼠标', price: 20,id:1,count:1},
{name: '键盘', price: 40,id:2,count:1},
{name: '耳机', price: 60,id:3,count:1},
{name: '显示屏', price: 80,id:4,count:1}
]
},
getters: {
total(state){
return state.products.reduce((n1,n2)=>{
return n1+n2.price;
},0)
}
},
mutations: {
},
actions: {
},
modules: {
}
})
组件中使用数据
this.$store.getters.total
mutations
mutations对象类型,类似于实例的 methods,但是必须是同步处理,不能处理异步方法。
组件中希望更改 Vuex 的 store 中的状态(数据)的唯一方法是提交 mutation,不要用赋值表达式直接在组件中给store设置新数据。这样设计的原因是只有通过mutation来更新数据,它才会去帮我们通知所有使用数据的组件更新数据刷新UI
先在mutations中注册事件
export default new Vuex.Store({
state: {
msg:'我就是所有共享的数据',
products: [
{name: '鼠标', price: 20,id:1,count:1},
{name: '键盘', price: 40,id:2,count:1},
{name: '耳机', price: 60,id:3,count:1},
{name: '显示屏', price: 80,id:4,count:1}
]
},
getters: {
total(state){
return state.products.reduce((n1,n2)=>{
return n1+n2.price*n2.count;
},0)
}
},
mutations: {
changecount(state,value){
//默认传第一个参数传state
console.log(state,value);
// 变更状态
state.products[2].count=value.n;
}
},
actions: {
},
modules: {
}
})
在组件中调用方法commit(提交载荷)
1.直接触发并传值
this.$store.commit('changecount',{n:100})
2.可以以一个对象的形式传入
传入对象时相当于把整个对象作为了第二个参数传入mutations
this.$store.commit({
type: 'increment',
n:100
})
actions
actions 类似于 mutations,不同在于:
actions提交的是mutations而不是直接变更状态actions中可以包含任意异步操作,mutations中绝对不允许出现异步actions中的回调函数的第一个参数是context上下文对象,是一个与store实例具有相同属性和方法的对象
在store中定义
export default new Vuex.Store({
state: {
msg: '我就是所有共享的数据'
},
mutations: {
change(state,value){
// 变更状态
state.msg=value.n;
}
},
actions: {
//默认第一个参数传一个跟store一样的对象
increment(context, obj) {
setTimeout(() => {
// 提交载荷
context.commit('change', obj)
},100)
}
},
modules: {
}
})
在组件中使用
1.直接分发
this.$store.dispatch('increment',{n:100})
2.以对象形式分发
this.$store.dispatch({
type: 'increment',
n:100
})
module
module可用于业务分块开发:由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块,每个模块拥有自己的 state、mutation、action、getter
在store的index.js中引入模块
import Vue from 'vue'
import Vuex from 'vuex'
//在store的index.js中引入模块
import Module1 from './Module1.js'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
// 注入模块
Module1
}
})
Module1.js
export default{
//局部命名空间(让state的中变量与其他模块中的同名变量不冲突)
namespaced: true,
state: {
msg: '我是Module1的数据',
},
getters: {
getmsg(state) {
return state.msg+"666666"
}
},
mutations: {
changecount(state, value) {
//默认传第一个参数传state
// 变更状态
state.msg = value.n;
},
change(state,value){
// 变更状态
state.msg=value.n;
}
},
actions: {
//默认第一个参数传一个跟store一样的对象
increment(context, obj) {
setTimeout(() => {
// 提交载荷
context.commit('change', obj)
},100)
}
}
}
组件中的使用注入的模块:
this.$store.state.Module1.msg // -> Module1的状态
this.$store.commit("Module1/change",100)-> Module1 的mutations
this.$store.getters["Module1/getmsg"]-> Module1的getters
this.$store.dispatch("Module1/change",100)-> Module1 的actions