Vue.js数组复制报错求助:无法读取'name'属性
问题分析与解决方案
咱们一步步拆解你遇到的几个问题:
1. forEach回调中this指向错误
你这段代码报错Cannot read property 'translations' of undefined,是因为普通function回调里的this并不指向Vue实例:
this.languages.forEach( function (item) { this.translations.push(item); });
解决方法很简单,二选一就行:
- 用箭头函数,它会自动继承外部作用域的
this:
this.languages.forEach(item => { this.translations.push(item); });
- 提前把Vue实例的
this存起来:
const vm = this; this.languages.forEach(function(item) { vm.translations.push(item); });
2. 浅拷贝导致原数组被修改
你用slice(0)、直接赋值this.translations = this.languages都是浅拷贝——当数组里的元素是对象类型时,拷贝的只是对象的引用,新数组和原数组里的对象指向同一个内存地址。所以你修改temp里的对象属性时,原languages数组也会跟着变。
要实现完全独立的数组拷贝(深拷贝),可以根据你的场景选方法:
- 如果数组里都是简单对象(没有嵌套对象、函数、Symbol等特殊类型),用JSON序列化最方便:
this.translations = JSON.parse(JSON.stringify(this.languages));
- 如果是复杂对象,自己写个递归深拷贝函数:
function deepCopy(obj) { if (typeof obj !== 'object' || obj === null) return obj; const copy = Array.isArray(obj) ? [] : {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { copy[key] = deepCopy(obj[key]); } } return copy; } // 在你的方法里调用 this.translations = deepCopy(this.languages);
3. 渲染时Cannot read property 'name' of undefined错误
这个错误的核心是:你的模板里大概率在直接访问translations数组中某个元素的name属性(比如{{ translations[0].name }}),但在mounted执行时,languages可能还没被父组件正确赋值(比如父组件是异步接口获取数据,子组件mounted时languages还是空数组),此时复制后translations是空数组,访问translations[0].name就会报错;而注释掉复制代码时,translations保持初始空数组,可能模板里有条件判断跳过了这段渲染,所以错误消失。
解决这个渲染问题,给你几个方案:
- 用可选链操作符(现代浏览器支持),避免访问undefined的属性:
{{ translations[0]?.name }}
- 加条件渲染,确保数组有内容再渲染:
<template v-if="translations.length > 0"> {{ translations[0].name }} </template>
- 给
translations设置符合模板预期的初始结构:
data() { return { translations: [{ value: { name: '', metaKeywords: '', metaDescription: '' } }] }; }
最后再提醒一下:你最后那段能运行但修改原数组的代码,本质还是因为浅拷贝,用深拷贝之后再修改translations里的对象,就不会影响原languages数组了。
内容的提问来源于stack exchange,提问作者dust_bg
相关产品推荐
相关产品推荐

