前端vue入门(纯代码)09

09.vue中组件的自定义事件

自定义组件链接

  • 在vue中用的click【点击】、keyup【按键】……等事件,这些属于内置事件,也就是js自带的事件。

问题一:什么是组件自定义事件呢?

  • 【内置事件】:是给html元素用的,比如span、div等标签,不是组件。
  • 【自定义事件】:顾名思义就是自己打造的事件,包含事件名,事件回调函数等,定义好之后去给组件使用。也是一种组件间的通信方式,适用于子组件==>父组件。这里我们通过传值去讲述自定义事件如何使用。

问题二:如何实现子组件给父组件传值?

(1)利用props传值实现

通过props也可以实现,先定义父子组件,school是父组件,student是子组件。

School.vue父组件

  • props传值:父组件需要提前给子组件一个函数【getStudentName】,子组件用props声明接收那个函数【getStudentName】

  • 注意:使用props属性时,需要使用冒号来区别传入的是双引号里面的内容还是字符串,这里我们传的是一个函数,因此需要用冒号去识别函数名

  • 具体写法对应是:

     <Student :子组件发送数据时调用的方法名="父组件接收数据的方法名"> </Student>
     <Student :getStudentName="getStudentName"/>
    
<template>
	<div class="school">
    <h1>父组件:School</h1>
    <Student :getStudentName="getStudentName"/>
    <h1>子组件Student传过来的值:{{ StudentName }}</h1>
	</div>
</template>

<script>
import Student from './Student';
export default {
	name: 'School',
    components: {Student},
	data() {
		return {
           StudentName:'',
		};
	},
	methods: {
    getStudentName(name){
      console.log('School收到了学生名:',name)
      this.StudentName= name
    }
  },
};
</script>

<style scoped>
.school {
	background-color: rgb(73, 192, 150);
}
</style>

Student.vue子组件

  • 首先需要用props声明接收父组件传的函数【getStudentName】。然后给按钮添加点击事件,通过点击来触发点击事件,从而调用sendStudentlName(name)方法【带参数:子组件中的参数name: '何大春'】,在该方法中调用已经声明过的父组件中的函数getStudentName(Studentname),并传入你要传递的数据参数,这就已经实现子组件向父组件传参,最后将该参数在父组件的模板中展示出来即可。

  • props子组件给父组件传递数据的过程就是:

    • 子组件通过调用父组件传过来接收子组件数据的方法,来实现子组件数据向父组件的传递。
<template>
	<div class="student">
    <h1>子组件信息</h1>
		<h2>学生姓名:{{ name }}</h2>
		<h2>学生性别:{{ sex }}</h2>
		<h2>学生年龄:{{ age }}</h2>
		<h2>学生成绩:{{ score }}</h2>
    <!-- 点击事件触发,调用函数sendStudentlName(name),并给该函数传一个data里面的参数name -->
		<button class="haha" @click="sendStudentlName(name)"><h2>点击此处给父组件School传值</h2></button>
	</div>
</template>

<script>
export default {
	name: 'Student',
  props:['getStudentName'],
	data() {
		return {
			name: '何大春',
			sex: '男',
			age: '22',
			score: '88',
		};
	},
	methods: {
    // 这里的Studentname就是name,别搞混了,我随便命名的
		sendStudentlName(Studentname) {
         // 调用父组件中的函数,并把子组件中的参数name传给父组件
         this.getStudentName(Studentname)
    },
	},
};
</script>

<style lang="less" scoped>
.student {
	background-color: tomato;
	padding: 50px;
	margin-top: 50px;
	margin-left: 50px;
	width: 300px;
	height: 350px;
}
.h2 {
  padding: 5px;
  margin: 5px 5px 5px 5px;
}
.haha {
  background-color: rgb(211, 233, 130);
}
</style>

App.vue组件

<template>
  <div> 
    <School/>
  </div>
</template>

<script>
import School from "./components/School";
export default {
	name: 'App',
  components: {School},
	data() {
		return {};
	},
};
</script>

界面展示:

在这里插入图片描述

在这里插入图片描述

(2)利用组件自定义事件实现父子传值

