父子组件传参
1:父传子
父
:title='name' :arr='[1,2,3]'
const name = 'Jason'
子
{{title}}
const props = defineProps({
title:{
type:string,
default:'Harry'
},
arr:{
type:number[],
default:[0]
}
})
const name = props.title
或
const props = defineProps<{
title:string,
arr:number[]
}>()
//TS 特有设置默认值
withDefaults(defineProps<{
title:string,
arr:number[]
}>(),{
arr:()=>[666],
title:'Harry'
})
2: 子传父 -> 基于事件派发
子:
@click='send'
const emit = defineEmits(['on-click'])
const send = ()=>{
emit('on-click', '小满')
}
或
const emit = defineEmits<{
(e:'on-click',name:string):void
}>()
父:
@on-click='getName'
const getName = (name:string)=>{
console.log(name)
}
3: 子组件暴露属性方法给父组件
子child.vue:
defineExpose({
name:'小满',
open:()=>{console.log('method')}
})
父:
ref="child"
import childVue from './child.vue'
const child = ref<InstanceType<typeof childVue>>()
const name = child.value?.name
child.value?.open()
多重父子组件之间的传参
爷组件
import {provide, readonly} from 'vue'
const color = ref<string>('red')
provide('color', color) 如果不想被子组件修改 provide('color', readonly(color))
父组件
import {inject} from 'vue'
import type {Ref} from 'vue'
const color = inject<Ref<string>>('color',ref('red')) //设默认值
孙组件和父组件一样
import {inject} from 'vue'
import type {Ref} from 'vue'
const color = inject<Ref<string>>('color')
兄弟组件之间传参
1: 通过父组件作为中间
2: EventBus Bus.ts
type BusClass = {
emit:(name:string)=>void
on:(name:string, callback:Function)=>void
}
type paramKey = string|number|symbol
type List = {
[key:paramKey]:Array<Function> //使用对象签名的方式
}
class Bus implements BusClass {
list: List
constructor(){
this.list = {}
}
emit(name:string, ...args:Array<any>){
let eventName:Array<Function> = this.list[name]
eventName.forEach(fn=>{
fn.apply(this, args)
})
}
on(name:string, callback:Function){
let fn:Array<Function> = this.list[name] || []
fn.push(callback)
this.list[name] = fn
}
}
export default new Bus()
A组件
import Bus from './Bus'
Bus.emit('on-click','Jason')
B组件
import Bus from './Bus'
Bus.on('on-click', (name:string)=>{
console.log(name)
})
3: 使用第三方组件Mitt
npm install mitt -S
方式一: 挂载到全局 main.ts
import mitt from 'mitt'
const Mit = mitt()
//TS注册,必须拓展ComponentCustomProperties类型才能得到类型提示
declare module "vue" {
export interface ComponentCustomProperties{
$Bus: typeof Mit
}
}
const app = createApp(App)
//Vue3挂载全局API
app.config.globalProperties.$Bus = Mit
A组件
@click='emit'
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
const emit = ()=>{
instance?.proxy.$Bus.emit('on-click', 'Jason')
}
B组件
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
instance?.proxy?.$Bus.emit('on-click', (name;string)=>{
console.log(name)
})
多条的情况
const callback = (type, callback)=>{
console.log(type, param)
}
instance?.proxy?.$Bus.emit('*', callback)
删除监听事件
instance?.proxy?.$Bus.off('on-click', callback)
删除所有监听事件
instance?.proxy?.$Bus.all.clear()