Vue2事件总线在第二次调用后工作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue2事件总线在第二次调用后工作相关的知识,希望对你有一定的参考价值。

我有一个嵌套组件,子组件应该从主实例接收一个参数,但问题是我必须调用事件两次获取参数。

的index.html

<div id="app">
    <button @click="displayComponent">Display</button><br/><hr/>
    {{ message }}

    <mycomponent v-if="showComponent" @hide="hideComponents"></mycomponent>
</div>

code.js

window.bus = new Vue();

Vue.component('mycomponent', {
    template: `
        <div>
            <h3>Im the parent component</h3>
            <childcomponent></childcomponent>
            <button @click="$emit('hide')">Hide components</button>
        </div>
    `
});

Vue.component('childcomponent', {
    template:`
        <div>
            <h4>Im the child component</h4>
            <p>{{ data }}</p>
        </div>
    `,

    data() {
        return {
            text: 'Nothing loaded'
        };
    },

    methods: {
        test() {
            alert('hello');
        },

        getData(x) {
            this.text = x;
        }
    },

    created(){
        bus.$on('extraCall', data => {
            this.getData(data);
            this.test();
        });
    }
});

const app = new Vue({
    el: '#app',

    data: {
        message: 'hello world!',
        showComponent: false
    },

    methods: {
        displayComponent() {        
            bus.$emit('extraCall', 'this is some extra text');
            this.showComponent = true;
        },

        hideComponents() {
            this.showComponent=false;
        }
    }
});

子组件元素中的文本值设置为默认值,在单击“显示”按钮后,它会使用bus.$emit事件以一些文本作为参数触发extraCall,这应该更新文本值,并且只在第二次单击后才会发生到显示按钮。

我错过了什么?

答案

由于<mycomponent>,单击“显示”按钮时,<childcomponent>(及其子v-if="showComponent")未实例化。

首先点击:

  1. extraCall是在公共汽车上发出的,但是没有听众可以忽略它。
  2. <mycomponent>设置为true后,showComponent被实例化。
  3. <mycomponent>extraCall钩子中注册了created事件的监听器。

第二次点击:

  1. extraCall在公共汽车上排放,<mycomponent>处理它。

您可能认为应该交换bus.$emit()this.showComponent = true行,以便在发出事件之前实例化<mycomponent>,但这仍然无法工作,因为Vue将视图更新后的组件创建推迟到下一个微任务。

这可能有效:

displayComponent() {
  this.showComponent = true;

  // Wait for child component to be instantiated
  this.$nextTick(() => {  
    bus.$emit('extraCall', 'this is some extra text');
  });
}

如果上面的代码适合你,我仍然不会真的推荐它。在发出事件之前,您不需要考虑创建子组件(它将组件耦合在一起)。您应该以其他方式共享数据,检查有关跨组件共享数据的最佳方法的其他SO问题。

以上是关于Vue2事件总线在第二次调用后工作的主要内容,如果未能解决你的问题,请参考以下文章

Click事件监听器仅在第二次工作

UIView 仅在第二次调用后显示

在第二次使用任何 Async api 调用后,Pi 上的 Bot 崩溃

为啥我的平移手势只能在第二次输入后识别事件?

模态仅在第二次单击后显示

jQuery 提交仅在第二次点击后工作