组件自定义事件需要用到v-on,也就是v-on在谁身上,就是在谁的组件实例上绑定了事件。

  • ①在父组件School中给子组件Student绑定一个自定义事件getName

    <!-- 给子组件的实例对象VC绑定了事件getName,该事件触发会调用函数getStudentName -->
        <Student v-on:getName="getStudentName"/>
    
  • ②如何触发自定义事件getName:在谁身上定义的就找谁触发,所以,我们需要找子组件的实例对象VC触发

    • 在子组件Student的实例对象上去,触自定义事件getNamethis.$emit('getName',参数1,...,参数n)
  • 子组件传入参数。不传参数就是单纯的触发父组件对应的函数。

    sendStudentlName() {
          // 触发自定义事件getName,并把子组件中的参数name传给父组件
          this.$emit('getName',this.name,this.age,this.score)
        },
    
  • 父组件接收子组件的参数

    	methods: {
    /*     getStudentName(name,age,score){
          console.log('School收到了学生名:',name,age,score)
          this.StudentName= name
        } */
        // 可以传多个参数【...params】
        getStudentName(name,...params){
          console.log('School收到了学生名:',name,params)
          // School收到了学生名: 何大春 (2) ['22', '88']
          this.StudentName= name
          this.StudentAge = params[0]
        }
      },
    

完整代码:

School.vue父组件【样式不变,还是上面的样式】

<template>
	<div class="school">
    <h1>父组件:School</h1>
    <!-- 给子组件的实例对象VC绑定了事件getName,该事件触发会调用函数getStudentName -->
    <Student v-on:getName="getStudentName"/>
    <h1>子组件Student传过来的name:{{ StudentName }}</h1>
    <h1>子组件Student传过来的age:{{ StudentAge }}</h1>
	</div>
</template>

<script>
import Student from './Student';
export default {
	name: 'School',
  components: {Student},
	data() {
		return {
      StudentName:'',
      StudentAge:'',
		};
	},
	methods: {
/*     getStudentName(name,age,score){
      console.log('School收到了学生名:',name,age,score)
      this.StudentName= name
    } */
    // 可以传多个参数【...params】
    getStudentName(name,...params){
      console.log('School收到了学生名:',name,params)
      // School收到了学生名: 何大春 (2) ['22', '88']
      this.StudentName= name
      this.StudentAge = params[0]
    }
  },
};
</script>

Student.vue子组件

<template>
	<div class="student">
    <h1>子组件信息</h1>
		<h2>学生姓名:{{ name }}</h2>
		<h2>学生性别:{{ sex }}</h2>
		<h2>学生年龄:{{ age }}</h2>
		<h2>学生成绩:{{ score }}</h2>
    <!-- 点击事件触发,调用函数sendStudentlName(name),并给该函数传一个data里面的参数name -->
	<!-- <button class="haha" @click="sendStudentlName(name)">
     <h2>点击此处给父组件School传值</h2></button> -->
		<button class="haha" @click="sendStudentlName()">
      <h2>点击此处给父组件School传值</h2></button>
	</div>
</template>

<script>
export default {
	name: 'Student',
	data() {
		return {
			name: '何大春',
			sex: '男',
			age: '22',
			score: '88',
		};
	},
	methods: {
    // 这里的Studentname就是name,别搞混了,我随便命名的
/*     sendStudentlName(Studentname) {
      // 触发自定义事件getName,并把子组件中的参数name传给父组件
      this.$emit('getName',Studentname)
    }, */
		sendStudentlName() {
      // 触发自定义事件getName,并把子组件中的参数name传给父组件
      this.$emit('getName',this.name,this.age,this.score)
    },
	},
};
</script>
  • 【简写】:v-on的简写形式就是@

(3)利用ref实现父子传值

ref相当于一个组件的标识,可以直接拿到该组件的实例对象。

  • ref 加在子组件上,用this.$refs.(ref值) 获取到的是组件实例vc,可以使用组件的所有方法和属性。

        <Student ref="studentRef"/>
    
  • 如何通过ref去绑定自定义事件:通过**$on**

    // 当父组School件挂载完毕时,通过$on去绑定自定义事件,以及调用的函数。
      mounted() {   
       this.$refs.studentRef.$on('getName',this.getStudentName)
          
        // 自定义事件只触发一次
        // this.$refs.studentRef.$once('getName',this.getStudentName)
      },
    
  • 好处是:虽然麻烦但灵活性强,比如我们想3秒之后再调用这个事件我们可以直接添加一个定时器:

    // 3s之前,不会触发;3秒钟过后,才能触发该自定义事件
        setTimeout(() => {
          this.$refs.studentRef.$on('getName',this.getStudentName)
        }, 3000); 
    

