vuex官网的介绍:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。可以把他认为是另外一个存放公共变量的地方,但是同时面临变量会被某个组件更改,从而使得其他组件内容也发生更改。所以维护状态的唯一性就变的格外重要,接下来就让我们来了解一下vuex
npm install vuex --save
;
;// 引入vue与vuex
import Vue from 'vue'
import Vuex from 'vuex'
// 注册
Vue.use(Vuex)
// 引入子仓库
import son from './module/son'
// 导出
export default new Vuex.Store({
// 仓库
state: {
},
// 同步
mutations: {},
// 异步
actions: {},
// 子模块
modules: {
son
},
// 计算属性
getters: {}
})
// 在main.js文件下
// 引入
import store from './store'
// 挂载
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
Vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。就是说state就是一个应用里面的数据源,而里面的数据都是响应式的,当数值发生改变时其他引用此状态时也会发生改变。需要注意的是vuex属于单向数据流不能直接更改state里面的数据,具体怎么更改后面会讲到;
// 方法一:在组件中导入store对象
import store from "@/store/index.js"
// 使用
this.list = store.state.list
// 方法二:store默认绑定在vue原型上可以直接访问
this.list = this.$store.state.list
// 方法三:使用计算属性返回状态
computed: {
getList(){
return this.$store.state.list;
}
}
// 使用计算属性映射出来,可以直接映射到当前组件this上
computed: mapState(['list']),
// 或者
computed: mapState({
list: state=>state.list
}),
// 当想要modules里面的state话
computed: mapState({
list: state=>state.son.list
}),
// 还可以使用对象展开运算符,把数据源解构出来
computed: {
...mapState({
list: state=>state.list,
sonList: state=>state.son.sonSlist
})
}
getter可以认为是 store 的计算属性,对 state 的加工,是派生出来的数据。就像 computed 计算属性一样,getter 返回的值会根据它的依赖被缓存起来,且只有当它的依赖值发生改变才会被重新计算,可以同时被多个组件共享;需要注意的是:getter属性可以改变state状态值
// 假设在store中有一个计算属性
const store = new Vuex.Store({
state: {
list: []
},
getters: {
fun: (state,getters) => {
return state.list.length
}
}
})
// 在组件中
// 方式一:store.getters.fn,$store.getters.fn
// 方式二:使用mapGetters辅助方法映射出来
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters(['fun'])
}
// 子仓库中的计算属性
...mapGetters('仓库名',['方法名'])
Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。使用的时候用commit()来触发;注意:mutations中只能存放同步方法,无法调用异步方法
// 假设在store中有一个同步函数
const store = new Vuex.Store({
state: {
list: []
},
mutations: {
fun: (state,params) => {
state.list = params;
}
}
})
// 在组件中
// 方式一:store.commit('fun', 10),$store.commit('fun', 10)
// 方式二:使用mapMutations辅助方法映射出来
computed: {
// 使用对象展开运算符将 mutations混入 methods对象中
...mapMutations(['fun'])
}
// 子仓库中的计算属性
...mapMutations('仓库名',['方法名'])
为了解决mutations无法调用异步回调,便是使用Action来发起异步方法, Action提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。Action 通过 store.dispatch 方法触发,返回的是Promise对象;注意:在不同模块中可以触发多个 action 函数。在这种情况下,只有当所有触发函数完成后,返回的 Promise 才会执行。
// 假设在store中有一个异步函数
const store = new Vuex.Store({
state: {
list: []
},
mutations: {
fun: (state,params) => {
state.list = params;
}
},
actions: {
api: (context) {
context.commit('fun');
}
}
})
// 在组件中
// 方式一:store.dispatch('api'),$store.dispatch('api')
// 方式二:使用mapActions辅助方法映射出来
computed: {
// 使用对象展开运算符将 Actions混入 methods对象中
...mapActions(['api'])
}
// 子仓库中的计算属性
...mapActions('仓库名',['方法名'])
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。注意:子模块创建时必须先创建独立命名空间namespaced: true;这样模块才能相对独立,具有更高的封装度和复用性