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

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

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

1. props 实现(复习)

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


在父组件 App.vue 中定义 getSchoolName() 用来接收从子组件传过来的值。

在子组件 School.vue 中定义 props: ['getSchoolName'] ,接收父组件给子组件传递函数。

在子组件 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>

26b69331cecf4924b82a40cebbdd61e3.png

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

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


在父组件 App.vue 中自定义事件 @atguigu 绑定到 Student 组件上。

在子组件 Student.vue 中通过 this.$emit("atguigu", xxx) 触发该事件。

可以传参,在 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>

8a3404b7bc144ab5abf21884a63b4093.png

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

ref | 参考链接

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


在 Student 标签中通过 ref = student 给组件注册引用信息(相当于 id 的替代者)。

在钩子函数中,通过 this.$refs.student.$on('atguigu', xxx) 绑定自定义事件。(ref 打标识,$refs 获取)

vm.$on(event, callback) 用于监听当前实例上的自定义事件,事件可以由 vm.$emit 触发。

如果把 $on 改成 $once 则只触发一次。

可以给添加 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); //绑定自定义事件(一次性)
    },
  };

67da4cf6adc54bb5960d4a32e99fb552.png

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

8e64e3633f81471e84de0648532f53fa.png

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

77220db944dc48eb911ba4a7775a0541.png

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

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 指向会出问题。

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

相关文章
|
10天前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
vue学习第四章
|
10天前
|
JavaScript 前端开发
vue学习第九章(v-model)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生,自学前端2年半,正向全栈进发。此篇介绍v-model在不同表单元素中的应用及修饰符的使用,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
vue学习第九章(v-model)
|
10天前
|
JavaScript 前端开发 开发者
vue学习第十章(组件开发)
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文深入讲解Vue组件的基本使用、全局与局部组件、父子组件通信及数据传递等内容,适合前端开发者学习参考。持续更新中,期待您的关注!🎉🎉🎉
vue学习第十章(组件开发)
|
3天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
18 8
|
3天前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
15天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
存储 前端开发 JavaScript
为什么我不再用Vue,改用React?
当我走进现代前端开发行业的时候,我做了一个每位开发人员都要做的决策:选择一个合适的框架。当时正逢 jQuery 被淘汰,前端开发者们不再用它编写难看的、非结构化的老式 JavaScript 程序了。
|
16天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
16天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
16天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。