Vue3最佳实践 第五章 Vue 组件应用 2 ( Emit )

news/2024/7/7 20:16:48

  本章带领大家理解组件、props、emits、slots、providers/injects,Vue 插件 等Vue组件使用的基础知识。

第一章 Vue3项目创建 1 Vue CLI 创建vue项目
第一章 Vue3项目创建 2 使用 Webpack 5 搭建 vue项目
第一章 Vue3项目创建 3 Vite 创建 vue项目
第二章 Vue3 基础语法指令
第三章 Vue Router路由器的使用
第四章 VUE常用 UI 库 1 ( element-plus,Ant ,naiveui,ArcoDesign)
第四章 VUE常用 UI 库 2 ( ailwind 后台框架)
第五章 Vue 组件应用 1( Props )
第五章 Vue 组件应用 2 ( Emit )
第五章 Vue 组件应用 3( Slots )
第五章 Vue 组件应用 4 ( provide 和 inject )
第五章 Vue 组件应用 5 (Vue 插件)

5.3 Emit

  上面我们讲到了props使用,props是用于将父组件中的数据传递给子组件的。在有些开发代码中是需要将子组件的数据返回给父组件,如果由于用户在子组件中执行的操作而需要更新父级的反应变量,则需要一个通知机制让子组件通知父组件应该更新父组件中目标反应变量。在vue3中给我们提供了Emit 用于完成上面功能实现。Emit 负责从子组件通知父组件,它可以将数据和事件一起传递给父组件。Emit 用于将数据从子级传递到父级,而 props 用于将数据从父级传递到子级。
在这里插入图片描述

5.3.1 $emit生成事件

  介绍如何使用 $emit 从子组件到父组件的事件通信。如果你想从子组件的模板标签中使用父组件中的事件,只需将你选择的父组件中的事件名称设置为 e m i t 参数。在子组件中的按钮上设置点击事件,这个点击事件绑定 emit 参数。在子组件中的按钮上设置点击事件,这个点击事件绑定 emit参数。在子组件中的按钮上设置点击事件,这个点击事件绑定emit,$emit参数是父组件事件的引用。子组件Index.vue中的代码实现一下内容。

<script setup>
</script>
<template>
  <div>
    <h2>子组件</h2>
    <button @click="$emit('nozht')">通知父组件</button>
  </div>
</template>

在父组件App.vue中创建一个handleEvent函数,将它和子组件index 中v-on绑定在一起。使用 v-on 指令并在 v-on: 之后设置 $emit 函数引用名称nozht,然后在绑定handleEvent事件到 $emit 函数中。子组件执行事件的过程是通过引用名称nozht来找到父组件中的它绑定的函数,并执行这个函数。

<script setup>
import index from './components/index.vue';
const handleEvent = () => {
  alert('获得子组件事件');
};
</script>
<template>
//  v-on 指令 引用名称=执行事件
 <index v-on:nozht="handleEvent"  />
</template>

  单击出现在屏幕上的“通知父组件”按钮。会显示handleEvent函数中“获得子组件事件”,则说明父组件成功检测到子组件发生的事件。

在这里插入图片描述

**$ emit事件参数KaTeX parse error: Expected 'EOF', got '&' at position 11: event设置** &̲emsp;&emsp;在emit函数除了绑定事件,也可以绑定这个事件的参数。例如我们将 e v e n t 参数通过 event参数通过 event参数通过emit函数函数赋值给onzht引用的函数handleEvent。

<script setup>
</script>
<template>
  <div>
    <h2>子组件</h2>
    <button id="1111" @click="$emit('onzht',$event)">通知父组件</button>
  </div>
</template>

在App.vue代码中做一下修改。

<script setup>
import index from './components/index.vue';
const handleEvent = (event) => {
  console.log(event.target.id);
};
</script>
<template>
 <index v-on:onzht="handleEvent"  />
</template>

5.3.2 使用 defineEmits

  在上面介绍了当index.vue组件中生成通知父组件事件时,如何在模板的html标签中使用$emit 函数。现在我们在来介绍下如何使用 defineEmits 函数与父组件进行信息通信。

   我们来改写 Index.vue组件中的代码,在脚本中创建defineEmits()函数获得emit对象,在脚本中其他事件中通过使用emit对象与父组件进行通信。在创建sendation函数,在函数中使用emit指定要执行父组件中onzht指向的函数。在将sendation函数与模板中按钮事件绑定在一起,当点击页面的按钮时就会通过sendation函数来执行父组件中的函数了。这样做可以在更自由的使用emits对象来进行业务逻辑的加工了。

