Nuxt引入外部Vue组件出现$attrs、$listeners只读及props突变报错如何解决
问题根因
这个报错的核心原因是运行时存在两个独立的Vue实例。当你从Nuxt项目外的目录导入组件时,组件所依赖的Vue是其所在目录下node_modules中安装的版本,和Nuxt项目自身依赖的Vue是两份完全独立的代码,两个实例各自维护内置属性的读写权限和响应式规则,就会触发$attrs、$listeners只读、props被意外修改的警告。当你把组件复制到Nuxt项目目录内后,组件会统一使用项目内的Vue实例,因此报错消失。
可行解决方案
场景1:外部组件为待发布的npm包
- 将组件库package.json中的
vue、vue-property-decorator从dependencies移到peerDependencies,声明依赖由宿主项目提供。 - 打包组件库时配置externals排除Vue相关依赖,以webpack为例:
// 组件库webpack配置 module.exports = { // 其他配置项 externals: { vue: 'Vue', 'vue-property-decorator': 'vuePropertyDecorator' } }
场景2:本地开发直接导入外部未打包的组件文件/使用npm link调试组件库
修改Nuxt项目的nuxt.config.js配置:
- 强制所有Vue相关导入指向项目内的依赖实例
- 把外部组件目录加入转译列表
export default { build: { // 填入外部组件所在目录的绝对路径 transpile: ['/absolute/path/to/your/external/component/directory'], extend(config) { // 强制所有导入都使用项目内的Vue实例 config.resolve.alias['vue'] = require.resolve('vue') config.resolve.alias['vue-property-decorator'] = require.resolve('vue-property-decorator') } } }
验证方法
你可以分别在外部组件的代码和Nuxt项目的代码中打印console.log(Vue),如果是两个不同的对象即可确诊为多实例问题,按上述方案配置后两个位置打印的Vue会是同一个实例,报错即可解决。
内容的提问来源于stack exchange,提问作者Colibri
相关产品推荐
相关产品推荐

