Vue3组件通信 详解(上)

Vue3组件通信和Vue2的区别

  • 移出事件总线,使用mitt代替。
  • vuex换成了pinia
  • .sync优化到了v-model里面了。
  • $listeners所有的东西,合并到$attrs中了。
  • $children被砍掉了。

常见搭配形式

props

概述:props是使用频率最高的一种通信方式,常用与 :父 ↔ 子

  • 父传子:属性值是非函数
  • 子传父:属性值是函数

父组件:

<template>
  <div class="father">
    <h3>父组件,</h3>
		<h4>我的车:{{ car }}</h4>
		<h4>儿子给的玩具:{{ toy }}</h4>
		<Child :car="car" :getToy="getToy"/>
  </div>
</template>

<script setup lang="ts" name="Father">
	import Child from './Child.vue'
	import { ref } from "vue";
	// 数据
	const car = ref('奔驰')
	const toy = ref()
	// 方法
	function getToy(value:string){
		toy.value = value
	}
</script>

子组件:

<template>
    <div class="child">
      <h3>子组件</h3>
          <h4>我的玩具:{{ toy }}</h4>
          <h4>父给我的车:{{ car }}</h4>
          <button @click="getToy(toy)">玩具给父亲</button>
    </div>
  </template>
  
  <script setup lang="ts" name="Child">
      import { ref } from "vue";
      const toy = ref('奥特曼')
      
      defineProps(['car','getToy'])
  </script>

自定义事件

  • 子组件中:使用“defineEmits”定义事件命名为“Xxx”
  • 子组件中:调用事件“Xxx”,将数据传递出去
  • 父组件中:调用组件,绑定事件“Xxx”,接受数据

子组件:

<template>
  <button @click="butFn">改变page值</button>
</template>
  
<script setup lang="ts" name="Child">
  import {ref} from 'vue'
  //自定义事件:child
  const emit = defineEmits(['child']);
  //数据:num
  let num=ref(1);
  //方法:child,
  const butFn=()=>{
    emit("child",num.value)
    num.value+=1;
  }
</script>

父组件: 

<template>
  值:{{ page }}
  <Child    
      @child="pageFn"
  ></Child>
</template>

<script setup lang="ts" name="Father">
  import {ref} from 'vue'
  import Child from '@/components/_1_tongxun/zi_ding_yi_shi_jian/Child.vue'

  //数据
  const page=ref(0)
  //方法
  const pageFn=(val1:number)=>{
    page.value=val1
  }
</script>

Mitt

概述:与消息订阅与发布(pubsub)功能类似,可以实现任意组件间通信。

安装mitt

npm i mitt

model.ts文件

  • 暴露emitter
// 引入mitt 
import mitt from "mitt";
// 创建emitter
const emitter = mitt()
//暴露emitter
export default emitter

Model1.vue文件

<template>
    <h2>------------------------------</h2>
    <h2>{{ num }}</h2>
    <button @click="sendToy">按钮1</button>

</template>

<script setup lang="ts" name="Model1">
import emitter from './model';
import { ref, onUnmounted, onMounted } from 'vue';

let num = ref<number>(0);

onMounted(() => {
  // 接受事件
  emitter.on('send-toy',(res: any)=>{
    num.value=res;
  });
})


function sendToy(){
  // 触发事件
  emitter.emit('send-toy',num.value+1);
}

onUnmounted(()=>{
  // 解绑事件
  emitter.off('send-toy')
})

</script>

Model2.vue文件

<template>
  <h2>------------------------------</h2>
  <h2>{{ num }}</h2>
    <button @click="sendToy">按钮2</button>

</template>

<script setup lang="ts" name="Model2">
import emitter from './model';
import { ref, onUnmounted, onMounted } from 'vue';

let num = ref<number>(0);

onMounted(() => {
  // 接受事件
  emitter.on('send-toy',(res: any)=>{
    num.value=res;
  });
})


function sendToy(){
  // 触发事件
  emitter.emit('send-toy',num.value+1);
}

onUnmounted(()=>{
  // 解绑事件
  emitter.off('send-toy')
})

</script>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值