添加模态框后Vue中v-show失效问题排查求助
Vue展开行v-show失效问题排查
问题背景
首次学习Vue,开发带数据行的应用,通过v-show实现可展开行以避免一次性加载过多数据,点击按钮展开时调用数据库获取对应行的额外信息,原本功能正常。但添加编辑/删除模态框按钮后,v-show功能失效。
组件结构
- Row.vue:每行固定显示的信息及展开按钮
- RowContent.vue:点击展开后显示的内容,包含打开模态框的按钮
- DeleteModal.vue/EditModal.vue:删除/编辑确认模态框
层级关系:Row.vue -> RowContent.vue -> DeleteModal.vue/EditModal.vue
现有代码
Row.vue
<script setup> const isOpen=ref(false); function expand(npc) { isOpen.value = !isOpen.value npcName.value = ref(npc.get('Name')); if(isOpen.value){ getClass(npc); getType(npc); getRace(npc); } } </script> <template> <div class="RowBackground"> <div class="alwaysShown"> <h1>{{ npc.get('Name') }}</h1> <button @click="expand(npc)">Expand</button> </div> <RowContent class='drawer' :npcName='npcName' :npcClass='npcClass' :npcType='npcType' :race='race' :extra='extra' v-show='isOpen'></RowContent> </div> </template> <script> import RowContent from './RowContent.vue'; export default { props: { npc: Object, }, components: { RowContent, }, }; </script>
RowContent.vue
<script setup> import DeleteModal from '../components/DeleteModal.vue'; import { ref } from 'vue'; const showModal= ref(false); </script> <template> <div class="rowContainer"> <div class="row"> <h3>Class: {{ npcClass }}</h3> <h3>Type: {{ npcType }}</h3> </div> <div class="row"> <h3>Race: {{ race }}</h3> <h3>Extra: {{ extra }}</h3> </div> <div class="row"> <button class="editButton">Edit</button> <button class="deleteButton" @click="showModal=true">Delete</button> </div> </div> <DeleteModal :npcName="npcName" :show="showModal" @close="showModal = false"> </DeleteModal> </template>
DeleteModal.vue
<script setup> const props = defineProps({ show: Boolean, }); </script> <template> <div v-if="show" class="modal-mask"> <div class="modal-container"> <div class="modal-header"> <h3 class="deleteText">Delete {{ npcName }} permanently?</h3> </div> <div class="modal-body"> <div class="interactionButtons"> <button>Confirm</button> <button @click="$emit('close')">Cancel</button> </div> </div> </div> </div> </template> <script> export default { props: { npcName: { type: String } }, data() { return { isOpen: false, }; }, }; </script>
问题分析与修复方案
1. 响应式变量赋值错误(Row.vue)
在expand函数中,npcName.value = ref(npc.get('Name'))是错误的:npcName本身已经是ref创建的响应式变量,赋值时不需要再用ref包裹,直接赋值即可。同时需要先声明npcName及其他传递给子组件的响应式变量:
修正后的Row.vue <script setup>:
<script setup> import { ref } from 'vue'; import RowContent from './RowContent.vue'; const props = defineProps({ npc: Object, }); const isOpen = ref(false); const npcName = ref(''); const npcClass = ref(''); const npcType = ref(''); const race = ref(''); const extra = ref(''); function expand(npc) { isOpen.value = !isOpen.value; npcName.value = npc.get('Name'); // 去掉多余的ref if (isOpen.value) { getClass(npc); getType(npc); getRace(npc); } } // 补充示例数据获取函数(根据实际逻辑调整) function getClass(npc) { npcClass.value = npc.get('Class'); } function getType(npc) { npcType.value = npc.get('Type'); } function getRace(npc) { race.value = npc.get('Race'); } </script>
2. 组件API混用(DeleteModal.vue)
同时使用<script setup>和选项式API会导致响应式逻辑冲突,统一改为<script setup>风格:
修正后的DeleteModal.vue:
<script setup> const props = defineProps({ show: Boolean, npcName: String }); const emit = defineEmits(['close']); </script> <template> <div v-if="show" class="modal-mask"> <div class="modal-container"> <div class="modal-header"> <h3 class="deleteText">Delete {{ npcName }} permanently?</h3> </div> <div class="modal-body"> <div class="interactionButtons"> <button>Confirm</button> <button @click="emit('close')">Cancel</button> </div> </div> </div> </div> </template>
3. 补充子组件Props声明(RowContent.vue)
确保RowContent.vue中接收的所有props都通过defineProps声明,否则无法正常读取:
<script setup> import DeleteModal from '../components/DeleteModal.vue'; import { ref } from 'vue'; const props = defineProps({ npcName: String, npcClass: String, npcType: String, race: String, extra: String }); const showModal= ref(false); </script>
总结
修复后,v-show的响应式状态会正常工作,模态框的交互也不会影响展开行的显示逻辑。
内容的提问来源于stack exchange,提问作者Tony L.
相关产品推荐
相关产品推荐

