Skip to content

Commit

Permalink
feat: ✨ 新增 Vue3组件通信方法总结
Browse files Browse the repository at this point in the history
  • Loading branch information
dselegent committed Sep 30, 2023
1 parent 52dec01 commit c4b3e7f
Show file tree
Hide file tree
Showing 2 changed files with 594 additions and 133 deletions.
133 changes: 0 additions & 133 deletions vue/vue3/08 【Props 组件事件】.md
Original file line number Diff line number Diff line change
Expand Up @@ -693,136 +693,3 @@ function test() {
```

![image-20220809130712485](https://i0.hdslb.com/bfs/album/b923af6cbf3547f18b1800321b6c53ce7bbfca71.png)

### 2.7 `vue3`中事件总线

#### 2.7.1 插件

1.在vue3中,创建方法改成了createApp({}),prototype属性也被取消了,因此无法使用之前Vue.prototype.$bus = new Vue()的方式使用事务总线。

2.且在vue3中移除了$on,$off方法,因此官方推荐:事件总线模式可以被替换为使用外部的、实现了事件触发器接口的库,例如 mitt 或 tiny-emitter。

3.首先安装mitt:npm install --save mitt

4.在代码中使用:

```js
import mitt from "mitt"
import {createApp} from "vue"

const app = createApp(App)//正常配置
//挂载事务总线
app.config.globalProperties.$bus = mitt()

//在组件A中使用事务总线触发某个动作
import {getCurrentInstance } from 'vue';
const instance = getCurrentInstance();
function send() {
instance.proxy.$bus.emit('receive', '你是一个瓜皮');
}

//在组件B中监听动作的发生
import { getCurrentInstance } from 'vue';
let data = ref('');

// const instance = getCurrentInstance();
const { $bus }: any = getCurrentInstance().appContext.config.globalProperties

$bus.on('receive', str => {
console.log('来数据了');
data.value = str;
});

```

**对于ts文件的写法**

```typescript
import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'

const Mitt = mitt()

//TypeScript注册
// 由于必须要拓展ComponentCustomProperties类型才能获得类型提示
declare module "vue" {
export interface ComponentCustomProperties {
$bus: typeof Mitt
}
}

const app = createApp(App)

//Vue3挂载全局API
app.config.globalProperties.$Bus = Mit

app.mount('#app')
```

#### 2.7.2 手写

`Bus.ts`

```typescript
import * as Console from 'console'


type BusClass = {
emit: (name: string) => void,
on: (name: string, callback: Function) => void
}

type CallbackName = string | number | symbol

type List = {
[key: CallbackName]: Array<Function>
}

class Bus implements BusClass {
list: List

constructor() {
this.list = {}
}

emit(name: string, ...args: Array<any>) {
let callbacks: Array<Function> | undefined = this.list[name]
if (callbacks === undefined) {
console.warn(`event "${name}" is not bound`)
return
}
callbacks.forEach(callback => {
console.log('emit', this)
callback.apply(this, args) // this 为 Bus.ts 导出的实例, on方法如果使用ArrowFunction, 则无法使用this
})
}

on(name: string, callback: Function) {
let callbacks: Array<Function> = this.list[name] || []
callbacks.push(callback)
this.list[name] = callbacks
}
}

export default new Bus()
```

> 挂载到全局Vue config
> 或者单独的页面引入 import Bus from ‘bus.ts’
> Bus.emit 触发,Bus.on监听
![image-20220810185533253](https://i0.hdslb.com/bfs/album/f94abe842d83839d9c7f0f7852094e228f94b3c2.png)

`main.ts`

```ts
import { createApp } from 'vue'
import App from './App.vue'
import Bus from "./utils/Bus"
const app = createApp(App);
app.config.globalProperties.$bus = Bus;
app.mount('#app')
```

使用方法和插件一模一样
Loading

0 comments on commit c4b3e7f

Please sign in to comment.