在Vue中当执行this.$emit() 时发生了什么?this.$emit() 的调用是异步的吗?

news/2024/7/10 1:17:28 标签: vue, javascript, html5, 大前端, 前端

当在Vue组件中调用this. e m i t ( ) 时 , 实 际 上 是 调 用 了 ‘ V u e . p r o t o t y p e . emit()时,实际上是调用了 `Vue. prototype. emit()Vue.prototype.emit` 方法。
下面我们来看看Vue.$emit方法的定义

Vue.$emit 的方法源码位于 Vue源码目录下的src/core/instance/event.js

javascript">Vue.prototype.$emit = function (event: string): Component {
    const vm: Component = this
    if (process.env.NODE_ENV !== 'production') {
      const lowerCaseEvent = event.toLowerCase()
      if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
        tip(``)
      }
    }
    let cbs = vm._events[event]
    if (cbs) {
      cbs = cbs.length > 1 ? toArray(cbs) : cbs
      const args = toArray(arguments, 1)
      const info = `event handler for "${event}"`
      for (let i = 0, l = cbs.length; i < l; i++) {
        invokeWithErrorHandling(cbs[i], vm, args, vm, info)
      }
    }
    return vm
  }

从源码中可以看出$emit的执行是同步的,当 $emit执行之后会去遍历注册的事件数组

也就是说 this.$emit 之后的代码会在 $emit执行完成之后执行

那了解这个机制有什么用呢?可以用在什么地方呢?

答案是

可以用于子组件与父组件之间的联动也就是便于子组件实时获取父组件的数据,这个数据可通过Prop传递。

假设子组件中的this.$emit 执行之后要进行网络请求,这个网络请求依赖于父组件的中某个可变的数据或者依赖于父组件几个数据经过一定运算后得出的结果,这个时候就非常有用了。

你可能会说,这种情况可以通过提前把关联的变量都传给子组件来解决。这样是可以解决问题但是不够灵活,当你一个页面有几十个组件联动都有类似的需求后,这种方式就会变得非常的麻烦且很难维护。也有同学可能会说既让几十个组件都有需求那就直接用inject注入的方式来复制就好了,这种方式也可以但是组件的复用会变得麻烦,因为你需要在每个用到子组件的地方都注入数据。

下面我们用一个例子来演示这种情况。

  • 首先定义一个子组件
<template>
    <div class="child-container">
        <div>我是子组件</div>
        <div>子组件获取父组件数据进行列表展示</div>
        <button @click="onSearch">获取父组件参数后进行数据更新</button>
        <ul>
            <li v-for="(item,key) in list" :key="key">Hello{{key}}</li>
        </ul>
    </div>
</template>
javascript"><script>
    export default {
        name: "EmitComponent",
        props:{
            searchParam:{
                type:Object,
                default:()=>{}
            }
        },
        data(){
            return{
                list:[]
            }
        },
        methods:{
            onSearch(){
                this.$emit('getParam')
                if(this.searchParam.value === 10){
                    for (let i = 0; i < 10; i++) {
                        this.list.push(i)
                    }
                }else{
                    this.list.push(1)
                }
            }
        }

    }
</script>

在子组件中通过发送getParam 参数来获取父组件中传递的值来决定页面的展示当同步且正确的获取时,会展示10项列表数据,当获取失败时只展示1个

下面是父组件中的代码:

<template>
    <div>
        <div>$emit function 同步测试</div>
        <EmitComponent
            :search-param="childParam"
            @getParam="getParam"
        ></EmitComponent>
    </div>
</template>
javascript"><script>
    import EmitComponent from './_component/EmitComponent'
    export default {
        name: "TestEmit",
        components:{EmitComponent},
        data(){
            return{
                childParam:{
                    value:1
                }
            }
        },
        methods:{
            getParam(){
                this.childParam.value = 10
            }
        }
    }
</script>

父组件的逻辑很简单就是改变传给子组件Prop的值来模拟子组件从父组件获取指定运算数据的情况。

来看一下演示结果:
在这里插入图片描述
结果与预期的一致。


http://www.niftyadmin.cn/n/1361564.html

相关文章

JavaScript运行环境判断

是否运行在浏览器 var inBrowser typeof window ! undefined;前置条件获取UserAgent var UA inBrowser && window.navigator.userAgent.toLowerCase();是否运行在IE浏览器 var isIE UA && /msie|trident/.test(UA);是否运行在ie9 var isIE9 UA &&am…

rollup.js 引用第三方库

第一步&#xff1a;安装 rollup-plugin-node-resolve 和 rollup-plugin-commonjs npm install --save rollup-plugin-node-resolve npm install --save rollup-plugin-commonjs 第二步&#xff1a;在 rollup.config.js 中 引入以上两个库并在plugins 中实例化&#xff0c;…

Java IO流(二)

File类字符流与字节流File 类 1.1 File 概述 打开API&#xff0c;搜索File类。阅读其描述&#xff1a;File文件和目录路径名的抽象表示形式。即&#xff0c;Java中把文件或者目录&#xff08;文件夹&#xff09;都封装成File对象。也就是说如果我们要去操作硬盘上的文件&#x…

入门级五星好书之《编码》【推荐】

《编码》是一本任何想进入编程领域的人都有必要看的一本书。巅峰之作&#xff0c;培育了几代软件开发设计人员。当你翻开这本书的时候&#xff0c;你一定会像看一本小说一样爱不释手。一本技术图书也能让你看得欲罢不能&#xff01;本书前一次出版时&#xff0c;近150人参与评论…

ABAP 给报表程序的 输入参数 添加文本

目录 设置前 第一步 第二步 设置后 示例代码 设置前 第一步 菜单栏定位 Goto -> Text Elements -> Selection Texts 第二步 Selection Texts 处输入对应文本 并激活 设置后 示例代码 REPORT ZREGEX. PARAMETERS field TYPE CHAR10.

ABAP 虚拟机使用记录

目录 启动SAP服务 第一步&#xff1a;切换到指定用户 第二步&#xff1a;开启所有服务 第三步: 检查所有进程是否启动成功 (状态显示为GREEN即为启动成功) 启动SAP服务 第一步&#xff1a;切换到指定用户 su -l npladm 第二步&#xff1a;开启所有服务 startsap ALL 第三步…

mongoDB-----针对某个或多个文档只需要部分更新可使用原子的更新修改器

update() db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document> } ) db.collection.update( criteria, objNew, upsert, multi ) 四个参数的说明如下&#xff1a; criteria: update的…

Android黑科技之微信语音助手-长辈关怀利器

前段时间在跟一个长辈交流过程中发现他不识字。但是能听懂普通话。虽然能正常使用微信进行语音聊天。但是文字认不出来&#xff0c;朋友圈也只能看图片。这无疑少了许多乐趣。而且通过进一步沟通了解到如果是工作日有什么事找子女咨询&#xff0c;因为在上班子女也不方便使用语…