Vue.js 3 SFC兄弟组件传值失败求助:卡片与输入框传ID
Vue3 兄弟组件传值问题解决方案
问题排查
你的代码存在三个核心问题导致传值失败:
- ButtonElement未转发点击事件:CardElement中直接给ButtonElement绑定
@click不会生效,因为ButtonElement组件内部没有监听原生按钮点击并向上传递事件。 - 响应式变量赋值错误:
selectedHeader是用ref创建的响应式变量,直接赋值selectedHeader = header会丢失响应式,必须通过.value修改。 - InputElement传参方式错误:需要通过绑定
input-label属性传递变量,而非将变量放在组件标签内部(你的组件未定义插槽)。
修改后的代码
1. ButtonElement.vue
添加点击事件转发逻辑,让父组件能监听到按钮点击:
<script setup> const props = defineProps({ editBtn: { type: String } }) // 定义要触发的事件 const emit = defineEmits(['click']) </script> <template> <button type="button" class="btn btn-outline-light btn-sm ms-5" @click="emit('click')" > {{ editBtn }} </button> </template>
2. CardElement.vue
显式声明要向父组件触发的事件,确保点击事件能正确传递:
<script setup> import ButtonElement from './ButtonElement.vue' defineProps({ header: { type: String, required: true } }) // 定义向App.vue传递的事件 const emit = defineEmits(['displayBtnId']) </script> <template> <div class="col-sm-6 col-12 d-flex justify-content-center align-items-center"> <div class="card text-white mb-3"> <div class="card-header"> {{ header }} <ButtonElement @click="emit('displayBtnId', header)" :id="header" edit-btn="Add item" ></ButtonElement> </div> <div class="card-body"> <p class="card-text"></p> </div> </div> </div> </template>
3. App.vue
修正响应式变量赋值方式,并正确给InputElement传递参数:
<script setup> import { ref } from 'vue'; import CardElement from './components/CardElement.vue'; import InputElement from './components/InputElement.vue'; const selectedHeader = ref(''); function displayBtnIdOnInput(header){ console.log(header) // 修正ref变量的赋值方式 selectedHeader.value = header; console.log('id ' + selectedHeader.value) } </script> <template> <main> <div class="row mt-4 mb-4"> <CardElement type="bg-primary" header="Typical" @displayBtnId="displayBtnIdOnInput" ></CardElement> <CardElement type="bg-warning" header="Non-typical" @displayBtnId="displayBtnIdOnInput" ></CardElement> </div> <div class="row mt-4 mb-4"> <!-- 正确绑定input-label属性,传递响应式变量 --> <InputElement :input-label="selectedHeader"></InputElement> </div> </main> </template>
4. InputElement.vue
保持原代码即可,无需修改:
<script setup> defineProps({ inputLabel: { type: String }, }) </script> <template> <div class="col-12 d-flex justify-content-center align-items-center"> <div class="input-group"> <span class="input-group-text">{{ inputLabel}}</span> <textarea class="form-control"></textarea> </div> </div> </template>
总结
修改后,点击卡片上的按钮时,卡片的header值会通过ButtonElement -> CardElement -> App.vue -> InputElement的路径传递,最终在输入框的标签中显示选中的ID。
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

