Vue —— 进阶脚手架(四)(组件的自定义事件)


一、组件自定义事件_绑定

1. props 实现(复习)

通过父组件给子组件传递函数类型的 props 实现:子给父传递数据

  1. 在父组件 App.vue 中定义 getSchoolName() 用来接收从子组件传过来的值。
  2. 在子组件 School.vue 中定义 props: ['getSchoolName'] ,接收父组件给子组件传递函数。
  3. 在子组件 School.vue 的 methods 方法中把值传给父组件。

School.vue

	<template>
	  <div class="demo2">
	    <h2>学校名称:{
    
    {
    
     name }}</h2>
	    <h2>学校地址:{
    
    {
    
     address }}</h2>
	    <button @click="sendSchoolName">把学校名给App</button>
	  </div>
	</template>
	
	<script>
	export default {
    
    
	  name: "SchoolName",
	  props: ["getSchoolName"],
	  data() {
    
    
	    return {
    
    
	      name: "哔哩哔哩",
	      address: "中国",
	    };
	  },
	  methods: {
    
    
	    sendSchoolName() {
    
    
	      this.getSchoolName(this.name);
	    },
	  },
	};
	</script>

App.vue

	<template>
	  <div class="demo">
	    <h3>{
    
    {
    
     msg }}</h3>
	    <!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 -->
	    <School :getSchoolName="getSchoolName" />
	  </div>
	</template>
	
	<script>
	// 引入组件
	import School from "./components/School.vue";
	import Student from "./components/Student.vue";
	export default {
    
    
	  name: "App",
	  components: {
    
     School, Student },
	  data() {
    
    
	    return {
    
    
	      msg: "你好",
	    };
	  },
	  methods: {
    
    
	    getSchoolName(name) {
    
    
	      console.log("App收到了学校名:", name);
	    }
	  }
	};
	</script>

在这里插入图片描述

2. 自定义事件实现(使用 @)

通过父组件给子组件绑定一个自定义事件实现:子给父传递数据 (使用@)

  1. 在父组件 App.vue 中自定义事件 @atguigu 绑定到 Student 组件上。
  2. 在子组件 Student.vue 中通过 this.$emit("atguigu", xxx) 触发该事件。
  3. 可以传参,在 App 组件中可以以形参的方式(...params)接收并输出。

Student.vue

	<template>
	  <div class="demo1">
	    <h2>学生姓名:{
    
    {
    
     name }}</h2>
	    <h2>学生性别:{
    
    {
    
     sex }}</h2>
	    <button @click="sendStudentName">把学生名给App</button>
	  </div>
	</template>
	
	<script>
	export default {
    
    
	  name: "StudentName",
	  data() {
    
    
	    return {
    
    
	      name: "张三",
	      sex: "男",
	    };
	  },
	  methods: {
    
    
	    sendStudentName() {
    
    
	      // 触发Student组件实例上的atguigu事件
	      this.$emit("atguigu", this.name, 666);
	    },
	  },
	};
	</script>

App.vue

	<template>
	  <div class="demo">
	    <h3>{
    
    {
    
     msg }}</h3>
	    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据 (第一种写法:使用@)-->
	    <Student @atguigu="getStudentName"/>
	</template>
	
	<script>
	import School from "./components/School.vue";
	import Student from "./components/Student.vue";
	export default {
    
    
	  name: "App",
	  components: {
    
     School, Student },
	  data() {
    
    
	    return {
    
    
	      msg: "你好",
	    };
	  },
	  methods: {
    
    
	    getStudentName(name, ...params) {
    
    
	      console.log("App收到了学生名:", name, params);
	    }
	  }
	};
	</script>

在这里插入图片描述

3. 自定义事件实现(使用 ref)

ref | 参考链接

通过父组件给子组件绑定一个自定义事件实现:子给父传递数据 (使用ref)

  1. Student 标签中通过 ref = student 给组件注册引用信息(相当于 id 的替代者)。
  2. 在钩子函数中,通过 this.$refs.student.$on('atguigu', xxx) 绑定自定义事件。(ref 打标识,$refs 获取)
  3. vm.$on(event, callback) 用于监听当前实例上的自定义事件,事件可以由 vm.$emit 触发。
  4. 如果把 $on 改成 $once 则只触发一次。
  5. 可以给添加 setTimeout() 执行异步任务。

Student.vue 不变

