父子组件传值
子组件
<template>
<div>this is childComponent {{ title }}</div>
</template>
<script setup lang="ts">
// 常规
defineProps({
title:String
})
// 常规设置默认值
defineProps({
title:{
type:String,
default:"默认值"
}
})
// TS语法
defineProps<{
title:string
}>()
// TS设置默认值
withDefaults(defineProps<{
title:string,
arr:number[]
}>(),{
arr:()=>[1,2,3]
})
</script>
父组件
<template>
<div> this is app</div>
<HelloWorld title="name"></HelloWorld>
</template>
<script setup lang="ts">
import HelloWorld from "./components/HelloWorld.vue"
</script>
子组件向父组件传值
子组件
<template>
<div>this is childComponent</div>
<button @click="handleClick">click</button>
</template>
<script setup lang="ts">
const emit = defineEmits(['on-click'])
const handleClick = ()=>{
emit('on-click',"这是子组件的传值")
}
// TS写法
const emit = defineEmits<{
(e:"on-click",name:string):void
}>();
const handleClick = ()=>{
emit('on-click',"这是子组件的传值")
}
</script>
父组件
<template>
<div> this is app</div>
<HelloWorld @on-click="getChildData"></HelloWorld>
</template>
<script setup lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
const getChildData = (data:string)=>{
console.log(data);
}
</script>
依赖注入 provide / inject 方式
父组件
<template>
<HelloWorld></HelloWorld>
</template>
<script setup lang="ts">
import {ref,provide} from "vue";
import HelloWorld from "./components/HelloWorld.vue"
const data = ref("父组件的provide传值")
provide("data",data)
</script>
子组件
<template>
<h2>this is childComponent {{ data }}</h2>
</template>
<script setup lang="ts">
import { inject,Ref, ref } from 'vue'
const data = inject('data',ref(""))
//使用泛型
const data = inject<Ref<string>>("data",ref(""))
</script>
注意: 使用 provide 和 inject 传参子组件可以直接修改, 其他组件也会同步更更新
兄弟组件传值
自定义 eventBus 传参
创建 lib/eventBus.ts
type EventHandler = (data?: any) => void;
export default class EventBus {
private events: Record<string, EventHandler[]> = {};
public emit(eventName: string, data?: any): void {
if (this.events[eventName]) {
this.events[eventName].forEach((fn) => {
fn(data);
});
}
}
public on(eventName: string, fn: EventHandler): void {
this.events[eventName] = this.events[eventName] || [];
this.events[eventName].push(fn);
}
public off(eventName: string, fn: EventHandler): void {
if (this.events[eventName]) {
for (let i = 0; i < this.events[eventName].length; i++) {
if (this.events[eventName][i] === fn) {
this.events[eventName].splice(i, 1);
break;
}
}
}
}
}
在 main.ts 中配置
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import EventBus from "./lib/eventBus.ts";
const $bus = new EventBus();
const app = createApp(App)
app.config.globalProperties.$bus = $bus;
app.mount('#app')
在组件A中设置 emit
<template>
<h1>this is comA</h1>
<button @click="handleClick">click</button>
</template>
<script setup lang="ts">
import {getCurrentInstance} from "vue"
let {proxy}:any = getCurrentInstance();
const handleClick = ()=>{
proxy.$bus.emit("update","传参")
}
</script>
在组件B 中接收传参
<template>
<h1>this is comB</h1>
</template>
<script setup lang="ts">
import {getCurrentInstance} from "vue"
let {proxy}:any = getCurrentInstance();
proxy.$bus.on("update",(data:any)=>{console.log(data);})
</script>
使用第三那方 mitt 传参
原理就是 eventBus
安装
yarn add mitt
创建 src / types / mitt.d.ts 存放 mitt 的类型声明文件
declare module 'mitt' {
type EventHandler<T = any> = (event?: T, ...args: any[]) => void;
type WildcardEventHandler<T = any> = (type: string | symbol, event?: T, ...args: any[]) => void;
type MittEmitter<T = any> = {
on(type: string | symbol, handler: EventHandler<T>): void;
off(type: string | symbol, handler: EventHandler<T>): void;
emit(type: string | symbol, event?: T, ...args: any[]): void;
};
type MittAllEmitter<T = any> = {
on(type: string | symbol, handler: EventHandler<T>): void;
on(handler: WildcardEventHandler<T>): void;
off(type: string | symbol, handler: EventHandler<T>): void;
off(handler: WildcardEventHandler<T>): void;
emit(type: string | symbol, event?: T, ...args: any[]): void;
};
function mitt<T = any>(all?: boolean): MittEmitter<T> | MittAllEmitter<T>;
export default mitt;
}
在 main.ts 中
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import mitt from 'mitt'
const $bus = mitt();
const app = createApp(App)
app.config.globalProperties.$bus = $bus;
app.mount('#app')
使用同上一节的 eventBus 使用方法