您的位置:首页 > 教育 > 锐评 > Vue 数据更新了但页面没有更新

Vue 数据更新了但页面没有更新

2025/4/3 18:41:33 来源:https://blog.csdn.net/m0_73531461/article/details/139447198  浏览:    关键词:Vue 数据更新了但页面没有更新

在 vue 项目中,有时我们会遇到修改完数据,但是视图却没有更新的情况。具体的场景不一样,解决问题的方法也不一样,在此汇总一下。

1. vue 无法检测实例被创建时没存在于 data 对象中的属性

原因:由于 vue 会在初始化实例时,对 data 对象中的属性执行 getter/setter 转化,所以属性必须在 data 对象上存在才能让 vue 将它转化为响应式的。

场景

let vm = new Vue({data:{},// 页面不会变化template: '<div>{{message}}</div>'
})
vm.message = 'Hello!' // `vm.message` 不是响应式的

解决办法

var vm = new Vue({data: {// 声明 message 为一个空字符串message: '',},template: '<div>{{ message }}</div>'
})
vm.message = 'Hello!'

2. vue 无法检测对象属性的添加或删除

原因:官方–由于 JavaScript(ES5) 的限制,Vue.js 不能检测到对象属性的添加或删除。因为 vue.js 在初始化实例时将属性转为 getter/setter,所以属性必须在 data 对象上才能让 vue.js 转换它,才能让它是响应的。

场景

var vm = new Vue({data:{obj: {id: 001}},// 页面不会变化template: '<div>{{ obj.message }}</div>'
})
vm.obj.message = 'hello' // 不是响应式的
delete vm.obj.id       // 不是响应式的

解决办法

// 动态添加 -- vue.set
Vue.set(vm.obj, message, 'hello');
// 动态添加 -- vm.$set
vm.$set(vm.obj, message, 'hello');// 动态添加多个
// 代替 Object.assign(this.obj, {a:1,b:2})
this.obj = Object.assign({}, this.obj, {a:1,b:2});// 动态移除--vm.$delect
Vue.delete(vm. obj, id);
// 动态移除 --vm.$delete
vm.$delete(vm. obj, id);

3. vue 不能检测通过数组索引值,直接修改一个数组项

原因:官方–由于 JavaScript 的限制,Vue 不能检测数组和对象的变化;性能代价和获得用户体验不成正比。

场景

var vm = new Vue({data: {items: ['a', 'b', 'c']}
})
vm.items[1] = 'x' // 不是响应性的

解决办法

// Vue.set
Vue.set(vm.items, 1, 'x');
// vm.$set
vm.$set(vm.items, 1, 'x');
// Array.prototype.splice
vm.items.splice(1, 1, 'x');

4. vue 不能监测直接修改数组长度的变化

原因:官方–由于 JavaScript 的限制,vue 不能检测数组和对象的变化;(性能代价和获得用户体验不成正比)。

场景

var vm = new Vue({data: {items: ['a', 'b', 'c']}
})
vm.items.length = 2 // 不是响应性的

解决办法

vm.items.splice(2)

那么在修改数组数据的时候,我们应该使用 push()、pop()、shift()、unshift()、splice()、sort()、reverse() 等原生的方法去操作数据,因为 vue 可以直接检测这些方法所带来的数组数据变化。

5. 使用 this.$forceUpdate() 强制更新

比如:循环嵌套层级太深,视图不更新

6. 使用 this.$nextTick(() => {  })

  • 如果修改完数据之后向立刻操作 DOM 元素,就需要使用 nextTick
    methods:{testClick:function(){this.msg="修改后的值";this.$nextTick(() => {console.log(that.$refs.btn.innerText);  // 输出:修改后的值});}
    }
    
  • 如果想要在 created() 中操作 DOM,也需要使用 nextTick,因为在此阶段,DOM 还未被渲染
    created(){this.$nextTick(() => {  // 不使用this.$nextTick()方法会报错that.$refs.btn.innerHTML="created中更改了按钮内容";  // 写入到DOM元素});
    },
    

7. 修改组件的 key 值

原因:当某个组件的 key 变化后,组件都会被重新渲染一遍

<template><el-table :data="data" :key="refresh">...</el-table>
</template>
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
@Component({})
export default class extends Vue {refresh = true@Watch('data')watchData() {this.refresh = !this.refresh}
}
</script>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com