只想触发一次函数,怎么办?

  • 第一种ref形式,将$on,改为$once

        // 自定义事件只触发一次
        this.$refs.studentRef.$once('getName',this.getStudentName)
    
  • 第二种 自定义事件的,添加once修饰符

    <Student v-on:getName.once="getStudentName"/>
    <!-- <Student @getName.once="getStudentName"/> -->
    

完整代码:

School.vue父组件【样式不变,还是上面的样式】

<template>
	<div class="school">
    <h1>父组件:School</h1>
    <!-- <Student v-on:getName.once="getStudentName"/> -->
    <!-- <Student @getName.once="getStudentName"/> -->
    <Student ref="studentRef"/>
    <h1>子组件Student传过来的name:{{ StudentName }}</h1>
    <h1>子组件Student传过来的age:{{ StudentAge }}</h1>
	</div>
</template>

<script>
import Student from './Student';
export default {
	name: 'School',
  components: {Student},
	data() {
		return {
      StudentName:'',
      StudentAge:'',
		};
	},
	methods: {
/*     getStudentName(name,age,score){
      console.log('School收到了学生名:',name,age,score)
      this.StudentName= name
    } */
    // 可以传多个参数【...params】
    getStudentName(name,...params){
      console.log('School收到了学生名:',name,params)
      // School收到了学生名: 何大春 (2) ['22', '88']
      this.StudentName= name
      this.StudentAge = params[0]
    }
  },
  // 当父组件挂载完毕时,通过$on去绑定自定义事件,以及调用的函数。
  mounted() {
    // 3s之前,不会触发;3秒钟过后,才能触发该自定义事件
    /* setTimeout(() => {
      this.$refs.studentRef.$on('getName',this.getStudentName)
    }, 3000); */
    this.$refs.studentRef.$on('getName',this.getStudentName)
    // 事件只触发一次
    // this.$refs.studentRef.$once('getName',this.getStudentName)
  },
};
</script>

Student.vue子组件

<template>
	<div class="student">
    <h1>子组件信息</h1>
		<h2>学生姓名:{{ name }}</h2>
		<h2>学生性别:{{ sex }}</h2>
		<h2>学生年龄:{{ age }}</h2>
		<h2>学生成绩:{{ score }}</h2>
    <!-- 点击事件触发,调用函数sendStudentlName(name),并给该函数传一个data里面的参数name -->
		<!-- <button class="haha" @click="sendStudentlName(name)"><h2>点击此处给父组件School传值</h2></button> -->
		<button class="haha" @click="sendStudentlName()">
      <h2>点击此处给父组件School传值</h2></button>
	</div>
</template>

<script>
export default {
	name: 'Student',
	data() {
		return {
			name: '何大春',
			sex: '男',
			age: '22',
			score: '88',
		};
	},
	methods: {
    // 这里的Studentname就是name,别搞混了,我随便命名的
/*     sendStudentlName(Studentname) {
      // 触发自定义事件getName,并把子组件中的参数name传给父组件
      this.$emit('getName',Studentname)
    }, */
		sendStudentlName() {
      // 触发自定义事件getName,并把子组件中的参数name传给父组件
      this.$emit('getName',this.name,this.age,this.score)
    },
	},
};
</script>
总结:
  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件

  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

  3. 绑定自定义事件:

    • 第一种方式,在父组件中:<Demo @getName="test"/><Demo v-on:getName="test"/>

    • 第二种方式,在父组件中:

    <Demo ref="demo"/>
    ......
    mounted(){
       this.$refs.xxx.$on('getName',this.test)
    }
    
    • 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。
  4. 触发自定义事件:this.$emit('getName',数据)

  5. 解绑自定义事件this.$off('getName')

  6. 组件上也可以绑定原生DOM事件,需要使用native修饰符。

  7. 注意:通过this.$refs.xxx.$on('getName',回调函数)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!

   <Demo ref="demo"/>
   ......
   mounted(){
      this.$refs.xxx.$on('getName',this.test)
   }
  • 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。
  1. 触发自定义事件:this.$emit('getName',数据)

  2. 解绑自定义事件this.$off('getName')

  3. 组件上也可以绑定原生DOM事件,需要使用native修饰符。

  4. 注意:通过this.$refs.xxx.$on('getName',回调函数)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/29638.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

