vue 2 和 vue3 组件的五种通讯方式

1. props 和 $emit

适用于父子组件

父组件:通过:list像子组件传递参数,@showMsg获取子组件传过来的值

在这里插入图片描述

子组件:通过props监听,当点击按钮时,发送this.$emit('父组件的方法',参数)

在这里插入图片描述

2. 自定义事件 event.emit event.on event.off

适用于不相关组件直接的通讯。

vue2同vue3获取总线的方式不同:vue2是直接new vue()实例即可

vue3是使用插件mitt

多对多

event.js

在这里插入图片描述

CustomDemo2和CustomDemo3是两个没有关系的组件

CustomDemo3中发送事件

在这里插入图片描述

CustomDemo2中监听事件:

在这里插入图片描述

vue3 自定义事件 推荐使用mitt插件

1)安装mitt
cnpm i mitt 
2) main.ts 全局引入
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from '../src/router/index'
import 'element-plus/dist/index.css'
import '../src/assets/css/icon.css'
import { createPinia } from 'pinia'
**import mitt, { Emitter } from 'mitt';
type Events = {
    foo: string;
    bar?: number;
}
const mitter: Emitter<Events> = mitt();
const emitter = mitt();**
**app.config.globalProperties.$bus = emitter;**


/**
 * 完整引入 elementPlus 不推荐
 * import ElementPlus from 'element-plus'
 */

const pinia = createPinia();
const app = createApp(App);
app.use(router);


app.use(pinia);
app.mount('#app')
3) 父子组件联系

 child.vue
<template>
    <div>
        <h3>我是子组件</h3>
        <span v-for="item in data.list" :key="item.id">
            {{item.name}}
        </span>

        <div style="margin:100px;">
            <el-button type="success" @click="showMsg">传递给父组件值</el-button>
        </div>
    </div>
</template>
<script setup lang="ts">

import { getCurrentInstance, reactive } from 'vue'
const $bus = getCurrentInstance()?.appContext.config.globalProperties.$bus;

interface ListDemo {
    id: number,
    name: string
}

let data = reactive({
    list: [] as ListDemo[]
})

function showMsg(msg: ListDemo[]) {
   ** $bus.emit('emitterDemo', 'hello')**
}

**$bus.on('list', (msg: ListDemo[]) => {
    data.list = msg;
})**
</script>
  Parent.vue
<template>
    <el-button type="primary" @click="handleClick">点击</el-button>
    <el-input style="margin: 100px;" v-model="data.msg" placeholder="我是被传递过来的值"></el-input>
    <Child></Child>

</template>
<script setup lang="ts">
import { reactive, getCurrentInstance, onMounted, onUnmounted } from 'vue'
import Child from './Child.vue'

const $bus = getCurrentInstance()?.appContext.config.globalProperties.$bus;

interface ListDemo {
    id: number,
    name: string
}
let data = reactive(
    {
        list: [
            { id: 1, name: 'zhangsan' },
            { id: 2, name: 'lisi' }
        ] as ListDemo[],
        msg: ''
    }
);


function handleClick(): void {
   ** $bus.emit('list', data.list);**
};

**$bus.on('emitterDemo', (val: string) => {
    data.msg = val;
})**
onMounted(
    () => {

    }
);

onUnmounted(() => {
    $bus.off('list');
})
</script>

3. $attrs

适用于父子组件。

vue2中在子组件mouted()里面 直接获取 

this.$attrs就可以获取父亲组件中的属性

this.$listeners就可以获取父亲组件中的方法



父组件:定义子组件的属性和方法

在这里插入图片描述

子组件:mouted中可获取

在这里插入图片描述

vue3中,在子组件mouted通过 this,$attrs中获取属性和方法。



也就是说vue3中将this.$listeners和this.$attrs中合并到this.$attrs中。

同时$attrs是对props和emit的补充。

4. $parent $refs

vue2中:

父组件:在子组件上使用ref

在这里插入图片描述

mouted中可以调用子组件的方法和属性

在这里插入图片描述

子组件

在mounted中使用可获取父组件的方法和属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pGiv3eKj-1666597738637)(https://secure2.wostatic.cn/static/89dyTSPa2nW3poZq9FL6tm/image.png?auth_key=1666597565-adcGFv9b9hESBbQJuGMWfh-0-2587c87fadf6269f2f1ace9267750b0e)]

5. provide和inject

适用于任何场合

一个组件中提供

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MysRU3W8-1666597738637)(https://secure2.wostatic.cn/static/34LF1TZQuJTpBDQ7NDJaEt/image.png?auth_key=1666597565-3TBNe2MSsJV8Z82DUM2prv-0-fb8640e8747a4ef5a82319583969a1aa)]

另一个组件中通过inject使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VJ2ilJlB-1666597738637)(https://secure2.wostatic.cn/static/uGcEVcnEeHjFjPTv6qbWK5/image.png?auth_key=1666597565-6VhDLfaFVEw2UZEbaWVN2-0-77a1a2befcbb8dabc9a19ea165b845a2)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值