Vuex
组件之间传值
目标:熟悉组件之间传值的各种情况(关注非父子之间传值)
- 父组件向子组件传值 props
- 子组件向父组件传值 $emit
- 非父子组件之间传值 : 爷孙;兄弟
- 发布订阅模式
- 基于Vue实现发布订阅模式
// 相当于中介
const eventBus = new Vue()
// 订阅事件
eventBus.$on('event-b', (param) => {
this.counta = this.counta + '----' + param
})
// 发布事件
eventBus.$emit('event-b', 123)
状态管理必要性分析
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex介绍
目标:熟悉Vuex是如何实现上述集中管理组件数据这种思想(模式)的
- state 管理组件数据,管理的数据是响应式的,当数据改变时驱动视图更新。
- mutations 更新数据,state中的数据只能使用mutations去改变数据(只能处理同步的场景)
- actions 请求数据,响应成功后把数据提交给mutations(可以处理异步的场景)
- Devtools指的是浏览器的Vue插件调试工具
初始化项目
目标:基于脚手架初始化项目
- 第一步:
npm i vuex --save/-S
- 第二步: 创建store.js
import vuex from 'vuex'
import vue from 'vue'
- 第三步:
Vue.use(vuex)
- 第四步:
const store = new Vuex.Store({...配置项})
- 第五步:导出
export default store
- 第六步:导入main.js 在根实例配置 store 选项指向 store 实例对象
// 初始化一个vuex的实例(数据仓库) 导出即可
import Vuex from 'vuex'
import Vue from 'vue'
// 使用安装
Vue.use(Vuex)
// 初始化
const store = new Vuex.Store({
// 配置(state|mutations|actions)
})
export default store
import store from '@/store'
new Vue({
// 把store对象挂载到vue实例对象中,这样就可以在所有的组件中获取store中的数据了
store,
render: h => h(App),
}).$mount('#app')
状态state
初始化状态
- 管理数据
// 初始化vuex对象
const store = new vuex.Store({
state: {
// 管理数据
count: 0
}
})
- 在组件获取state的数据:原始用法插值表达式
<div>A组件 state的数据:{{$store.state.count}}</div>
- 使用计算属性:
// 把state中数据,定义在组件内的计算属性中
computed: {
// 1. 最完整的写法
// count: function () {
// return this.$store.state.count
// },
// 2. 缩写
count () {
return this.$store.state.count
}
}
// 不能使用剪头函数 this指向的不是vue实例
mapState
目标:简化获取store数据的代码
- 把vuex中的state数据映射到组件的计算属性中。
import { mapState } from 'vuex'
- 使用:mapState(对象)
// 使用mapState来生成计算属性 mapState函数返回值是对象
// 使用mapState使用对象传参
// computed: mapState({
// // 1. 基础写法 (state) 代表就是vuex申明的state
// // count: function(state) {
// // return state.count
// // }
// // 2. 使用箭头函数
// // count: state => state.count
// // 3. vuex提供写法 (count是state中的字段名称)
// count: 'count',
// // 4. 当你的计算属性 需要依赖vuex中的数据 同时 依赖组件中data的数据
// count (state) {
// return state.count + this.num
// }
// })
- 使用:mapState(数组)
// 2、mapState参数是一个数组
// computed: mapState(['count', 'total'])
- 如果组件自己有计算属性,state的字段映射成计算属性
// 3、即在内部保留原有的计算属性,又要把store中的数据映射为计算属性
computed: {
// 组件自己的计算属性
calcNum () {
return this.num + 1
},
// 把mapState返回值那个对象进行展开操作(把对象的属性添加到该位置)
...mapState(['count'])
}
状态修改mutations
状态修改基本操作
目标:Vuex规定必须通过mutation修改数据,不可以直接通过store修改状态数据。
为什么要用mutation方式修改数据?Vuex的规定
为什么要有这样的规定?统一管理数据,便于监控数据变化
- 定义状态修改函数
// mutations是固定的,用于定义修改数据的动作(函数)
mutations: {
// 定义一个mutation,用于累加count值
// increment这个名字是自定义的
increment (state, payload) {
// state表示Store中所有数据
// payload表示组件中传递过来的数据
state.count = state.count + payload
}
}
- 组件中调用
handleClick () {
// 从js语法角度,是否可以这样修改对象的属性值?可以
// 但是我们不应该这样修改数据(Vuex不建议这样修改数据)
// this.$store.state.count++
// 那么Vuex建议如何修改数据?通过mutation修改
// 触发mutation
this.$store.commit('increment', 5)
}
mapMutations
- 把vuex中的mutations的函数映射到组件的methods中
- 通俗:通过mapMutations函数可以生成methods中函数
methods: {
// 1、对象参数的写法
// ...mapMutations({
// // 冒号右侧的increment是mutation的名称
// // 冒号左侧的increment是事件函数的名称,可以自定义
// increment: 'increment'
// })
// 2、数组参数的写法(事件函数名称和mutation名称一致)
...mapMutations(['increment'])
// 3、这种写法和第2种等效
// increment (param) {
// // 点击触发该函数后要再次触发mutation的
// this.$store.commit('increment', param)
// }
}
异步操作action
异步获取数据
目标:主要用于处理异步的任务
- 定义获取数据方法
// actions是固定的,用于定义异步操作的动作(函数)
actions: {
increment (context, payload) {
// context 执行上下文(vuex提供的一个对象,它当中包含了vuex提供的一些方法)
// context可以理解为this.$store(但是不完全一样---约等于)
// context === this.$store.commit()
// this.$store.commit()
// context.commit()
// payload表示触发action时传递的参数
// 这里要实现的功能:2秒后修改数据
setTimeout(() => {
// 修改数据必须通过mutation
context.commit('increment', payload)
}, 2000)
}
}
- 组件使用:
methods: {
handleClick () {
// 触发action(必须调用dispatch方法)
this.$store.dispatch('increment', 2)
}
}
mapActions
- mapActions辅助函数,把actions中的函数映射组件methods中
- 通俗:通过mapActions函数可以生成methods中函数
// 相当于 methods申明了一个函数fn(num){ this.$store.dispatch('getData', num)}
// ...mapActions({
// fn: 'queryData'
// })
// 相当于 methods申明了一个函数getData(num){ this.$store.dispatch('getData', num)}
...mapActions(['queryData'])