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

求助:Pinia动态渲染组件时触发TypeError: d is null错误

解决Vue动态组件渲染报错TypeError: d is null的问题

问题场景

代码中Pinia状态管理逻辑正常,点击标签页时selected状态能正确更新,但动态渲染组件时触发TypeError: d is null报错,组件无法正常显示。

核心原因

  1. 异步组件被响应式系统包裹:Pinia状态中的component是异步导入函数,Vue的响应式系统会自动包装该函数,导致动态组件<component>无法正确识别组件对象。
  2. 初始化时机不匹配:页面加载初期selected为空对象,此时activeComponent返回undefined,触发组件渲染异常。

解决方案

1. 用markRaw标记异步组件

在Pinia store中,给每个异步导入的组件添加markRaw,避免被Vue响应式系统处理(动态组件不需要响应式特性)。

2. 控制组件渲染时机

在模板中给动态组件部分添加v-if="tabs.ready",确保selected状态完成初始化后再渲染组件。

修改后的代码示例

Pinia Store代码

import { defineStore, markRaw } from 'pinia' // 导入markRaw

export const useTabs = defineStore('tabs',  {
  state: () => ({
    ready: false,
    selected: {},
    list:[
        {
            name: "Pubblicazione",
            icon: "fas fa-image",
            component: markRaw(() => import('@Squadrario/Views/Pubblicazione.vue')) // 用markRaw包裹异步组件
        },
        {
            name: "Edit",
            icon:"fas fa-music",
            component: markRaw(() => import('@Squadrario/Views/Edit.vue')) // 用markRaw包裹异步组件
        },
    ],
  }),
  getters: {
    isActive: (state) => {
        return (id) => state.selected.name == state.list[id].name
    },
    activeComponent: (state) => {
        return state.selected.component || null; // 兜底返回null避免异常
    }
  },
  actions: {
    init(){
      this.selected = this.list[0];
      this.ready = true;
    },
    activate(id){
        this.selected = this.list[id];
    },
  },
})

主组件代码

<script setup>
import { onBeforeMount } from 'vue'
import { storeToRefs} from 'pinia'
import { useTabs } from './stores/tabs.js';

const tabs = useTabs();
const { isActive, activeComponent } = storeToRefs(tabs);

onBeforeMount(() => {
    tabs.init();
})
</script>
<template>
    <div v-if="tabs.ready" class="tabs is-toggle is-centered">
        <ul>
            <li v-for="(item,id) in tabs.list" :class="{'is-active': isActive(id)}" @click="tabs.activate(id)">
                <a>
                    <span class="icon is-small"><i :class="item.icon" aria-hidden="true"></i></span>
                    <span>{{ item.name }}</span>
                </a>
            </li>
        </ul>
    </div>
    <!-- 等待状态初始化完成后再渲染动态组件 -->
    <Transition v-if="tabs.ready">
        <keep-alive>
            <component :is="activeComponent"></component>
        </keep-alive>
    </Transition>
</template>
<style>
</style>

效果验证

修改后,点击标签页时activeComponent能正确返回经过markRaw处理的异步组件函数,动态组件可正常渲染,不会再出现TypeError: d is null报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 16:26:10