014、数据库管理之配置管理

配置管理 TiDB配置系统配置集群配置配置的存储位置区分TiDB的系统参数和集群参数 系统参数系统参数的作用域系统参数的修改 集群参数集群参数的修改配置参数的查看 实验一&#xff1a; 在不同作用域下对数据库的系统参数进行修改session级别global级别 实验二&#xff1a; 修改…

【TCP/IP】多进程服务器的实现(进阶) - 信号处理及signal、sigaction函数

目录 信号 signal函数 sigaction函数 用信号来处理僵尸进程 在之前我们学习了如何处理“僵尸进程”&#xff0c;不过可能也会有疑问&#xff1a;调用wait和waitpid函数时我们关注的始终是在子进程上&#xff0c;那么在父进程上如何实现对子进程的管控呢&#xff1f;为此&am…

零基础速成simulink代码生成——简单滤波器实现2

simulink setting 找到model settings solver求解器配置 Code Generation 代码生成配置 生成代码报告 添加stateflow注释 可以将变量保存在定义的文件(选) 实践 简单一阶滤波器

使用一键安装工具快速搭建 ESP-IDF 开发环境 (Windows)

我们收到用户对 ESP-IDF SDK 软件开发环境感到搭建难、门槛高的反馈。为解决用户在此方面的问题。为此&#xff0c;我们推出本期教程介绍在 Windows 操作系统下使用一键安装工具快速搭建 ESP-IDF 开发环境。 您可以观看下面的教程视频&#xff0c;也可以阅读接下来本篇的图文教…

CVPR 2023 | 图像超分,结合扩散模型/GAN/部署优化,low-level任务,视觉AIGC系列

1、Activating More Pixels in Image Super-Resolution Transformer 基于Transformer的方法在低级别视觉任务中&#xff0c;如图像超分辨率&#xff0c;表现出了令人印象深刻的性能。Transformer的潜力在现有网络中仍未得到充分发挥。为了激活更多的输入像素以实现更好的重建&a…

有哪些工具软件一旦用了就离不开?

&#x1f496;前言 目前&#xff0c;随着科技的快速发展&#xff0c;电脑已经进入了许许多多人的生活 &#xff0c;在平日的学习、工作和生活里&#xff0c;我们会用的各种各样的强大软件。市面上除了某些大公司开发在强大软件&#xff0c;还有各路大神开发具有某些功能的强大…

Java阶段四Day01

Java阶段四Day01 文章目录 Java阶段四Day01Security框架通配符Vue脚手架 Vue-cli关于VUE关于VUE Cli创建Vue Cli工程解决端口被占用 Vue工程的工程结构[.idea]【重要】[node_modules]【重要】[public]favicon.icoindex.html [src][assets][compnents]【重要】[router][store]【…

Spring基础知识(二)

目录 1.Spring Bean是什么 2.Spring提供的配置方式 3.Spring bean中的scope 4.Spring bean容器的生命周期 5.Spring的内部bean 6.Spring装配是什么 7.自动装配模式 8.自动装配的局限性 9.基于注解配置容器 10.如何启动注解装配 1.Spring Bean是什么 Spring官方文档对…

客户端负载均衡工具Ribbon

一 什么是Ribbon Ribbon介绍 目前主流的负载方案分为以下两种&#xff1a; 集中式负载均衡&#xff0c;在消费者和服务提供方中间使用独立的代理方式进行负载&#xff0c;有硬件的&#xff08;比如 F5&#xff09;&#xff0c;也有软件的&#xff08;比如 Nginx&#xff09;…

10大白帽黑客专用的 Linux 操作系统

平时在影视里见到的黑客都是一顿操作猛如虎&#xff0c;到底他们用的都是啥系统呢&#xff1f; 今天给大家分享十个白帽黑客专用的Linux操作系统。 ▍1. Kali Linux Kali Linux是最著名的Linux发行版&#xff0c;用于道德黑客和渗透测试。Kali Linux由Offensive Security开发&…

