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

添加模态框后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.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 00:44:52