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

Vue.js子组件注入变量初始为undefined,跳转链接id获取失败

Vue组件传值与跳转链接问题排查与修复

问题场景

父组件内通过按钮点击修改selectedReceipt变量,并用provide传递给子组件。子组件通过inject获取变量后,初始值为undefined,但watch监听能正常拿到值;尝试通过链接'printDetails/' + selectedReceipt?.value?.id跳转时,id始终显示undefined。


父组件代码

<script setup>
const selectedReceipt = ref([]);
provide('selectedReceipt', selectedReceipt);

function setSelectedReceipt(receipt){
    selectedReceipt.value = receipt;
}
</script>

<template>
  <tr v-for="(receipt,index) in receipts" :key="index">
    <td class="align-middle">{{ index + receipts_Data.from }}</td>
    <td class="align-middle">{{ receipt.hospitals ? receipt.hospitals.en_name: 'N/A' }}</td>
    <td class="align-middle">{{ receipt.years ? receipt.years.en_name : 'N/A' }}</td>
    <td class="align-middle">{{ receipt.months ? receipt.months.month_name : 'N/A' }}</td>
    <td class="align-middle">{{ receipt.assessment_date }}</td>
    <td class="align-middle">{{ receipt.maktoob_no }}</td>
    <td class="align-middle">{{ receipt.maktoob_date }}</td>
    <td class="align-middle">{{ receipt.description }}</td>
    <td class="align-middle">
      <div class="btn-list">
        <AppButton
          @click="setSelectedReceipt(receipt)" type="outline-primary" btn-sm
          data-bs-toggle="modal" data-bs-target="#edit_receipts_modal">
          <i class="fe fe-edit"></i>
        </AppButton>
        <BtnOptions @click="setSelectedReceipt(receipt)"
          type="outline-primary" btn-sm>
          <li><a @click="openDetailsModal">Details</a></li>
          <li><a @click="openStaffModal">Staff</a></li>
        </BtnOptions>
      </div>
    </td>
  </tr>
</template>

子组件代码

<script setup>
const selectedReceipt = inject('selectedReceipt');

watch( () => selectedReceipt, async() => {
        console.log(selectedReceipt.value);
        master_Filter.value.hospital_id = selectedReceipt.value.hospitals.en_name;

        master_Filter.value.assessment_date = selectedReceipt.value.assessment_date;
        master_Filter.value.maktoob_no = selectedReceipt.value.maktoob_no;
        master_Filter.value.maktoob_date = selectedReceipt.value.maktoob_date;

        await getDetails();
    },
    {deep: true });
</script>

<template>
  <template #footer>
    <button type="reset" form="frm-store" class="btn btn-default btnCloseModal" data-bs-dismiss="modal">{{ Lang.get('Close') }}</button>
    
    <AppButton type="btn-primary">
      <a :href="'printDetails/' + selectedReceipt?.value?.id">Print</a>
    </AppButton>
  </template>
</template>

问题原因与修复方案

1. 初始值类型不匹配

父组件中selectedReceipt初始化为数组ref([]),但实际赋值的是单个receipt对象,类型不一致会导致模板中可选链判断失效。
修复:将初始值改为与赋值类型一致的null:

const selectedReceipt = ref(null);
provide('selectedReceipt', selectedReceipt);

2. Watch监听逻辑错误

当前监听的是selectedReceipt这个ref对象本身,而非其value属性,虽开启deep: true能触发,但写法不规范且容易引发异常。
修复:直接监听ref对象,并新增空值判断:

watch(selectedReceipt, async (newReceipt) => {
  if (!newReceipt) return; // 避免初始undefined时执行后续逻辑
  console.log(newReceipt);
  master_Filter.value.hospital_id = newReceipt.hospitals.en_name;
  master_Filter.value.assessment_date = newReceipt.assessment_date;
  master_Filter.value.maktoob_no = newReceipt.maktoob_no;
  master_Filter.value.maktoob_date = newReceipt.maktoob_date;

  await getDetails();
}, { deep: true });

3. 模板链接的空值安全处理

即使使用可选链,仍需确保selectedReceipt.value.id存在时才渲染按钮,避免生成无效链接。
修复:添加条件渲染:

<template #footer>
  <button type="reset" form="frm-store" class="btn btn-default btnCloseModal" data-bs-dismiss="modal">{{ Lang.get('Close') }}</button>
  
  <AppButton v-if="selectedReceipt?.value?.id" type="btn-primary">
    <a :href="'printDetails/' + selectedReceipt.value.id">Print</a>
  </AppButton>
</template>

4. 模态框与状态更新的同步问题

点击Details时,先设置selectedReceipt再打开模态框,若模态框基于DOM操作(如Bootstrap),可能存在子组件未及时更新状态的情况。
修复:使用nextTick等待状态更新后再打开模态框:

// 父组件中修改openDetailsModal方法
import { nextTick } from 'vue';

async function openDetailsModal() {
  await nextTick(); // 等待Vue完成状态更新和DOM渲染
  const modal = new bootstrap.Modal(document.getElementById('你的详情模态框ID'));
  modal.show();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:45:20