[GN] Vue3.2 快速上手 ---- 组件通信


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>

子组件
defineProps 引父组件传来的

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


提示:以下是本篇文章正文内容,下面案例可供参考

mitt – 任意组件

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

安装mitt

npm i mitt
  1. 新建文件:src\utils\emitter.ts
// 引入mitt 
import mitt from "mitt";

// 创建emitter
const emitter = mitt()

/*
  // 绑定事件
  emitter.on('aaa',(value)=>{
    console.log('aaa事件被触发',value)
  })
  setInterval(() => {
    // 触发事件
    emitter.emit('aaa',666)
  }, 1000);
  setTimeout(() => {
    // 清理事件
    emitter.all.clear()
  }, 3000); 
*/

// 创建并暴露mitt
export default emitter
  1. 接收数据的组件中:绑定事件、同时在销毁前解绑事件:
import emitter from "@/utils/emitter";
import {
    onUnmounted } from "vue";

// 绑定事件
emitter.on('send-toy',(value)=>{
   
  console.log('send-toy事件被触发',value)
})

onUnmounted(()=>{
   
  // 解绑事件
  emitter.off('send-toy')
})
  1. 提供数据的组件,在合适的时候触发事件
import emitter from "@/utils/emitter";

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

注意这个重要的内置关系,总线依赖着这个内置关系

r e f s 、 refs、 refsparent – 父 ↔ 子

概述:

  • $refs用于 :父→子。
  • $parent用于:子→父。

原理如下:

属性 说明
$refs 值为对象,包含所有被ref属性标识的DOM元素或组件实例。
$parent 值为对象,当前组件的父组件实例对象。

provide、inject 祖->孙

  1. 概述:实现祖孙组件直接通信

  2. 具体使用:

    • 在祖先组件中通过provide配置向后代组件提供数据
    • 在后代组件中通过inject配置来声明接收数据
  3. 具体编码:

    【第一步】父组件中,使用provide提供数据

    <template>
      <div class="father">
        <h3>父组件</h3>
        <button @click="money += 1">资产+1</button>
        <button @click="car.price += 1">汽车价格+1</button>
        <Child/>
      </div>
    </template>
    
    <script setup lang="ts" name="Father">
      import Child from './Child.vue'
      import {
          ref,reactive,provide } from "vue";
      // 数据
      let money = ref(100)
      let car = reactive({
         
        brand:'奔驰',
        price:100
      })
      // 用于更新money的方法
      function updateMoney(value:number){
         
        money.value += value
      }
      // 提供数据
      provide('moneyContext',{
         money,updateMoney})
      provide('car',car)
    </script>
    

    注意:子组件中不用编写任何东西,是不受到任何打扰的

    【第二步】孙组件中使用inject配置项接受数据。

    <template>
      <div class="grand-child">
        <h3>我是孙组件</h3>
        <h4>资产:{
         {
          money }}</h4>
        <h4>汽车:{
         {
          car }}</h4>
        <button @click="updateMoney(6)">点我</button>
      </div>
    </template>
    
    <script setup lang="ts" name="GrandChild">
      import {
          inject } from 'vue';
      // 注入数据
     let {
         money,updateMoney} = inject('moneyContext',{
         money:0,updateMoney:(x:number)=>{
         }})
      let car = inject('car')
    </script>
    

slot

默认插槽

父组件中:
        <Category title="今日热门游戏">
          <ul>
            <li v-for="g in games" :key="g.id">{
   {
    g.name }}</li>
          </ul>
        </Category>
子组件中:
        <template>
          <div class="item">
            <h3>{
   {
    title }}</h3>
            <!-- 默认插槽 -->
            <slot></slot>
          </div>
        </template>

具名插槽

父组件中:
        <Category title="今日热门游戏">
          <template v-slot:s1>
            <ul>
              <li v-for="g in games" :key="g.id">{
   {
    g.name }}</li>
            </ul>
          </template>
          <template #s2>
            <a href="">更多</a>
          </template>
        </Category>
子组件中:
        <template>
          <div class="item">
            <h3>{
   {
    title }}</h3>
            <slot name="s1"></slot>
            <slot name="s2"></slot>
          </div>
        </template>

相关推荐

  1. [GN] Vue3.2 快速上手 ---- 组件通信

    2024-01-27 11:10:02       58 阅读
  2. [GN] Vue3.2 快速上手 ----常用API及其新组件

    2024-01-27 11:10:02       54 阅读
  3. electron 快速上手学习

    2024-01-27 11:10:02       48 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-27 11:10:02       91 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-27 11:10:02       97 阅读
  3. 在Django里面运行非项目文件

    2024-01-27 11:10:02       78 阅读
  4. Python语言-面向对象

    2024-01-27 11:10:02       88 阅读

热门阅读

  1. CF1029E Tree with Small Distances 题解

    2024-01-27 11:10:02       57 阅读
  2. TiDB中Table映射到KV

    2024-01-27 11:10:02       55 阅读
  3. nginx做盗链与防盗链配置

    2024-01-27 11:10:02       46 阅读
  4. 常用的gpt-4 prompt words收集8

    2024-01-27 11:10:02       50 阅读
  5. php 源码加密保护 bease方案

    2024-01-27 11:10:02       49 阅读
  6. android studio开发的一些问题

    2024-01-27 11:10:02       54 阅读
  7. CentOS 7.9 OS Kernel Update 3.10 to 4.19

    2024-01-27 11:10:02       41 阅读
  8. 出现次数超过一半的数(c++题解)

    2024-01-27 11:10:02       50 阅读