VueX的概念
vuex是vue的状态管理工具,状态即数据。状态管理就是集中管理vue中的通用数据
注意:
- 不是所有的场景都适用于vuex,只有在必要的时候才使用vuex
- 使用了vuex之后,会附加更多的框架中的概念进来,增加了项目的复杂度
vuex 的使用流程图
vuex是一个vue的状态管理工具, 统一的管理一些通用的数据
-
state: 状态, 可以提供数据
-
mutations: 存放操作数据的方法
-
getters: 基于state, 得到一些额外的属性 (state的计算属性)
-
actions: 可以存放一些异步的操作内容, 可以提交mutation, 不可以直接操作state
-
Module: 可以对Vuex进行分割,形成不同的数据模块(每个模块都有自己的state、mutation、action、getter、和子模块)
vuex中如何提供数据,组件如何访问数据
store与state
// 创建一个所有组件都能访问到的仓库 组件中: this.$store 访问
// 仓库中, 包含了存储状态 state, 状态即数据
// 如果要获取到仓库中的数据, 先要访问到仓库, 再去拿仓库中state中的数据
const store = new Vuex.Store({
// 指定了state属性, 用于提供数据, 类似于之前的data,
// 区别: state中的数据, 是所有组件都能访问的数据 this.$store.state.xxx
state: {
msg: '你好哇',
count: 100
}
})
// 直接访问
console.log(store.state.count)
// 由于建立了关联, 组件中访问, 通过 实例.$store.state
console.log(vm.$store.state.count)
console.log(this.$store.state.count)
vue中修改 vuex 的数据(严格模式)
默认修改是能改的, 但是是不合理的, 所以一般需要开上严格模式
严格模式: https://vuex.vuejs.org/zh/guide/strict.html
const store = new Vuex.Store({
// ...
strict: true
})
不要在发布环境下启用严格模式!深度监听消耗性能
getters属性
getters在vuex中的作用,相当于vue中的计算属性 , 依赖state
中的数据变化而变化,而且和vue中一样具有 缓存 ,直到下回数据发生变化,都只会计算一次.调用也是缓存调用
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
// getters 会接受 state 数据 作为第一个参数
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
Getter 会暴露为 store.getters
对象,你可以以属性的形式访问这些值:
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
//在 store 实例中 可以通过 this.getters 在mutations和Actio中访问到getters中的值
Getter 也可以接受其他 getter
作为第二个参数:
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
通过方法访问getters
getters: {
// ...
// 获取到 在state.todos 数组中 对应 id 的 对象
getTodoById: (state) => (id) => state.todos.find(todo => todo.id === id)
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
注意,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。
mutations属性
修改vuex中的数据,必须通过 mutations
进行修改,不能直接修改
mutations
提供的都是方法, 这些方法是可以修改state
中的数据的state
中的数据变化都要在mutations
中进行- 所有的方法的第一个参数, 都是
state
,表示state对象
mutations
中的事件必须时同步函数
,异步函数
就需要在Action
中注册在往mutations
中提交**
mutations: {
// state:表示state对象
add (state) {
state.count++
}
}
// --------------------------------------
// 组件中提交mutations
// 想要修改state,必须触发mutations提供的方法
this.$store.commit('add')
提交载荷 Payload
额外参数(Payload)
// 定义mutations
// 如果要修改state,需要在mutations的方法修改
mutations: {
addNum (state, num) {
state.count += num
}
}
// --------------------------------------
// 组件中提交mutations,并带上参数
this.$store.commit('addNum', 5)
但是只能传递一个参数, 所以如果有多个参数, 传入一个对象即可
this.$store.commit('addNum', { num: 5, msg: '嘎嘎' })
Mutation 需遵守 Vue 的响应规则
既然 Vuex 的 store 中的 状态是响应式的
,那么你在Mutation对象中添加新的数据时,就需要遵循vue的响应规则对新添加的数据进行数据劫持
//使用
Vue.set(obj, 'newProp', 123)
//或者 用新的对象数据替换旧对象中的数据
state.obj = { ...state.obj, newProp: 123 }
在Mutations
函数中调用另外的Mutations
函数和getters
函数
// 在 store 中是有 this 指向的 可以通过 this 指向当前的 store 实例:
getters:{
cont(state){
return state.const
}
},
mutations:{
add (state) {
state.count++
},
del (state) {
//通过 this 指向当前实例 查找实例中的方法
this.commit('add')
this.getters.cont
}
}
Action属性
Action 类似于 mutation,不同在于:
- Action 提交的是
mutation
,而不是直接变更状态。 { 通过context.commit()
} - Action 可以包含任意
异步操作
。
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
//在组件中调用action
this.$store.dispatch('xxx')
Action
函数接受一个与 store
实例具有相同方法和属性的 context
对象,因此你可以调用 context.commit
提交一个 mutation
,或者通过 context.state
和 context.getters
来获取 state
和 getters
。
但是这个 context
并不是store
实例本身,这个就要涉及到Module
了,可以先简单理解为,Module
就是vue
中的组件,context
是组件中的data
,每个组件都要有自己的data
,虽然每个组件中的data
都有和 vue
根实例上的data
一样的属性,但是他们不是一个data
,如何是一个data
的话,必然会造成,组件data
和vue
根实例data
冲突的问题,而context
也是一个为了解决多模块数据和根实例数据冲突而设计的.
因此context
并不等于store
实例,但是如何你的vuex
中没有模块的话,context
基部等价于store
实例.
Module
Module
适用于数据量比较大的项目,需要把数据分割成不同的模块方便管理.对于Module
建议查看官网文档,里面解释较为详细,这里不在赘述: