Skip to content
标签
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') 来移除事件监听

参考

Vue事件总线(EventBus)使用详细介绍

贡献者

The avatar of contributor named as jiechen jiechen

页面历史

撰写