vue3组件通信(七种方法)

目录

1.props

2.v-model 

3.自定义事件

4. 全局事件总线 $bus

5.ref和$parent 

ref使用方法:

$parent使用方法:

6.provide-inject 订阅

7.其他 

1.props

 //父给子组件Categorys 传了一个categoryList属性

<Categorys :categoryList="categoryList"></Categorys>

 子组件使用:

ts写法:

//ts写法

import type { categoryPanel } from "@/types/index"

defineProps<{

    categoryList: categoryPanel[]

}>()

@/types/index文件:

export interface categoryPanel {

    id: string,

    name: string,

    icon: string,

}

普通写法:

defineProps({

categoryList:Object

)

2.v-model 

父组件:

//一个响应式通信 

<Child v-model="money"></Child>

//多个响应式通信

<Child1 v-model:pageNo="pageNo" v-model:pageSize="pageSize"></Child1>

Child:

let props = defineProps(["modelValue"]);

let $emit = defineEmits(['update:modelValue']);

//子组件内部按钮的点击回调

const handler = ()=>{

   //触发自定义事件

   $emit('update:modelValue',props.modelValue+1000);

}

Child1:

let props = defineProps(["pageNo", "pageSize"]);

let $emit = defineEmits(["update:pageNo", "update:pageSize"]);

//第一个按钮的事件回调

const handler = () => {

  $emit("update:pageNo", props.pageNo + 3);

};

它其实是个语法糖,其底层原理为

父组件:

let money = ref(10000);

//自定义事件的回调

const handler = (num) => {

  //将来接受子组件传递过来的数据

  money.value = num;

};

//给子组件child传入modelValue属性 和 @update:modelValue方法

<Child :modelValue="money" @update:modelValue="handler"></Child>

子组件:

 <h3>钱数:{{ modelValue }}</h3>

//接受props

let props = defineProps(["modelValue"]);

let $emit = defineEmits(['update:modelValue']);

//子组件内部按钮的点击回调

const handler = ()=>{

   //触发自定义事件

   $emit('update:modelValue',props.modelValue+1000);

}

这样就实现了父子响应式通信; 

3.自定义事件

自定义事件和v-model差不多

父组件:

let money = ref(0);

//自定义事件的回调

const handler = (num) => {

  //将来接受子组件传递过来的数据

  money.value = num;

};

//给子组件child传入modelValue属性 和 @update:modelValue方法

<Child @hander="handler"></Child>

子组件:

//接受props

let $emit = defineEmits(['hander']);

//子组件内部按钮的点击回调

const handler = ()=>{

   //触发自定义事件

   $emit('hander',1000);

}

这样子组件通过调用 handler 方法,改变了父组件的 money.

4. 全局事件总线 $bus

vue3没有全局事件总线 $bus,但可以通过引入mitt插件实现全局事件总线。

$bus文件:

// 引入全局事件总线

import mitt from 'mitt'

 const $bus = mitt()

 export default $bus

兄弟组件1:

//引入$bus

import $bus from '@/bus/index' 

//创建一个taggleImg事件,并传入参数index

let taggleImg = (index) => {

  $bus.emit('taggleImg', index)

}

 兄弟组件2:

//引入$bus

import $bus from '@/bus/index' 

let  imgIndex = ref(0)

$bus.on('taggleImg',(index)=>{

  imgIndex.value = index

})

当兄弟组件1调用taggleImg方法,就会改变兄弟组件2的imgIndex值

5.ref和$parent 

ref:父组件通过拿到子组件实例,就可以拿到子组件暴露的属性,方法

ref使用方法:

父组件:

//给子组件绑定ref

<Child ref="son"></Son>

//变量名必须为son

const son= ref()

//父组件内部按钮点击回调

const handler = ()=>{

   son.value.money-=10;

}

子组件:

let money = ref(666);

//组件内部数据对外关闭的,别人不能访问

//如果想让外部访问需要通过defineExpose方法对外暴露

defineExpose({

  money,

})

这样父组件通过ref调用子组件实例暴露的money属性 。

$parent:和自定义事件、props类似,实现子组件获取父组件属性、方法,不过它需要父组件暴露对应的属性、方法

$parent使用方法:

父组件:

let money = ref(100)

defineExpose({

   money

})

子组件:

//直接调用$parent,拿到父组件暴露的属性、方法

const handler = ($parent)=>{

   $parent.money-=10000;

}

6.provide-inject 订阅

vue3提供provide(提供)与inject(注入),可以实现隔辈组件传递数据(数据为响应式数据,父子相互响应)

祖先:

import { ref, provide } from "vue";

let car = ref("法拉利");

//两个参数:第一个参数就是提供的数据key

//第二个参数:祖先组件提供数据

provide("TOKEN", car);

后辈:

import {inject} from 'vue';

let car = inject('TOKEN');

const updateCar = ()=>{

//可以修改祖先的值

   car.value  = '自行车';

}

7.其他 

useAttrs方法,它和defineEmits几乎一样,但defineEmits的优先级更高

//父组件:

<Child @handler = "handler ">

const handler = ()=>{

  alert(12306);

}

//子组件

import {useAttrs} from 'vue';

//此方法执行会返回一个对象

let $attrs = useAttrs();

用一些插件(pinia、vuex...)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值