# 常用传值
父子传值,兄弟传值,祖孙传值
# 父子传值
# 父组件 => 子组件
属性props
将父组件的数据通过props传给子组件。
// parent
<common-c :num="appleNum" />
// child
props: {
num: {
type: Number,
default: 0
}
},
2
3
4
5
6
7
8
9
10
11
12
ref
通过引用ref拿到子组件内部的数据或者方法
// parent
<common-c ref="commonC" :num="appleNum" @addNumber="addNumber"/>
this.$refs.commonC.handleToggle()
2
3
4
5
6
# 子组件 => 父组件
使用$emit触发自定义事件
// parent
<common-c @addNumber="addNumber"/>
// child
<el-button @click="addNumber">加苹果</el-button>
addNumber() {
this.$emit('addNumber')
}
2
3
4
5
6
7
8
9
10
11
12
# 兄弟传值
常用方法是以父组件作为中转站,子组件1$emit给父组件,父组件$on给子组件2
// child1
reduceApple() {
this.$emit('reduceApple')
}
// parent
<common-c1 @reduceApple="reduceApple"/> // child1
<common-c :num="appleNum"/> // child2
reduceApple() {
this.appleNum--
}
// child2
props: {
num: {
type: Number,
default: 0
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 祖孙传值
https://cn.vuejs.org/v2/api/#vm-attrs
$attrs
可以获取父作用域传入的值(不包括 props
中的), $listeners
相当于父作用域的事件监听器,从而实现祖孙之间的数据通信。
// 第一代
<common-c2 :info="info" @getName="getName"/>
// 第二代
<Grandson v-bind="$attrs" v-on="$listeners"/>
// 第三代
<h3>第一代传过来的信息是:{{this.$attrs.info}}</h3>
<el-button @click="getName">名字传给第一代</el-button>
getName() {
this.$emit('getName','切图妞')
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- 将组件的所有props传递给子组件
<child v-bind="$props" />
利用v-if可在http请求返回后再显示。这样子组件可以返回的http请求数据。
# EventBus通讯
EventBus
又称为事件总线。在 Vue
中可以使用 EventBus
来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件。工作原理是发布/订阅方法,通常称为 Pub/Sub
# 常用
定义一个vue对象作为eventBus,让其代为订阅发布事件,AB页面通过EventBus文件,分别调用Bus事件触发和监听来实现通信和参数传递。
- EventBus
import Vue from 'vue'
export const EventBus = new Vue()
2
- 发送消息
EventBus.$emit(channel: string, callback(payload1,…))
// A页面
<
el - button @click = "sendMsg" > 发送消息给B < /el-button>
import {
EventBus
} from "./event-bus.js"
sendMsg() {
EventBus.$emit('sendMsg', '我是来自A的消息')
}
2
3
4
5
6
7
8
9
10
11
12
- 监听接收消息
EventBus.$on(channel: string, callback(payload1,…))
// B页面
mounted() {
EventBus.$on('sendMsg', msg => {
this.msg = msg
})
},
2
3
4
5
6
7
# 全局
- 创建全部EventBus
// main.js
Vue.prototype.$bus = new Vue()
2
3
发布订阅模式相当于
var EventBus = new Vue();
Object.defineProperties(Vue.prototype, {
$bus: {
get: function() {
return EventBus
}
}
})
2
3
4
5
6
7
8
9
- 使用
this.$bus.$emit('name', {});
this.$bus.$on('name', ($event) => {})
this.$bus.$off('name')
2
3
4
5
# 问题
多次触发
B页面接收事件的组件没挂载之前仍会接受 $emit,在排队等待dom挂载后集中接收之前发出的全部事件,导致多次触发。 处理方法:在生命周期的beforeDestroy中,将事件销毁。
beforeDestroy() {
EventBus.$off('sendMsg')
}
2
3
https://github.com/vuejs/vue/issues/3399
路由跳转情况下未生效
vue-router切换的时候,会先加载新的组件,当新的组件渲染好但是还没mount的时候,销毁旧组件,然后再挂载新组件,也就是说当B页面的生命周期进行到beforeMount的时候,下一步走到的就是A页面的beforeDestory或者destroyed方法里面。
Dom渲染完毕后再处理回调
this.$nextTick(() => {
})
2
3
- 复杂情况难维护
eventbus
在复杂情况下使用不太方便,若使用不慎易造成难以维护的灾难,需要更完善的Vuex作为状态管理中心,将通知的概念上升到共享状态层次。
https://blog.csdn.net/i168wintop/article/details/95107935