求助:Pinia动态渲染组件时触发TypeError: d is null错误
解决Vue动态组件渲染报错TypeError: d is null的问题
问题场景
代码中Pinia状态管理逻辑正常,点击标签页时selected状态能正确更新,但动态渲染组件时触发TypeError: d is null报错,组件无法正常显示。
核心原因
- 异步组件被响应式系统包裹:Pinia状态中的
component是异步导入函数,Vue的响应式系统会自动包装该函数,导致动态组件<component>无法正确识别组件对象。 - 初始化时机不匹配:页面加载初期
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
相关产品推荐
相关产品推荐

