ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue3 基础-父子组件间如何通过事件通信

2022-09-10 17:00:47  阅读:225  来源: 互联网

标签:count const methods app 父子 vue3 组件 emit


前几篇讨论的父子组件间如何进行传数据的话题. 即父组件在调用子组件的时候, 通过自定义属性 (v-bind) 的方式传递数据, 同时子组件通过 props 属性进行接收. 子组件可以对数据进行各种校验, 但不能修改, 即所谓的 "单项数据流''的概念, 这样其实是合理的, 不能混乱. 若是在要改就另存一份副本再进行操作即可.

本篇的学习是父子组件如何通过事件进行通信, 即子组件想要搞一个操作, 向父组件进行请示 (emit), 父组件同意后帮其在父组件的 methods 中进行回应.

子组件向父组件通信

<!DOCTYPE html>
<html lang="en">

<head>
  <title>组件事件通信 $emit</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      data () { return { count: 1 }},
      methods: {
        handleAddOne () {
          this.count += 1
        }
      },
      // 3. 父组件接收到信息并进行全局处理
      template: `
      <div>
        <Son :count=count @add-one="handleAddOne" />
      </div>
      `
    })

    app.component('Son', {
      props: ['count'],
      methods: {
        handleClick () {
          // 1. 当用户点击, 触发 handleClick 事件
          // 2. 然后其向父组件发射(请示) emit 一个名为 addOne 的事件 
          this.$emit('addOne')
        }
      },
      template: '<div @click="handleClick">{{count}}</div>'

    })
    
    const vm = app.mount('#root')

  </script>
</body>

</html>

以上例, 梳理组件事件传递的基础逻辑:

  • 在子组件中, 当用户点击, 触发 handleClick 事件
  • 然后其向父组件发射(请示) $emit 一个名为 addOne 的事件
  • 父组件在调用子组件的地方接收 add-one 事件 (注意子emit用驼峰, 父接收用短横) 能默认识别
  • 父组件在自己的 methods 中进行全局处理哦

补充一下这里的 $emit 是可以进行校验和传参的, 就校验举个栗子:

// 子组件首层
emit: {
      add: (count) => {
        if (count < 0) {
          return true;
        }
        return false; 
      }

传参也演示一下:

    const app = Vue.createApp({
      data () { return { count: 1 }},
      methods: {
        handleAdd (arg1, arg2) {
          this.count += 1
        }
      },
      // 3. 父组件接收到信息并进行全局处理
      template: `
      <div>
        <Son :count=count @add="handleAdd" />
      </div>
      `
    }

    app.component('Son', {
      props: ['count'],
      methods: {
        handleClick () { 
          this.$emit('add', 1, 2)
        }
      },
      template: '<div @click="handleClick">{{count}}</div>'

    })
    
    const vm = app.mount('#root')

modelValue 关键字

这种父组件向子组件传值, 子组件向父组件 emit 事件的过程, 岂不和 v-model 这个指令有异曲同工之妙嘛. 因此在约定俗成下, 我们能用 modelValue 这个关键字进行改写:

<!DOCTYPE html>
<html lang="en">

<head>
  <title>modelValue</title>
  <script src="https://unpkg.com/vue@3"></script>
</head>

<body>
  <div id="root"></div>
  <script>
    const app = Vue.createApp({
      data () { return { count: 1 } },
      // 1. 父组件通过 v-model 来监听 count 的变化
      template: `<Son v-model=count />`
    })

    app.component('Son', {
      props: ['modelValue'],
      methods: {
        handleClick () {
          // 监控数据变化
          this.$emit('update:modelValue', this.modelValue + 3)
        }
      },
      template: '<div @click="handleClick">{{modelValue}}</div>'

    })
    
    const vm = app.mount('#root')

  </script>
</body>

</html>

当然也是可以改名字的, 通过 v-model​:xxx 的写法:​

<script>
    const app = Vue.createApp({
      data () { return { count: 1 } },
      // 1. 父组件通过 v-model 来监听 count 的变化
      template: `<Son v-model:cj=count />`
    })

    app.component('Son', {
      props: ['cj'],
      methods: {
        handleClick () {
          this.$emit('update:cj', this.cj + 3)
        }
      },
      template: '<div @click="handleClick">{{cj}}</div>'

    })
    
    const vm = app.mount('#root')

  </script>

小结

最后再来对整个子组件向父组件 emit 事件的操作流程做一个小结

  • 在子组件中, 触发一个名为 nb 的时间
  • 然后其向父组件发射(请示) $emit 一个名为 nb 的事件
  • 父组件在调用子组件的地方接收 nb 事件
  • 父组件在自己的 methods 中进行全局处理哦
  • 可以用 v-model 的写法来进行简写这种父子通信的代码

标签:count,const,methods,app,父子,vue3,组件,emit
来源: https://www.cnblogs.com/chenjieyouge/p/16677855.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有