文章目录
- 版权声明
- Vuex 概述
- Vuex 的主要概念和组件
- vuex的使用
- 状态 (state)
- Vuex特点
- 访问vuex中数据
- $store访问
- mapState辅助函数访问
- 开启严格模式及Vuex的单项数据流
- 突变(mutations)
- mutations初识
- 带参 mutations
- 辅助函数 mapMutations
- 动作(Actions)
- 辅助函数 mapActions
- vuex mutations VS actions
- 获取器(Getters)
- 总结
版权声明
- 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明,所有版权属于黑马程序员或相关权利人所有。本博客的目的仅为个人学习和交流之用,并非商业用途。
- 我在整理学习笔记的过程中尽力确保准确性,但无法保证内容的完整性和时效性。本博客的内容可能会随着时间的推移而过时或需要更新。
- 若您是黑马程序员或相关权利人,如有任何侵犯版权的地方,请您及时联系我,我将立即予以删除或进行必要的修改。
- 对于其他读者,请在阅读本博客内容时保持遵守相关法律法规和道德准则,谨慎参考,并自行承担因此产生的风险和责任。本博客中的部分观点和意见仅代表我个人,不代表黑马程序员的立场。
Vuex 概述
- uex 是一个用于 Vue.js 的状态管理库【状态就是数据】。简言之,Vuex 是一个插件,可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。
- 使用场景
- 优势
- 共同维护一份数据,数据集中化管理
- 响应式变化
- 操作简洁
Vuex 的主要概念和组件
-
状态(State):Vuex 中的状态是存储应用程序数据的地方,通常表示为 JavaScript 对象。
-
获取器(Getters):获取器用于根据当前状态计算派生状态,类似于存储库中的计算属性。
-
突变(Mutations):突变是修改状态的唯一方式。它们是同步的,通过明确定义状态如何改变,有助于维护可预测的状态。
-
动作(Actions):动作用于执行异步操作和触发突变。适合进行诸如发出 API 请求然后根据结果提交突变等任务。
-
模块(Modules):Vuex 允许将存储划分为模块。这对于较大的应用程序有助于将状态、突变、动作和获取器组织成更小、更可管理的部分。
-
Vuex 特别适用于较大的应用程序,其中状态管理可能变得复杂。
-
它强制执行单向数据流,并使更容易跟踪应用程序状态变化的来源。这种可预测性有助于调试和维护不断增长的应用程序。
vuex的使用
- Vue.js 应用程序中设置 Vuex 的一般步骤
-
安装(Installation):你需要将 Vuex 安装为依赖项,可以使用 npm 或 yarn 进行安装。
npm i vuex@3 # vue2适用
-
存储配置(Store Configuration):通过定义状态、突变、动作和获取器来创建一个存储。
- 为了维护项目目录的整洁,在src目录下新建一个store目录其下放置一个index.js文件。
// store.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { // 在这里定义应用程序的状态 }, mutations: { // 在这里定义突变函数 }, actions: { // 在这里定义动作函数 }, getters: { // 在这里定义获取器函数 } }) export default store
- 为了维护项目目录的整洁,在src目录下新建一个store目录其下放置一个index.js文件。
-
在 main.js 中导入挂载到 Vue 实例上
import Vue from 'vue' import App from './App.vue' import store from './store' Vue.config.productionTip = false new Vue({ render: h => h(App), store }).$mount('#app')
-
测试打印Vuex
created(){ console.log(this.$store) }
状态 (state)
- “state”(状态)是指应用程序中的数据的集合,通常表示为一个包含各种属性的 JavaScript 对象。这些属性可以包括应用程序的配置、用户信息、页面内容、各种设置等。
- State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储。
- store 对象的 state 属性中定义应用程序的状态
const store = new Vuex.Store({
// state 状态, 即数据, 类似于vue组件中的data,
// 区别:
// 1.data 是组件自己的数据,
// 2.state 中的数据整个vue项目的组件都能访问到
state: {
user: null,
settings: {
theme: 'light',
language: 'en',
},
// 其他应用程序状态
},
// 其他配置项
})
Vuex特点
- Vuex 中状态的一些重要特点
-
Centralized: Vuex 中的状态是集中管理的,这意味着所有组件都可以访问相同的状态数据,而不需要通过复杂的组件传递数据来实现共享。
-
Reactive: Vuex 的状态是响应式的。当状态发生变化时,依赖于该状态的组件会自动更新以反映这些变化。
-
Read-Only: Vuex 的状态是只读的。这意味着你不能直接在组件中修改状态,而是需要通过 mutations 来进行修改。这有助于维护状态的可预测性。
-
Single Source of Truth: Vuex 鼓励将应用程序的状态集中到一个单一的状态树中,使其成为整个应用程序的“唯一数据源”。这有助于简化状态的管理和维护。
-
Predictable: 由于状态的修改只能通过 mutations 来进行,因此状态的变化变得可预测,易于调试和维护。
-
访问vuex中数据
- 通过
$store
直接访问 —>{{ $store.state.count }}
- 通过
辅助函数mapState
映射计算属性 —>{{ count }}
$store访问
- 通过$store访问的语法
获取 store: 1.Vue模板中获取 this.$store 2.js文件中获取 import 导入 store 模板中: {{ $store.state.xxx }} 组件逻辑中: this.$store.state.xxx JS模块中: store.state.xxx
- 模板中使用
- 在组件中访问 Vuex 中的状态,可以使用
this.$store.state
来获取状态的值
- 在组件中访问 Vuex 中的状态,可以使用
<template>
<div>
<p>User: {{ $store.state.user }}</p>
<p>Theme: {{ $store.state.settings.theme }}</p>
</div>
</template>
- 组件逻辑中使用
- 将state属性定义在计算属性中
<h1>state的数据 - {{ count }}</h1> // 把state中数据,定义在组件内的计算属性中 computed: { count () { return this.$store.state.count } }
- js文件中使用
//main.js
import store from "@/store"
console.log(store.state.count)
mapState辅助函数访问
- mapState是辅助函数,把store中的数据映射到 组件的计算属性中, 它属于一种方便的用法。
- 第一步:导入mapState (mapState是vuex中的一个函数)
import { mapState } from 'vuex'
- 第二步:采用数组形式引入state属性
mapState(['count'])
- 上面的代码等价于
count () { return this.$store.state.count }
- 第三步:利用展开运算符将导出的状态映射给计算属性
computed: { ...mapState(['count']) } <div> state的数据:{{ count }}</div>
开启严格模式及Vuex的单项数据流
- vuex 同样遵循单向数据流,组件中不能直接修改仓库的数据
- 直接在组件中修改Vuex中state的值
- Son1.vue
button @click="handleAdd">值 + 1</button>
methods:{
handleAdd (n) {
// 错误代码(vue默认不会监测,监测需要成本)
this.$store.state.count++
// console.log(this.$store.state.count)
},
}
- 开启严格模式
- 通过
strict: true
可以开启严格模式,开启严格模式后,直接修改state中的值会报错 - state数据的修改只能通过mutations,并且mutations必须是同步的
- 通过
突变(mutations)
mutations初识
- 定义mutations
const store = new Vuex.Store({
state: {
count: 0
},
// 定义mutations
mutations: {
}
})
- 格式说明
- mutations是一个对象,对象中存放修改state的方法
mutations: {
// 方法里参数 第一个参数是当前store的state属性
// payload 载荷 运输参数 调用mutaiions的时候 可以传递参数 传递载荷
addCount (state) {
state.count += 1
}
}
- 组件中提交 mutations
this.$store.commit('addCount')
带参 mutations
- 提交 mutation 是可以传递参数的
this.$store.commit('xxx', 参数)
- 提供mutation函数(带参数)
mutations: { ... addCount (state, count) { state.count = count } }
- 提交mutation
handle ( ) { this.$store.commit('addCount', 10) }
- 小tips: 提交的参数只能是一个, 如果有多个参数要传, 可以传递一个对象
this.$store.commit('addCount', { count: 10 })
辅助函数 mapMutations
- mapMutations 和 mapState很像,它是把位于mutations中的方法提取了出来,映射到组件methods中。
import { mapMutations } from 'vuex' methods: { ...mapMutations(['addCount']) } //等价于 methods: { // commit(方法名, 载荷参数) addCount () { this.$store.commit('addCount') } }
- 在组件中,可以直接通过this.addCount调用
<button @click="addCount">值+1</button>
- 请注意: Vuex中mutations中要求不能写异步代码,如果有异步的ajax请求,应该放置在actions中
动作(Actions)
-
actions是用于处理异步操作的,例如从服务器获取数据或执行复杂的计算。Actions可以包含任何异步操作,但是它们最终需要调用mutations来更新state中的数据。
-
Actions是通过dispatch方法来调用的,dispatch方法接收一个action的名称和一个可选的payload参数。当调用dispatch方法时,它会触发一个action,并且可以在action中执行任何异步操作。
- 定义actions
mutations: {
changeCount (state, newCount) {
state.count = newCount
}
}
actions: {
setAsyncCount (context, num) {
// 一秒后, 给一个数, 去修改 num
setTimeout(() => {
context.commit('changeCount', num)
}, 1000)
}
}
- 组件中通过dispatch调用
setAsyncCount () {
this.$store.dispatch('setAsyncCount', 666)
}
辅助函数 mapActions
- mapActions 是把位于 actions中的方法提取了出来,映射到组件methods中
- Son.vue
import { mapActions } from 'vuex' methods: { ...mapActions(['changeCountAction']) } //mapActions映射的代码 本质上是以下代码的写法 //methods: { // changeCountAction (n) { // this.$store.dispatch('changeCountAction', n) // }, //}
- 直接通过 this.方法 就可以调用
<button @click="changeCountAction(200)">+异步</button>
vuex mutations VS actions
Mutations | Actions | |
---|---|---|
目的 | 修改state中的数据 | 执行异步操作、调用多个mutations |
同步/异步 | 同步操作 | 可以是同步或异步操作 |
使用场景 | 更新state中的数据 | 执行异步请求、处理复杂逻辑 |
调用方式 | 使用commit方法调用 | 使用dispatch方法调用 |
响应 | 不能返回任何值,只能修改state | 可以返回Promise或异步操作的结果 |
跟踪 | 可以在devtools中跟踪mutations的调用 | 可以在devtools中跟踪actions的调用 |
- 总体来说
- mutations适用于同步操作,用于修改state中的数据。它们是可追踪的,可以在devtools中查看它们的调用。
- actions适用于执行异步操作、调用多个mutations或处理复杂逻辑。它们可以是同步或异步操作,并且可以返回Promise或异步操作的结果。
- 在调用上,mutations使用commit方法,而actions使用dispatch方法。
获取器(Getters)
- getters用于从store中获取数据,类似于计算属性,可以基于store中的state计算出一个新的值。
- getters可以看作是store的计算属性,它们的值会被缓存起来,只有当所依赖的state发生变化时才会重新计算。
- 好处:可以将数据的处理逻辑从组件中抽离出来,将其放在store中,从而使得组件更加简洁和易于维护。另外,getters还可以在多个组件中共享和重复使用,避免了代码的冗余。
- getter示例:
- 定义doneTodos的getter,它基于store中的todos数组计算出一个新的数组,该数组包含所有已完成的todo对象
const getters = { //getters: { // getters函数的第一个参数是 state // 必须要有返回值 doneTodos: state => { return state.todos.filter(todo => todo.done) } }
- 访问getters
- 使用store访问getters
{{ $store.getters.doneTodos}}
- 在组件中使用这个getter,使用mapGetters辅助函数
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters([
'doneTodos'
])
}
}
总结
- 关于Vuex中state、getters、mutations和actions的使用总结:
State | Getters | Mutations | Actions | |
---|---|---|---|---|
用途 | 存储应用程序的数据 | 从state中派生出计算属性 | 修改state中的数据 | 执行异步操作、调用多个mutations |
直接访问 | 使用this.$store.state | 使用this.$store.getters | 不直接访问,通过commit方法调用 | 不直接访问,通过dispatch方法调用 |
用法示例 | this.$store.state.count | this.$store.getters.doneTodos | this.$store.commit(‘increment’) | this.$store.dispatch(‘fetchData’) |
参数 | 无 | 接收state作为参数 | 接收state和payload作为参数 | 接收context对象作为参数 |
返回值 | 无 | 返回基于state的计算属性或派生数据 | 无返回值,只能修改state | 可以返回Promise或异步操作的结果 |
异步操作 | 不适用 | 不适用 | 不适用 | 适用 |
跟踪 | 无 | 可以在devtools中跟踪getters的调用 | 可以在devtools中跟踪mutations的调用 | 可以在devtools中跟踪actions的调用 |