【Vue3从零开始-第三章】3-5 父子组件之间事件通信

简介: 【Vue3从零开始-第三章】3-5 父子组件之间事件通信

]UWOD(KIB9LJS9~S[T{QHM9.png


前言


上一篇的文章中,我们了解了vue组件Non-Props属性,今天我们继续深入了解一下vue组件中的父子组件之间通信


回顾


在前面的几篇文章中,我们知道组件之间传值的时候,可以通过父组件调用子组件标签,然后在子组件标签上用动态传参的方法传递给子组件,但是子组件没办法去修改父组件的值,因为子组件接收到的值是只读的。


<script>
  const app = Vue.createApp({
    data(){
      return {
        count: 1
      }
    },
    template: `
      <div>
        <counter :count="count" />
      </div>
    `
  });
  app.component('counter', {
    props: ['count'],
    methods: {
      handleClick(){
        this.count += 1
      }
    },
    template: `
      <div @click="handleClick">{{count}}</div>
    `
  })
  const vm = app.mount('#root');
</script>
复制代码


[Vue warn]: Attempting to mutate prop "count". Props are readonly.


今天的文章中我们将详细讲解一下父子组件如何通过事件方法进行通信。


$emit


  • $emit:子组件触发父组件事件的方法 当子组件中无法完成的一些事件操作时,可


  • 以通过$emit方法通知父组件去完成。下面我们就来改造一下上面的代码。


handleClick(){
    this.$emit('addOne')
}
复制代码


  • this.$emit():这个方法时一个固定的写法,也是vue提供的事件,意思就是我要向外部触发一个事件,传入事件名称即可。


既然子组件要通知父组件触发一个事件,那么父组件就得接收到子组件传递过来的事件。


const app = Vue.createApp({
    data(){
      return {
        count: 1
      }
    },
    methods: {
      handleAddOne(){
        this.count += 1
      }
    },
    template: `
      <div>
        <counter :count="count" @add-one="handleAddOne" />
      </div>
    `
  });
复制代码


  • 父组件中可以在子组件标签上通过v-on指令(简写@)接收子组件触发的事件。


  • 子组件触发事件是采用驼峰形式去写方法名,父组件接收的时候需要改成-接收方法名。


  • 父组件接收到子组件传递过来的方法之后,就可以触发父组件内部方法了


BOJL`I5}%N6H{QHS_V001IR.png


传参


通过上面的代码我们看到父子组件之间通过事件已经可以进行通信了,但是我们只是触发了事件而已,当我们需要在子组件里面传递参数要咋整呢?


  • 子组件触发的事件中,调用$emit方法时,除了定义方法名之外,后面还可以直接携带参数。


handleClick(){
    this.$emit('add', 2)
}
复制代码


  • 父组件触发的事件中,可以直接在方法中接收子组件传递过来的参数。


const app = Vue.createApp({
    data(){
      return {
        count: 1
      }
    },
    methods: {
      handleAddOne(param){
        this.count += param
      }
    },
    template: `
      <div>
        <counter :count="count" @add="handleAddOne" />
      </div>
    `
});
复制代码


B11N%AY4UGVH_LNK0J`(D6H.png


  • $emit方法后面携带的参数可以是多个。


// 子组件中的事件
handleClick(){
    this.$emit('add', 2, 3)
}
// 父组件中的事件
handleAddOne(param1, param2){
    this.count += param2
}
复制代码


B11N%AY4UGVH_LNK0J`(D6H.png


  • $emit方法后面携带的参数也可以直接进行计算。


// 子组件中的事件
handleClick(){
    this.$emit('add', this.count + 4)
}
// 父组件中的事件
handleAddOne(count){
    this.count = count
}
复制代码


(8~(~0IXOR7T6G06@F%]SEE.png


emits


  • emits:校验对外触发的方法名


app.component('counter', {
    props: ['count'],
    emits: ['add'],
    methods: {
      handleClick(){
        this.$emit('add', this.count + 4)
      }
    },
    template: `
      <div @click="handleClick">{{count}}</div>
    `
})
复制代码


在子组件中可以定义emits来校验$emit中的方法名,如果一致则可以触发成功。


emits: ['minus'],
复制代码


如果我们将子组件中的emits定义的值和$emit中的方法名不一致,则会在浏览器控制台中进行提示。


[Vue warn]: Component emitted event "add" but it is neither declared in the

emits option nor as an "onAdd" prop.


除了在emits中使用数组定义方法名之外,还可以通过对象的方式进行校验。


emits: {
    add: (count) => {
        if(count < 0){
          return true
        }
        return false
    }
},
复制代码


  • emits对象中可以监听$emit中的方法名,触发一个事件的时候可以获取到$emit中传递的参数值。


当监听对象中校验不通过时,也会在浏览器控制台中进行提示。


[Vue warn]: Invalid event arguments: event validation failed for event "add".


v-model


在以前的文章中,我们知道v-model指令是做双向数据绑定的,其实它也可以做父子组件通信的指令。


<script>
  const app = Vue.createApp({
    data(){
      return {
        count: 1
      }
    },
    template: `
      <div>
        <counter v-model="count" />
      </div>
    `
  });
  app.component('counter', {
    props: ['modelValue'],
    methods: {
      handleClick(){
        this.$emit('update:modelValue', this.modelValue + 5)
      }
    },
    template: `
      <div @click="handleClick">{{modelValue}}</div>
    `
  })
  const vm = app.mount('#root');
</script>
复制代码


  • 父组件中调用子组件标签时,可以直接使用v-model指令进行传值。


  • 子组件中通过props接收父组件中的参数modelValue


  • $emit方法中,直接通过update:modelValue的事件就可以对父组件的值进行修改了。


(8~(~0IXOR7T6G06@F%]SEE.png

modelValue是默认写法,不可以随意更改。


但是有些时候,我们需要自定义父组件传递给子组件的参数名称要怎么做呢?


<script>
  const app = Vue.createApp({
    data(){
      return {
        count: 1
      }
    },
    template: `
      <div>
        <counter v-model:count="count" />
      </div>
    `
  });
  app.component('counter', {
    props: ['count'],
    methods: {
      handleClick(){
        this.$emit('update:count', this.count + 6)
      }
    },
    template: `
      <div @click="handleClick">{{count}}</div>
    `
  })
  const vm = app.mount('#root');
</script>
复制代码


  • 直接在父组件中的子组件标签上使用v-model:xxx的方式进行自定义名称即可。


  • 子组件就接收自定义的名称进行渲染和操作。


(8~(~0IXOR7T6G06@F%]SEE.png

总结


本篇文章主要讲解了vue中的父子组件之间通过事件通信的方法:$emitv-model,也讲解了在进行通信时可以传递参数,也可以对传递的方法和参数进行校验。

相关文章
|
6天前
|
JavaScript 前端开发 UED
vue2和vue3的响应式原理有何不同?
大家好,我是V哥。本文详细对比了Vue 2与Vue 3的响应式原理:Vue 2基于`Object.defineProperty()`,适合小型项目但存在性能瓶颈;Vue 3采用`Proxy`,大幅优化初始化、更新性能及内存占用,更高效稳定。此外,我建议前端开发者关注鸿蒙趋势,2025年将是国产化替代关键期,推荐《鸿蒙 HarmonyOS 开发之路》卷1助你入行。老项目用Vue 2?不妨升级到Vue 3,提升用户体验!关注V哥爱编程,全栈开发轻松上手。
|
9天前
|
JavaScript 前端开发 算法
高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图
mermaid是一款非常优秀的基于 JavaScript 的图表绘制工具,可渲染 Markdown 启发的文本定义以动态创建和修改图表。非常适合新手学习或者做一些弱交互且自定义要求不高的图表 除了流程图以外,mermaid还支持序列图、类图、状态图、实体关系图等图表可供探索。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
9天前
|
JavaScript 前端开发 API
你真的会使用Vue3的onMounted钩子函数吗?Vue3中onMounted的用法详解
onMounted作为vue3中最常用的钩子函数之一,能够灵活、随心应手的使用是每个Vue开发者的必修课,同时根据其不同写法的特性,来选择最合适最有利于维护的写法。博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
9天前
|
JavaScript 前端开发 API
管理数据必备;侦听器watch用法详解,vue2与vue3中watch的变化与差异
一篇文章同时搞定Vue2和Vue3的侦听器,是不是很棒?不要忘了Vue3中多了一个可选项watchEffect噢。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
3月前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
177 1
|
19天前
|
JavaScript 前端开发 算法
vue渲染页面的原理
vue渲染页面的原理
94 56
|
9天前
|
数据采集 资源调度 JavaScript
极致的灵活度满足工程美学:用Vue Flow绘制一个完美流程图
本文介绍了使用 Vue Flow 绘制流程图的方法与技巧。Vue Flow 是一个灵活强大的工具,适合自定义复杂的流程图。文章从环境要求(Node.js v20+ 和 Vue 3.3+)、基础入门案例、自定义功能(节点与连线的定制、事件处理)到实际案例全面解析其用法。重点强调了 Vue Flow 的高度灵活性,虽然预定义内容较少,但提供了丰富的 API 支持深度定制。同时,文中还分享了关于句柄(handles)的使用方法,以及如何解决官网复杂案例无法运行的问题。最后通过对比 mermaid,总结 Vue Flow 更适合需要高度自定义和复杂需求的场景,并附带多个相关技术博客链接供进一步学习。
|
9天前
|
存储 数据采集 供应链
属性描述符初探——Vue实现数据劫持的基础
属性描述符还有很多内容可以挖掘,比如defineProperty与Proxy的区别,比如vue2与vue3实现数据劫持的方式有什么不同,实现效果有哪些差异等,这篇博文只是入门,以后有时间再深挖。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
1月前
|
移动开发 JavaScript API
Vue Router 核心原理
Vue Router 是 Vue.js 的官方路由管理器,用于实现单页面应用(SPA)的路由功能。其核心原理包括路由配置、监听浏览器事件和组件渲染等。通过定义路径与组件的映射关系,Vue Router 将用户访问的路径与对应的组件关联,支持哈希和历史模式监听 URL 变化,确保页面导航时正确渲染组件。
|
1月前
|
监控 JavaScript 前端开发
ry-vue-flowable-xg:震撼来袭!这款基于 Vue 和 Flowable 的企业级工程项目管理项目,你绝不能错过
基于 Vue 和 Flowable 的企业级工程项目管理平台,免费开源且高度定制化。它覆盖投标管理、进度控制、财务核算等全流程需求,提供流程设计、部署、监控和任务管理等功能,适用于企业办公、生产制造、金融服务等多个场景,助力企业提升效率与竞争力。
117 12