App.vue

	<template>
	  <div class="demo">
	    <h3>{
    
    {
    
     msg }}</h3>
	    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据 (第二种写法:使用ref)-->
	    <Student ref="student" /> 
	  </div>
	</template>
	
	<script>
	import School from "./components/School.vue";
	import Student from "./components/Student.vue";
	export default {
    
    
	  name: "App",
	  components: {
    
     School, Student },
	  data() {
    
    
	    return {
    
    
	      msg: "你好",
	    };
	  },
	  methods: {
    
    
	    getStudentName(name){
    
    
	        console.log('App收到了学生名:', name);
	    }
	  },
	  mounted() {
    
    
	    this.$refs.student.$on("atguigu", this.getStudentName); //绑定自定义事件
	    // this.$refs.student.$once("atguigu", this.getStudentName); //绑定自定义事件(一次性)
	  },
	};

在这里插入图片描述

3s 后触发绑定的自定义事件(三秒之后点击才会输出内容)

	setTimeout(() => {
    
    
		this.$refs.student.$on('atguigu', this.getStudentName)
	}, 3000)

二、组件自定义事件_解绑

1. 解绑一个 / 多个自定义事件

语法:this.$off('xxx')

语法: this.$off(['xxx', 'xx'])

	<template>
	  <div class="demo1">
	    <h2>学生姓名:{
    
    {
    
     name }}</h2>
	    <h2>学生性别:{
    
    {
    
     sex }}</h2>
	    <button @click="sendStudentName">把学生名给App</button>
	    <button @click="unbind">解绑atguigu事件</button>
	  </div>
	</template>
	
	<script>
	export default {
    
    
	  name: "StudentName",
	  data() {
    
    
	    return {
    
    
	      name: "张三",
	      sex: "男",
	    };
	  },
	  methods: {
    
    
	    sendStudentName(){
    
    
	        this.$emit('atguigu', this.name) 
	    },
	    unbind(){
    
    
	        this.$off('atguigu') //解绑一个自定义事件
	        this.$off(['atguigu','demo']) //解绑多个自定义事件
	    }
	  }
	};
	<template>
	  <div class="demo">
	    <h3>{
    
    {
    
     msg }}</h3>
	    <Student @atguigu="getStudentName" @demo="m1" />
	  </div>
	</template>
	
	<script>
	// 引入组件
	import School from "./components/School.vue";
	import Student from "./components/Student.vue";
	export default {
    
    
	  name: "App",
	  components: {
    
     School, Student },
	  data() {
    
    
	    return {
    
    
	      msg: "你好",
	    };
	  },
	  methods: {
    
    
	    getStudentName(name) {
    
    
	      console.log("App接收到了学生名:", name);
	    },
	    m1() {
    
    
	      console.log("demo事件被触发了");
	    },
	  }
	};
	</script>

点击把学生名给 App

在这里插入图片描述

点击解绑 atguigu 事件后再点击把学生名给 App

在这里插入图片描述

三、总结 — 组件的自定义事件

1. 组件自定义事件是什么?

一种组件间通信的方式,适用于:子组件 => 父组件

2. 使用场景

A 是父组件,B 是子组件,B 想给 A 穿数据,那么就要在 A 中给 B 绑定自定义事件(事件的回调在 A 中)。

3. 绑定自定义事件(两种方式)
  1. 第一种方式,在父组件中
	<Demo @atguigu="test" />
	//或者
	<Demo v-on:atguigu="test" />
  1. 第二种方式,在父组件中
	<Demo ref="demo" />
	...
	mounted() {
    
    
		this.$refs.demo.$on("atguigu", this.test)
	}

若想让自定义事件只能触发一次,可以使用 once 修饰符,或 $once 方法

4. 触发自定义事件
	this.$emit('atguigu', 数据)
5. 解绑自定义事件
	this.$off('atguigu') //解绑一个自定义事件
	this.$off(['atguigu', 'demo']) //解绑多个自定义事件
6. 如何在组件上绑定原生的DOM事件

组件上也可以绑定原生DOM事件,需要使用 native 修饰符
如果不加 native 则会被认为是自定义事件

	<Demo @click.native='test' />
7. 注意事项

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

不积跬步无以至千里 不积小流无以成江海

猜你喜欢

转载自blog.csdn.net/qq_45902692/article/details/124783632
今日推荐