事件总线 和 插槽(slot )

事件总线 和 插槽(slot )的介绍

文章目录

  • 一、事件总线
    • 1. 手动实现事件监听和触发
    • 2.模板引用
  • 二、插槽(slot )
    • 1.插槽出口(slot outlet)和插槽内容(slot content)
      • 默认内容
    • 2.具名插槽
    • 3.作用域插槽


提示:以下是本篇文章正文内容,下面案例可供参考

一、事件总线

可以通过事件总线实现组件之间的通信。

配置全局属性(定义 $bus 为全局属性名,之后可以通过 this.$bus 可以调用 )

 app.config.globalProperties.$bus = mitt();
 app.config.globalProperties.$inEventName = '输入';
 app.mount('#first');

注册事件监听器,要明确 事件事件 和 监听器。

created() {
    // 注册事件监听器
    // 需要明确 事件名称 和 事件监听器
    this.$bus.on( this.$inEventName, this.changeContent );
}

1. 手动实现事件监听和触发

尝试获得指定事件名称对应的监听器数组,成功获取到监听器数组,并且在监听器数组末尾追加新的监听器;如果未能获取到监听器数组,则向 map 中添加新的映射。

    on( name, listener ) {
        // 先尝试获得指定事件名称对应的监听器数组
        let listeners = this.#map.get(name);
        // 若成功获取到监听器数组
        if( listeners ) {
            // 则在监听器数组末尾追加新的监听器
            listeners.push(listener);
            return;
        }
        // 若未能获取到监听器数组,则向 map 中添加新的映射
        this.#map.set( name, [listener] );
    }

尝试获得指定事件名称对应的监听器数组。

    emit(name, payload){
        // 先尝试获得指定事件名称对应的监听器数组
        let listeners = this.#map.get(name);
        if( listeners ){
            listeners.forEach( fn => fn(payload) );
        }
    }
    off(name) {
        if( this.#map.has( name ) ) {
            this.#map.delete(name);
        }
    }
    toString() {
        return this.#map.entries();
    }

2.模板引用

事件总线 和 插槽(slot )_第1张图片
挂载结束后引用都会被暴露在 this.$refs 之上:

 mounted() {
     console.log( this.$refs );
     console.log( this.$refs.unameInput );
 }

注意,你只可以在组件挂载后才能访问模板引用。如果你想在模板中的表达式上访问 $refs.input,在初次渲染时会是 null。这是因为在初次渲染前这个元素还不存在呢!

二、插槽(slot )

把父组件的内容插入到子组件预留好的位置上。

1.插槽出口(slot outlet)和插槽内容(slot content)

子组件预留的位置为 插槽出口(slot outlet) ,而父组件要插入的内容称为 插槽内容(slot content)。

在子元素中设定标签 作为 插槽出口(slot outlet)

  template: ``,

事件总线 和 插槽(slot )_第2张图片
而在父元素中在标签

  template: `
点我试试 {{this.text}}
`
,

元素是一个插槽出口 (slot outlet),标示了父元素提供的插槽内容 (slot content) 将在哪里被渲染。通过使用插槽, 仅负责渲染外层的 `,

 template: ``,

如果我们想在父组件没有提供任何插槽内容时在