VueJS中AJAX更新数据后DOM未更新的问题排查
嘿,这个问题我之前踩过坑,咱们一步步拆解解决:
核心问题1:回调函数里的this指向错误
你代码里用的self根本没正确指向Vue实例!在jQuery的$.ajax回调函数内部,this的指向会变成AJAX请求对象,而非你的Vue实例app。如果没提前把Vue实例的引用存下来,这里的self要么是全局的window对象,要么直接未定义——哪怕控制台能打印出值,那也是给全局变量赋值了,根本没更新Vue实例的data。
修复方案(三种任选其一):
方案1:提前保存Vue实例的引用
在fetch_data方法开头,把当前Vue实例的this存到变量里,后续用这个变量访问实例:fetch_data: function() { console.log('Running script for ajax...'); $("#retrieve_data_wait").text("Retrieving data. This will update when complete..."); // 保存Vue实例的引用 var vm = this; $.ajax({ url: '/test_json', dataType: 'json', timeout: 60000, success: function(data) { $("#retrieve_data_wait").text(data.test); // 通过vm访问Vue实例的data vm.message = 'Love the Vue.JS'; console.log('SUCCESS') console.log(vm.message); }, error: function(data) { $("#retrieve_data_wait").text("Fail"); } }); }方案2:使用箭头函数(ES6+)
箭头函数不会绑定自己的this,会直接继承外层作用域的this(也就是Vue实例的this):success: (data) => { $("#retrieve_data_wait").text(data.test); this.message = 'Love the Vue.JS'; console.log('SUCCESS') console.log(this.message); }方案3:利用jQuery的
context选项
给$.ajax配置context: this,强制让回调函数里的this指向Vue实例:$.ajax({ url: '/test_json', dataType: 'json', timeout: 60000, context: this, // 指定回调里的this指向当前Vue实例 success: function(data) { $("#retrieve_data_wait").text(data.test); this.message = 'Love the Vue.JS'; console.log('SUCCESS') console.log(this.message); }, error: function(data) { $("#retrieve_data_wait").text("Fail"); } });
核心问题2:DOM中没有渲染message的元素
看你的HTML代码,只有<span id="retrieve_data_wait"></span>,但没有任何绑定[[ message ]]的元素!就算你更新了data.message,页面上也没地方显示这个值,自然看起来DOM没同步。
修复HTML:
在#app容器里添加渲染message的元素,比如:
<div id="app"> <span id="retrieve_data_wait"></span> <!-- 新增:显示message的值 --> <p>当前消息:[[ message ]]</p> </div>
额外建议:尽量避免直接操作DOM
Vue的核心是数据驱动DOM,你现在用$("#retrieve_data_wait").text(...)手动操作DOM,其实违背了Vue的设计理念。更好的做法是把加载状态也改成数据绑定:
优化后的完整代码示例:
JavaScript:
var app = new Vue({ delimiters: ['[[', ']]'], el: '#app', data: { message: 'Hello Vue.js!', retrieveText: '' // 新增数据属性,用于显示加载状态 }, methods: { fetch_data: function() { console.log('Running script for ajax...'); this.retrieveText = "Retrieving data. This will update when complete..."; var vm = this; $.ajax({ url: '/test_json', dataType: 'json', timeout: 60000, success: function(data) { vm.retrieveText = data.test; vm.message = 'Love the Vue.JS'; console.log('SUCCESS') console.log(vm.message); }, error: function(data) { vm.retrieveText = "Fail"; } }); } } })
HTML:
<div id="app"> <span>[[ retrieveText ]]</span> <p>当前消息:[[ message ]]</p> <!-- 假设你有一个触发请求的按钮 --> <button @click="fetch_data">获取数据</button> </div>
这样完全用数据驱动DOM,就不会出现手动操作DOM带来的各种问题啦!
内容的提问来源于stack exchange,提问作者user3308477