<script setup>
//定义defineEmits获得emits对象
const emit = defineEmits();
const sendation = () => {
  emit('onzht');//执行emits中对应的onzht事件引用
};
</script>
<template>
  <div>
    <h2>子组件</h2>
    <button id="1111" @click="sendation">通知父组件</button>
  </div>
</template>

App.vue中的代码内容。

<script setup>
import index from './components/index.vue';
const handleEvent = () => {
  alert(1);
};
</script>
<template>
 <index v-on:onzht="handleEvent"  />
</template>

1 emit 函数传值

  emit是defineEmits()函数返回的Emits对象,emit函数第一个参数是父组件绑定的事件名称,以后的参数是绑定事件的参数,按顺序依次排列。在父组件App.vue代码中我们定义的函数中,要获得子组件的,事件源,参数一,参数二等信息。

<script setup>
import index from './components/index.vue';
const handleEvent = (event,a1,a2) => {
  alert(a1);//参数一
  alert(a2);//参数二
  console.log(event);//事件源
};
</script>
<template>
 <index v-on:onzht="handleEvent"  />
</template>

在子组件中使用emit函数来传递这些值。

<script setup>
const emit = defineEmits();
//获得事件,参数一,参数二
const sendation = (event,a1,a2) => {
   //子组件中的信息传给父组件
  emit('onzht',event,a1,a2);
};
</script>
<template>
  <div>
    <h2>子组件</h2>
    <button id="1111" @click="sendation(
                              $event,
                              '参数一',
                              '参数二')">
        通知父组件</button>
  </div>
</template>

2 emit绑定多个父组件事件

  在开发中很多时候子组件需要使用到父组件中的很多方法,那这些方法都可以在Emit中进行传递。在父组件app.vue中定义两个函数绑定到Emit中来。

<script setup>
import index from './components/index.vue';
const handleEvent = (event,a1,a2) => {
  alert(a1);
  alert(a2);
  console.log(event);
};
const onfind=()=>{
  alert("我是父类的onfind方法");
}
</script>
<template>
 <index v-on:onzht="handleEvent"  ----绑定到Emit中onzht属性上
        v-on:onfind="onfind"      ----绑定到Emit中onfind属性上
        />
</template>

在子组件index.vue中定义这两个函数的触发事件。

<script setup>
const emit = defineEmits(['onzht','onfind'])
const sendation = (event,a1,a2) => {
  emit('onzht',event,a1,a2);//触发父组件中的handleEvent事件
};
const sendfind=()=>{
  emit('onfind');//触发父组件中的onfind事件
}
</script>
<template>
  <div>
    <h2>子组件</h2>
    <button id="1111"
            @click="sendation($event,
                    '参数一','参数二')">通知父组件</button>
    <br>
    <button @click="sendfind">通知父组件onfind函数</button>
  </div>
</template>

5.3.3 emit参数更新值

  在开发中通过Emit事件子组件向父组件传值改变父组件中的变量值,但是也可以使用Emit中的触发的事件通知更新父组件中定义的反应变量。

  在 App.vue 文件中使用ref 函数定义一个反应变量name。使用 props 将name传递给 index组件。在子组件 index 中运行父组件中onfind方法将传入一个子组件中定义的参数值给父组件反应变量name ,父组件name值更新,子组件props 中的name值也更新。

<script setup>
import { ref } from 'vue';
import index from './components/index.vue';
const name = ref('zht');
const onfind=(cname)=>{
  name.value=cname;
}
</script>
<template>
 <index :name="name" v-on:onfind="onfind"/>
</template>

在 Index组件中,单击按钮会执行 sendfind函数,在sendfind函数内执行父组件onfind方法,并为父组件中的反应属性name传入值。

<script setup>
const props = defineProps({
  name: String,
});
const emit = defineEmits();
const sendfind=()=>{
  emit('onfind','子组件名称');
}
</script>
<template>
  <div>
    <h2>子组件</h2>
    <p>父组件中name: {{props.name }}</p>
    <button @click="sendfind">通知父组件onfind函数</button>
  </div>
</template>

  在点击“通知父组件onfind函数”按钮之前,屏幕上会显示 父组件中name: zht,说明props 中收到的name的初始值。
在这里插入图片描述
  当点击“通知父组件onfind函数”按钮时,会产生一个changeNameEvent,父组件检测到changeNameEvent事件,执行onfind函数,将反应变量name的值从“zht”更新为“子组件名称”。
