标签
note
字数
787 字
阅读时间
4 分钟
$attrs和 $slots
$attrs
存在一个场景,A 组件是 B 组件的父组件,B 组件是 C 组件的父组件(即 A 是 C 的祖父组件),要实现 A 传递数据到 C,B 中不需要显示,如何实现?
- 使用
props嵌套使用 - 使用
$attrs(属性透传的特性)
用例:
vue
<script>
let vm = new Vue({
el: '#app',
data: {
msg: '100'
},
components: {
'ComponentB': {
template: `<div>B<component-c v-bind="$attrs"></component-c></div>`,
components: {
'ComponentC': {
props: ['msg'],
template: '<div>C{{msg}}</div>'
}
}
},
}
})
</script>其中:inheritAttrs: false
$slots
vm.$slots 是一个对象,键名是所有具名 slot 的名称,加上一个 default,而键值则是一个存放 VNode 节点的数值
详情参考:
事件总线 EventBus
概述
Vue 中的组件与组件间数据通信可抽象为两种通信关系,兄弟组件,父子组件(包括祖父组件的层级嵌套),而 Vue 为每种关系都配备有对应的通信方式
父子组件:
1. props 和 $emit
2. attrs 和 listeners
3. v-model
4. provide 和 inject
5. 中央事件总线
6. parent 和 children
7. boardcast 和 dispatch
8. vuex
兄弟组件:
- EventBus

初始化
创建事件总线并将其导出,以便其它模块可以使用或者监听它
方法一(单独写一个 js 文件)
js
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()方法二(在项目的 main.js 中)
js
// main.js
Vue.prototype.$EventBus = new Vue()数据通信
用到的两个方法:
EventBus.$emit(channel: string, callback(payload1,…))// 抛出事件EventBus.$on(channel: string, callback(payload1,…))// 监听事件
应用场景:存在 A 和 B 两个 Vue页面,点击 A 中的按钮发送数据给 B 页面
A 页面 发送数据
js
<!-- A.vue -->
<template>
<button @click="sendMsg()">-</button>
</template>
<script>
import { EventBus } from "../event-bus.js";
export default {
methods: {
sendMsg() {
EventBus.$emit("aMsg", '来自A页面的消息');
}
}
};
</script>B 页面接收数据
js
<!-- IncrementCount.vue -->
<template>
<p>{{msg}}</p>
</template>
<script>
import {
EventBus
} from "../event-bus.js";
export default {
data(){
return {
msg: ''
}
},
mounted() {
EventBus.$on("aMsg", (msg) => {
// A发送来的消息
this.msg = msg;
});
}
};
</script>移除 EventBus
- 业务场景同上,当 A 页面的按钮反复触发,
EventBus便会多次触发,此时可以通过EventBus.$off('aMsg', {})来移除事件的监听
全局 EventBus
创建全局 EventBus
js
var EventBus = new Vue();
Object.defineProperties(Vue.prototype, {
$bus: {
get: function () {
return EventBus
}
}
})在这个特定的总线中使用两个方法 $on 和 $emit。一个用于创建发出的事件,它就是 $emit;另一个用于订阅 $on:
js
var EventBus = new Vue();
this.$bus.$emit('nameOfEvent', { ... pass some event data ...});
this.$bus.$on('nameOfEvent',($event) => {
// ...
})然后我们可以在某个 Vue 页面使用 this.$bus.$emit("sendMsg", '我是web秀');,另一个 Vue 页面使用
js
this.$bus.$on('updateMessage', function(value) {
console.log(value); // 我是web秀
})同时也可以使用 this.$bus.$off('sendMsg') 来移除事件监听