Vue3学习 组件之间的传参

父子组件传参

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()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值