哨兵架构redisCluster-Redis(五)

上篇文章介绍了主从架构以及lua脚本。 主从架构&lua脚本-Redis&#xff08;四&#xff09;https://blog.csdn.net/ke1ying/article/details/131159229 Sentinel集群 主从的搭建我们已经完成&#xff0c;但如果主节点宕机&#xff0c;这时候导致整个redis服务不可用怎么办…

打造智能生活方式

2个互联网工具与你分享 分享一&#xff1a; 随记单词是一款功能强大的单词记忆和管理应用程序。它为用户提供了便捷的学习工具和智能化的记忆方式&#xff0c;帮助用户轻松有效地记忆和掌握单词。 随记单词的特点之一是个性化记忆计划。用户可以根据自己的学习进度和需求&am…

【LeetCode热题100】打卡第21天:最小路径和爬楼梯

文章目录 【LeetCode热题100】打卡第21天&#xff1a;最小路径和&爬楼梯⛅前言 最小路径和&#x1f512;题目 爬楼梯&#x1f512;题目&#x1f511;题解 【LeetCode热题100】打卡第21天&#xff1a;最小路径和&爬楼梯 ⛅前言 大家好&#xff0c;我是知识汲取者&#…

牛客网基础语法41~50题

牛客网基础语法41~50题&#x1f618;&#x1f618;&#x1f618; &#x1f4ab;前言&#xff1a;今天是咱们第五期刷牛客网上的题目。 &#x1f4ab;目标&#xff1a;熟练用数学知识来解决编程问题&#xff0c;会利用每种循环。 &#x1f4ab;鸡汤&#xff1a;压抑了&#xff0…

什么是远程工具,远程工具推荐

在当今数字化时代&#xff0c;远程工作正在变得越来越普遍。这种趋势不仅使企业管理更加便利&#xff0c;节省了时间和资源&#xff0c;同时也使员工更加自由和灵活。许多远程工作都需要使用到远程工具。本文将对远程工具进行简介和阐述。 什么是远程工具 远程工具是一种数字…

互斥锁实现线程互斥(嵌入式学习)

互斥锁实现线程互斥 互斥锁的概念互斥锁的函数示例代码 互斥锁的概念 互斥锁&#xff08;Mutex&#xff09;是一种用于多线程编程的同步原语&#xff08;synchronization primitive&#xff09;&#xff0c;用于实现线程之间的互斥访问共享资源。互斥锁提供了一种机制&#xff…

wsl安装ubuntu并设置gnome图形界面详细步骤(win11+ubuntu18)

0.前言 wsl确实是个好东西&#xff0c;不过之前配了好几次都没有成功&#xff0c;因为wsl本身确实是有bug。当时配的时候查到GitHub上的一个issue还没被修好。现在重新配一下。 我的环境是Windows11家庭版。区别于win10&#xff0c;win11安装完默认就是wsl2。 1.下载 首先打…

[RPC]:Feign远程调用

文章目录 摘要1 RPC框架-Feign1.1 什么是Feign1.2 Feign解决的问题1.2.1 使用RestTemplate发送远程调用代码1.2.1.1 项目示例调用链路1.2.1.2 代码逻辑1.2.1.3 代码实现1.2.1.4 存在的问题 1.3 Feign如何使用1.3.1 使用逻辑1.3.2 引入依赖1.3.3 启动类添加注释开启feign功能 摘…

3.数据操作

SQL句子中语法格式提示&#xff1a; 1.中括号&#xff08;[]&#xff09;中的内容为可选项&#xff1b; 2.[&#xff0c;...]表示&#xff0c;前面的内容可重复&#xff1b; 3.大括号&#xff08;{}&#xff09;和竖线&#xff08;|&#xff09;表示选择项&#xff0c;在选择…

网络安全|渗透测试入门学习,从零基础入门到精通—渗透中的开发语言

目录 前面的话 开发语言 1、html 解析 2、JavaScript 用法 3、JAVA 特性 4、PHP 作用 PHP 能做什么&#xff1f; 5、C/C 使用 如何学习 前面的话 关于在渗透中需要学习的语言第一点个人认为就是可以打一下HTML&#xff0c;JS那些基础知识&#xff0c;磨刀不误砍柴…