You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue组件间emit通信问题:按钮组件触发事件后输入组件未捕获

问题根源

Vue组件的事件传递是子组件→直接父组件的单向机制,ButtonIO和DisplayInput属于兄弟组件,前者触发的trigger-emit事件无法直接被后者捕获,必须通过共同父组件App.vue作为中转。

修复方案

1. 修改App.vue,承担事件中转与状态管理

在父组件中监听ButtonIO的事件,维护计算器输入状态,再将状态传递给DisplayInput:

<template>
  <div class="container mt-5">
    <div class="col-2">
        <div class="d-flex justify-content-center">
            <!-- 传递父组件的输入状态给DisplayInput -->
            <DisplayInput :inputValue="inputValue"/>
        </div>
        
        <div class="d-flex justify-content-center">
            <!-- 监听ButtonIO的trigger-emit事件 -->
            <ButtonIO value="1" @trigger-emit="handleButtonClick"/>
            <ButtonIO value="2" @trigger-emit="handleButtonClick"/>
            <ButtonIO value="3" @trigger-emit="handleButtonClick"/>
        </div>

        <div class="d-flex justify-content-center">
            <ButtonIO value="4" @trigger-emit="handleButtonClick"/>
            <ButtonIO value="5" @trigger-emit="handleButtonClick"/>
            <ButtonIO value="6" @trigger-emit="handleButtonClick"/>
        </div>

        <div class="d-flex justify-content-center">
            <ButtonIO value="7" @trigger-emit="handleButtonClick"/>
            <ButtonIO value="8" @trigger-emit="handleButtonClick"/>
            <ButtonIO value="9" @trigger-emit="handleButtonClick"/>
        </div>

        <div class="d-flex justify-content-center">
          <ButtonIO value="+" @trigger-emit="handleButtonClick"/>
          <ButtonIO value="-" @trigger-emit="handleButtonClick"/>
          <ButtonIO value="*" @trigger-emit="handleButtonClick"/>
          <ButtonIO value="/" @trigger-emit="handleButtonClick"/>
        </div>
        <div class="d-flex justify-content-center">
          <ButtonIO value="=" @trigger-emit="handleButtonClick"/>
        </div>
    </div>
  </div>
</template>

<script>
import ButtonIO from './components/ButtonIO.vue';
import DisplayInput from './components/DisplayInput.vue';

export default {
    name: 'App',
    components: {
        ButtonIO,
        DisplayInput,
    },
    data() {
        return {
            inputValue: '' // 存储计算器输入内容
        }
    },
    methods: {
        handleButtonClick(value) {
            if (value === '=') {
                try {
                    // 简单实现计算逻辑,实际项目需添加安全校验
                    this.inputValue = eval(this.inputValue).toString();
                } catch (e) {
                    this.inputValue = 'Error';
                }
            } else {
                this.inputValue += value;
            }
        }
    }
}
</script>

2. 修改DisplayInput.vue,接收父组件状态

让DisplayInput通过props接收父组件传递的输入值,实现内容同步:

<template>
<!-- 绑定props到输入框value,确保内容与父组件状态一致 -->
<input type="text" class="form-control" :value="inputValue">
</template>

<script>
export default {
    name: 'DisplayInput',
    props: ['inputValue'] // 声明接收父组件的props
}
</script>

3. 保留ButtonIO.vue原有代码

ButtonIO的职责是触发事件并传递按钮值,原有代码无需修改:

<template>
    <button @click="$emit('trigger-emit', value)" class="btn btn-secondary m-2" type="button">{{ value }}</button>
</template>

<script>
export default {
    name: 'ButtonIO',
    props: ['value'],  
}
</script>
验证效果

点击按钮后,App.vue会捕获trigger-emit事件并更新输入状态,DisplayInput会实时显示点击内容,点击=号可执行简单计算。

内容的提问来源于stack exchange,提问作者Exploit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:11:09