Vue中获取Ajax响应后如何更新/触发HTML DOM?
解决Vue实例更新后DOM不自动变更的问题
Hey there! Let's work through why your DOM isn't updating after fetching new todos via Ajax. I've spotted a couple of key issues in your code that are causing this behavior:
主要问题分析
this指向错误:在setInterval的普通函数回调里,this并不指向你的Vue实例,而是指向window对象。这意味着你执行this.todos = response.data时,根本没有修改Vue实例里的todos数据,自然不会触发DOM更新。- 错误使用
Vue.set:你写的Vue.set(this, todos, response.data)存在两个问题:一是第二个参数应该是字符串形式的属性名'todos'(而不是未定义的变量todos);二是其实当你正确给Vue实例的todos赋值新对象时,Vue的响应式系统是能直接检测到的,这个Vue.set完全多余,甚至会引发错误。
修正后的代码
<div id="app"> <ul> <!-- 建议添加key属性,提升列表更新效率 --> <li v-for="(question, index) in todos.text" :key="index"> {{ question.text }} </li> </ul> </div> <script> var app = new Vue({ el: '#app', data: function () { return { message: 'You loaded this page on ' + new Date().toLocaleString(), todos: { Event: 'Event1', text: [ { text: 'Learn JavaScript1' }, { text: 'Learn Vue1' }, { text: 'Build something awesome1' } ] } } }, mounted: function() { // 使用箭头函数,确保this指向Vue实例 setInterval(() => { axios({ method: 'post', url: 'test.php', data: { firstName: 'Fred', lastName: 'Flintstone' } }).then(response => { console.log(response.data); // 直接赋值即可,Vue会检测到todos的变化 this.todos = response.data; }) .catch(err => { console.log(err); }); }, 5000); } }) </script>
额外提示
- 如果你需要更新
todos内部的某个嵌套属性(而不是替换整个todos对象),才需要用到Vue.set或者this.$set,比如this.$set(this.todos.text, 0, { text: 'New Text' })。 - 用
setInterval轮询接口要注意频率,避免给服务器造成过大压力,也可以考虑用WebSocket实现更高效的实时更新。
内容的提问来源于stack exchange,提问作者user8646340
相关产品推荐
相关产品推荐

