Vue项目访问date内容为空,控制台输出正常但前端页面无渲染数据
Vue项目响应式数据控制台输出正常但页面不渲染解决方案
问题原因
- 生命周期选择错误:你将异步请求逻辑写在了
beforeCreate生命周期钩子中,该阶段Vue的data数据还未完成响应式代理初始化,此时对data属性赋值无法触发视图更新。 - 普通函数this指向偏移:你定义的
computaTudo、countItems、ordeNar、finished都是普通函数,这类函数内部的this默认指向全局window对象,你赋值的this.bestc实际是挂载在window上的属性,而非Vue实例data中的bestc,这就是控制台能打印出预期值、但Vue视图没有更新的核心原因。
修复方案
- 把请求逻辑迁移到
created生命周期钩子,该阶段data已经完成初始化,响应式代理正式生效。 - 提前保存Vue实例指向,所有操作data属性的地方都用保存的实例变量访问,避免普通函数的this指向偏移问题。
修改后的核心代码如下:
el: "#app", data: { arrays: [], bestc: [], todos: [], errored: false, loading: false }, created(){ // 提前保存Vue实例指向,避免普通函数this偏移 const vm = this axios .get("https://api.com/result") .then((response) => { for (var i = 0; i < response.data.length; i++) { vm.arrays.push(response.data[i].dezenas); } }) .catch((error) => { console.log(error); vm.errored = true; }) .finally(() => computaTudo(vm.arrays)); function computaTudo(array) { var content = []; for (var j = 0; j < array.length; j++) { content = content.concat(array[j]); } return countItems(content); } function countItems(arr) { const countMap = Object.create(null); for (const element of arr) { countMap[element] = (countMap[element] || 0) + 1; } vm.todos = Object.entries(countMap).map(([value, count]) => ({ numero: value, quantidade: count, })); return ordeNar(); } function ordeNar() { let ordenadoPor = vm.todos.slice(0); ordenadoPor.sort(function (a, b) { return b.quantidade - a.quantidade; }); return finished(ordenadoPor); } function finished(ord){ let localArr = ord.map(function (obj) { return obj.numero; }); // 直接给Vue实例的bestc赋值整段数组,符合Vue2响应式触发规则 vm.bestc = localArr; if (vm.bestc.length > 0) { loader.hide(); vm.loading = true; console.log(vm.bestc) } } }
补充说明
如果后续需要修改数组的单个元素,需要使用Vue.set或者数组的splice等变异方法触发响应式,本次场景中直接为bestc赋值完整数组的操作本身符合响应式触发要求,仅需修正指向即可正常触发视图更新。
内容的提问来源于stack exchange,提问作者Douglas Teles
相关产品推荐
相关产品推荐

