Vue3 + Element Plus 报错:Cannot read properties of null (reading 'ce')

问题现象

在组件库中有一个封装组件 ElConfigProvider

vue 复制代码
<template>
  <el-config-provider v-bind="$attrs">
    <slot></slot>
  </el-config-provider>
</template>

在组件库自己的 demo 项目中使用时一切正常:

vue 复制代码
<ElConfigProvider namespace="otd" :size="'default'">
  <el-button>465</el-button>
</ElConfigProvider>

但当组件库打包后,通过 npm link 链接到另一个业务项目中使用时,控制台出现报错:

js 复制代码
runtime-core.esm-bundler.js:2984 Uncaught (in promise) TypeError: 
Cannot read properties of null (reading 'ce')
    at renderSlot (runtime-core.esm-bundler.js:2984)

初步分析

  • 报错位置在 Vue 3 内部的 renderSlot,意味着插槽 vnode 是 null

  • 一开始怀疑是 $attrs 透传问题或参数类型不对(如 locale)。

  • 经过多次验证,发现:

    • 在组件库 demo 项目中正常
    • 在业务项目中通过 npm link 使用时报错

这说明问题与业务逻辑本身关系不大,而是运行环境差异造成的。

核心原因

npm link 会在业务项目中产生两个 Vue 实例:

markdown 复制代码
projectA/ (业务项目)
  node_modules/
    vue/   ← 业务项目的 Vue
    otd-ui/  → symlink 到组件库
      node_modules/
        vue/ ← 组件库自己的 Vue

当:

  • 插槽 vnode 是由 业务项目的 Vue 渲染生成的
  • el-config-provider(来自组件库)是由 组件库的 Vue 渲染的

此时 vnode 跨 Vue 实例传递,Vue 内部类型检查不匹配,renderSlot 收到的 vnode.component 是 null,访问 .ce 就会报错。

在组件库 demo 项目中,Vue 实例只有一个,所以不报错

解决方案

目标:保证组件库和业务项目运行时只使用同一个 Vue 实例。

json 复制代码
{
  "peerDependencies": {
    "vue": "^3.2.0",
    "element-plus": "^2.0.0",
    "pinia": "^2.0.0"
  },
  "devDependencies": {
    "vue": "^3.2.0",
    "element-plus": "^2.0.0",
    "pinia": "^2.0.0"
  }
}
bash 复制代码
rm -rf node_modules/vue node_modules/element-plus node_modules/pinia
npm install

方法 2:npm link 时软链业务项目的 Vue

bash 复制代码
cd your-lib
npm link ../your-project/node_modules/vue
npm link ../your-project/node_modules/element-plus

方法 3:用 npm pack 代替 npm link

bash 复制代码
cd your-lib
npm pack
cd ../your-project
npm install ../your-lib/your-lib-0.0.1.tgz

这样依赖结构与正式发布一致,不会重复安装 Vue。

总结

这个错误的根源是 多 Vue 实例导致的 vnode 跨实例传递

在 Vue 3 中,不同实例的 vnode 互不兼容,一旦跨实例传递,就可能触发 renderSlot 中的 .ce 空值报错。

避免这个问题的关键是:组件库运行时使用业务项目的 Vue 实例

相关推荐
灵感__idea6 小时前
Hello 算法:贪心的世界
前端·javascript·算法
GreenTea7 小时前
一文搞懂Harness Engineering与Meta-Harness
前端·人工智能·后端
killerbasd9 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
吴声子夜歌9 小时前
ES6——二进制数组详解
前端·ecmascript·es6
码事漫谈9 小时前
手把手带你部署本地模型,让你Token自由(小白专属)
前端·后端
ZC跨境爬虫9 小时前
【爬虫实战对比】Requests vs Scrapy 笔趣阁小说爬虫,从单线程到高效并发的全方位升级
前端·爬虫·scrapy·html
爱上好庆祝9 小时前
svg图片
前端·css·学习·html·css3
王夏奇10 小时前
python中的__all__ 具体用法
java·前端·python
大家的林语冰10 小时前
《前端周刊》尤大开源 Vite+ 全家桶,前端工业革命启动;尤大爆料 Void 云服务新产品,Vite 进军全栈开发;ECMA 源码映射规范......
前端·javascript·vue.js
jiayong2311 小时前
第 8 课:开始引入组合式函数
前端·javascript·学习