在这里插入图片描述

  通过使用 emit,我们能够理解如何在子组件中执行的操作来更新父组件的反应变量。在子组件仅执行事件函数,但实际更新是由收到允许更新通知的父组件完成的。

5.3.4 emit输入元素

  这里我们将emit与input元素中的v-model 指令联合使用,开发一个有输入表单input元素的组件。使用这组件可以共通其他有输入input功能到这个组件中来完成,这样我们就可以在父组件中通过这个input组件设置多个input元素,通过一个主input组件控制父组件中所有使用到它组件样式与函数功能了。达到修改一个input组件就可以让所有使用这组件都会反生改变。

   输入组件一定要确保 v-model 指令中设置了@input 事件。在components文件夹下创建一个Input.vue文件,在input.vue文件中使用 props 为 input 元素设置值 modelValue。在input 元素中定义@input事件,这个事件中使用 e m i t 函数,让它的输入值和它的父组件进行通信。 emit函数,让它的输入值和它的父组件进行通信。 emit函数,让它的输入值和它的父组件进行通信。emit函数中第一参数是事件名称为update:modelValue 值,第二个参数是input 元素中的输入值。注意 Input 元素一定要确保设置了modelValue 值和@input 事件。

  <input
    :value="props.modelValue"   -----设置元素值
    @input="$emit(
            'update:modelValue', -----修改事件
            $event.target.value) -----表单输入值
  " />

当用户在input元素中输入值时,update:modelValue事件会被触发,它会将input元素中输入的值随事件传递给父组件。父组件接收到Input 组件通过 update:modalValue 事件发送过来的值,更新组件中 v-model 指令指定的变量值。

<script setup>
const props = defineProps({
  modelValue: String,
});
</script>
<template>
  <input
    :value="props.modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
</template>

  在导入 Input 组件的父组件 App.vue 文件中,通过 ref 函数定义name反应变量,在Input 组件中用modal-value指令绑定这个name变量。与 v-model 绑定后 Input 组件中props就可以使用到name了,它就可以设置成为输入元素的值。

<script setup>
import { ref } from 'vue';
import input from './components/input.vue';
const name = ref('zht');
</script>
<template>
  <p>name:{{ name }}</p>
  <input :model-value="name"/>
</template>

  子组件通过 props 接收到name,但在 input 元素中输入字符不会改变任何内容。这是因为父组件中未配置监听子组件中发生修改的事件。

  在 Input 组件中添加 @update:model-value 以检测从子组件发生的 update:modelValue 事件,并设置变化发生后name变量接收 e v e n t 值。 event值。 event值。event值中的数据是 emit 中事件$event.target.value参数值。

<index :model-value="name" @update:model-value="name = $event" />

App.vue 文件中全部的代码内容。

<script setup>
import { ref } from 'vue';
import input from './components/input.vue';
const name = ref('zht');
</script>
<template>
  <p>name:{{ name }}</p>
  <input :model-value="name"
         @update:model-value="name = $event"/>
</template>

  这看起来很复杂是因为事件名称包含一个 :(冒号)并使用name=$event 获得值,但它能更好的样我们理解目前学到的 props 和 emit。

在这里插入图片描述

我们在input.vue文件中将input元素中加入css样式,让它变得更美观一些吧。

<script setup>
const props = defineProps({
  modelValue: String,
});
</script>
<template>
  <input
    :value="props.modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
    style="padding: 1em; border-radius: 1em; margin: 0.5em"
  />
</template>

Input组件重复使用

​ 组件化输入元素的优点是可以重用。如果要显示同样设计的input元素,在App.vue中设置多个反应变量,将它们设置到Input组件中。

<script setup>
import { ref } from 'vue';
import input from './components/input.vue';
const name = ref('zht');
const address = ref('');
</script>
<template>
  <h1>emit 输入元素</h1>
  <p>名称:{{ name }}</p>
  <p>地址:{{ address }}</p>
  <input :model-value="name"------对应ref变量
         @update:model-value="name = $event"/>---对象ref变量
  <input :model-value="address"------对象ref变量
         @update:model-value="address = $event"/>---对象ref变量
</template>

我们要使用到相同设计内容的输入元素,可以将它的内容定义在一个子组件中,这样在父组件中就能重复使用它。这样的设计的好处就是,改变所有输入元素内容的时候直接修改子组件,这些输入元素都会发生变化。

在这里插入图片描述

input组件设置多个参数

