目标:熟悉组件之间传值的各种情况(关注非父子之间传值)
// 相当于中介
const eventBus = new Vue()
// 订阅事件
eventBus.$on('event-b', (param) => {
this.counta = this.counta + '----' + param
})
// 发布事件
eventBus.$emit('event-b', 123)
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
目标:熟悉Vuex是如何实现上述集中管理组件数据这种思想(模式)的
目标:基于脚手架初始化项目
npm i vuex --save/-S
import vuex from 'vuex'
import vue from 'vue'
Vue.use(vuex)
const store = new Vuex.Store({...配置项})
export default 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')
// 初始化vuex对象
const store = new vuex.Store({
state: {
// 管理数据
count: 0
}
})
A组件 state的数据:{{$store.state.count}}
// 把state中数据,定义在组件内的计算属性中
computed: {
// 1. 最完整的写法
// count: function () {
// return this.$store.state.count
// },
// 2. 缩写
count () {
return this.$store.state.count
}
}
// 不能使用剪头函数 this指向的不是vue实例
目标:简化获取store数据的代码
import { mapState } from 'vuex'
// 使用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
// }
// })
// 2、mapState参数是一个数组
// computed: mapState(['count', 'total'])
// 3、即在内部保留原有的计算属性,又要把store中的数据映射为计算属性
computed: {
// 组件自己的计算属性
calcNum () {
return this.num + 1
},
// 把mapState返回值那个对象进行展开操作(把对象的属性添加到该位置)
...mapState(['count'])
}
目标: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)
}
methods: {
// 1、对象参数的写法
// ...mapMutations({
// // 冒号右侧的increment是mutation的名称
// // 冒号左侧的increment是事件函数的名称,可以自定义
// increment: 'increment'
// })
// 2、数组参数的写法(事件函数名称和mutation名称一致)
...mapMutations(['increment'])
// 3、这种写法和第2种等效
// increment (param) {
// // 点击触发该函数后要再次触发mutation的
// this.$store.commit('increment', param)
// }
}
目标:主要用于处理异步的任务
// 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)
}
}
// 相当于 methods申明了一个函数fn(num){ this.$store.dispatch('getData', num)}
// ...mapActions({
// fn: 'queryData'
// })
// 相当于 methods申明了一个函数getData(num){ this.$store.dispatch('getData', num)}
...mapActions(['queryData'])