Nuxt.js中axios请求后赋值newProducts遇Uncaught (in promise)错误
Nuxt.js 请求数据后赋值data报错的解决方法
问题描述
在Nuxt.js中使用axios发起请求,需要对返回结果做两次循环处理,再将列表数据赋值给data中的products或newProducts用于页面展示。但出现错误:
Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'newProducts')
控制台能打印出正确数据,但赋值到data时失败。原代码如下:
<script> export default { data(){ return { products:[], newProducts:[] } }, created() { this.fetchData(); }, methods:{ fetchData() { this.$axios.get('/products/'+this.$route.name) .then((response)=> { this.products = response.data }).finally(()=>{ this.formatProducts(); }) }, formatProducts(){ _.forEach(this.products, function(value){ _.forEach(value.productList, function(filteredProducts) { console.log(filteredProducts); this.newProducts = filteredProducts; }); }); } } } </script>
更新尝试中的错误
- 尝试1:使用箭头函数作为第二个forEach回调,报错
Uncaught (in promise) TypeError: values.forEach is not a function,代码:
this.products.forEach(function(values){ values.forEach(products => { this.newProducts = products; }); });
- 尝试2:使用两个箭头函数,报错
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'forEach'),代码:
this.products.forEach((productGroup, index) => { this.productGroup.forEach((product, index) => { console.log(product); }); });
错误原因分析
- 原代码错误核心:普通
function回调中的this指向问题。lodash的_.forEach普通函数回调里,this不再指向Vue组件实例,导致访问this.newProducts时提示undefined。 - 尝试1错误:
values是products数组中的单个对象(包含productList属性),不是数组,不能直接调用forEach,应该遍历values.productList;同时外层用普通function,this指向依然错误。 - 尝试2错误:遍历参数是
productGroup,但代码中写成了this.productGroup,这是组件实例不存在的属性,应该直接用productGroup.productList来遍历。
正确解决方案
方案1:用箭头函数保持this指向(推荐)
箭头函数会继承外层作用域的this,确保指向Vue组件实例,同时用push收集所有项(避免直接赋值覆盖数据):
formatProducts(){ _.forEach(this.products, (value) => { // 先判断productList是否为数组,避免空值报错 if (value.productList && Array.isArray(value.productList)) { _.forEach(value.productList, (filteredProducts) => { console.log(filteredProducts); this.newProducts.push(filteredProducts); }); } }); }
方案2:普通函数手动绑定this
如果坚持用普通函数回调,可通过bind(this)手动绑定组件实例的this:
formatProducts(){ _.forEach(this.products, function(value){ if (value.productList && Array.isArray(value.productList)) { _.forEach(value.productList, function(filteredProducts) { console.log(filteredProducts); this.newProducts.push(filteredProducts); }.bind(this)); } }.bind(this)); }
方案3:原生数组forEach写法
不用lodash,直接用原生数组方法,同样注意this指向和遍历对象的正确属性:
formatProducts(){ this.products.forEach((productGroup) => { if (productGroup.productList && Array.isArray(productGroup.productList)) { productGroup.productList.forEach((product) => { console.log(product); this.newProducts.push(product); }); } }); }
注意:如果需要收集所有
productList中的项到newProducts,必须用push方法;如果直接赋值this.newProducts = filteredProducts,最终newProducts会变成单个对象,而非数组。
内容的提问来源于stack exchange,提问作者ottz0
相关产品推荐
相关产品推荐