​ 在input组件中可以使用v-model 设置多个反应变量值。从 Vue3 开始,现在可以在一个元素中对多个值进行v-model 联动绑定。App.vue中将name与address装入到input组件中props中。

<script setup>
import { ref } from 'vue';
import input from './components/input.vue';
const name = ref('zht');
const address = ref('');
</script>
<template>
  <h1>emit 输入元素</h1>
  <p>名称:{{ name }}</p>
  <p>地址:{{ address }}</p>
  <input v-model:name="name" v-model:address="address"/>
</template>

在input.vue文件中将name与address与输入元素绑定在一起。

<script setup>
const props = defineProps({
  name: String,
  address:String,
});
</script>
<template>
  名称
  <input
    :value="props.name"
    @input="$emit('update:name', $event.target.value)"
    style="padding: 1em; border-radius: 1em; margin: 0.5em"
  />
  地址
  <input
    :value="props.address"
    @input="$emit('update:address', $event.target.value)"
    style="padding: 1em; border-radius: 1em; margin: 0.5em"
  />
</template>


浏览其中在两个文本框中输入内容,对应的name与address参数在页面中显示出现。

在这里插入图片描述


http://lihuaxi.xjx100.cn/news/1576378.html

相关文章

求二分图的最大匹配(匈牙利算法)

861. 二分图的最大匹配 - AcWing题库 AC代码&#xff1a; #include <iostream> #include <cstring> #include <algorithm>using namespace std;const int N 510,M 100010; int n1,n2,m; int h[N],e[M],ne[M],idx; int match[N]; bool st[N];void add(int…

tailwind使用教程以及tailwind不生效的问题

以Vite项目为例 我们先安装依赖文件 生成文件 yarn add -D tailwindcss postcss autoprefixer npx tailwindcss init -p配置tailwind.config.js文件 /** type {import(tailwindcss).Config} */ export default {content: ["./index.html","./src/**/*.{vue,j…

学信息系统项目管理师第4版系列12_合同管理

1. 项目范围划分 1.1. 项目总承包合同 1.1.1. 总承包合同要求只与同一个卖方订立承包合同 1.1.2. 不意味着只订立一个总合同 1.2. 项目单项承包合同 1.2.1. 买方分别与不同的卖方订立项目单项承包合同 1.3. 项目分包合同 1.3.1. 满足5个条件 1.3.1.1. ①经过买方认可 …

酒店预订小程序制作详细步骤解析

" 随着移动设备的普及和互联网技术的不断发展&#xff0c;小程序成为了一个备受关注的应用领域。特别是在酒店预订行业&#xff0c;小程序可以为酒店带来更多的客源和方便快捷的预订服务。下面是酒店预订小程序的制作详细步骤解析。 第一步&#xff1a;注册登录【乔拓云】…

C++图像金字塔下采样的函数

图像金字塔下采样的函数 cv::pyrDown 是 OpenCV 中用于图像金字塔下采样的函数。图像金字塔是一种多分辨率图像表示方法&#xff0c;它通过逐级下采样&#xff08;减小图像尺寸&#xff09;和上采样&#xff08;增加图像尺寸&#xff09;来生成一系列不同分辨率的图像。cv::py…

MySQL - 全表分组后,获取组内排序首条数据信息

性能 不详!!! 不详!!! 不详!!! 请谨慎使用!!!环境 MySQL服务: 8.0版本;思路 使用8.0版本的新函数特性: row_number(): 序号函数; 顾名思义, 就是给每组中的元素从1开始按顺序加上序号;over(): 其中两个语法如下 partition: 按某字段分组;order by: 按某字段排序;注意: 两函数详…

【2023年11月第四版教材】第15章《风险管理》(第四部分)

第15章《风险管理》&#xff08;第四部分&#xff09; 8 过程4-实施定量风险分析8.1 实施定量风险分析★★★8.2 数据分析★★★8.3 定量成本风险分析S曲线示例8.4 决策树示例8.5 龙卷风图示例8.6 项目文件&#xff08;更新&#xff09;★★★ 9 过程5-规划风险应对9.1 规划风险…

YOLOv5、YOLOv8改进:ConvNeXt(backbone改为ConvNextBlock)

目录 1.介绍 2. YOLOv5修改backbone为ConvNeXt 2.1修改common.py 2.2 修改yolo.py 2.3修改yolov5.yaml配置 1.介绍 论文地址&#xff1a;https://arxiv.org/abs/2201.03545官方源代码地址&#xff1a;https://github.com/facebookresearch/ConvNeXt.git 自从ViT(Vision T…