this.$set解决添加对象属性后,页面不显示效果的问题

本文介绍了在Vue项目中遇到的问题,即向对象添加新属性后,页面视图未更新。文章详细解释了响应式对象的概念,以及当普通对象新增属性后,为何需要使用this.$set方法确保属性变为响应式。通过示例代码展示了如何使用this.$set方法在模板中正确显示新增数据,并提供了解决页面不更新问题的解决方案。

项目场景:

写项目的时候由于项目需求需要给对象添加新的属性,但是添加属性后,在console面板上可以打印,但是页面视图上不显示对应效果,经网阅资料进行记录,以供参考

目录

项目场景:

原因分析:

解决方案:

 参阅资料:



原因分析:

这里涉及到一个概念,叫做响应式对象,普通对象设置了对象的访问属性:getter和setter后,成为一个响应式对象,响应式对象调用和修改属性需要对应用到get和set方法,如果添加或修改属性后不能正常在视图显示,那么就需要设置对象属性也是一个响应式对象,进而用到set方法解决


解决方案:

可以用到vue.set(obj,key,value)方法,也可以使用this.$set(obj,key,value)方法,虽然有本质区别,但是原理相同,此处使用this.$set方法

<template>
  <div>
    <el-card>{{ student }}</el-card>
    <el-button type="primary" @click="newData">点击显示新数据</el-button>
    <!-- 按钮监听点击事件绑定newData方法,newData方法里使用了set方法 -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 定义要修改的数据源,可以是数组,对象
      student: {
        name: 'zs',
        age: 5,
        sex: 'male',
      },
    }
  },
  mounted() {
    this.student.score = 90 // 普通方法修改数据,控制台输出{ "name": "zs", "age": 5, "sex": "male" },但是页面视图不显示
    console.log(this.student)
  },
  methods: {
    newData() {
      this.$set(this.student, 'score', 80) // set方法修改数据使新增的数据也成为响应式
      this.student = Object.assign({}, this.student) // 新增了响应式数据之后将整个对象重新拷贝赋值给this.student,之后页面可以正常显示新增数据
    },
  },
}
</script>

<style lang="less" scoped></style>

 点击按钮之前,在mounted里模拟普通对象新增数据score:90,console有输出,但是页面不显示

点击按钮之后,使用this.set方法新增数据score:80,页面正常显示

 

 

 参阅资料:

响应式对象是一个什么对象 - 哔哩哔哩点击进入查看全文>https://www.bilibili.com/read/cv4303259/vue中this.$set的用法_Stacey-TL的博客-优快云博客_vue中this.$set从三个方面给大家说一下这个this.$set:1.this.$set实现什么功能,为什么要用它?2.怎么用它?3.应用场景1.this.$set实现什么功能,为什么要用它?当你发现你给对象加了一个属性,在控制台能打印出来,但是却没有更新到视图上时,也许这个时候就需要用到this.$set()这个方法了,简单来说this.$set的功能就是解决这个问题的啦。官方解释:向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vuehttps://blog.youkuaiyun.com/qq_38687592/article/details/123477250

### 关于 `this.$set` 方法设置值后页面重新渲染的问题 当在 Vue 中使用 `this.$set` 更新数据时,如果发现视图未能及时响应变化并重新渲染,通常是因为某些特定情况下 Vue 的变更检测机制无法捕捉到这些更改。对于这个问题有几种解决方案。 #### 使用 `this.$forceUpdate()` 强制刷新组件 一种简单的方法是在调用了 `this.$set` 后立即执行 `this.$forceUpdate()` 来强制整个组件重新渲染[^1]: ```javascript // 假设我们有一个列表项需要添加标志位来控制输入框显示与否 let index = 0; // 这里应该是实际索引位置 this.$set(arr[index], 'flag', true); this.$forceUpdate(); // 执行此命令以确保界面同步更新 ``` 这种方法虽然有效但并推荐频繁使用,因为它会触发必要的重绘操作,影响性能。 #### 正确应用 `$set` 函数 另一个更优的方式是确保按照官方文档指导正确地运用 `this.$set` 或者其别名 `Vue.set` 。这涉及到理解为什么有时候直接修改对象属性会引起 UI 刷新——即由于 JavaScript ES5 局限性导致 Vue 无法追踪新增加的对象属性的变化[^3]。 因此,在向已有对象动态添加新字段之前应该总是通过 `this.$set` 完成这一过程: ```javascript // 如果 person 是一个存在于 data 上的对象,则可以这样安全地为其增加 sex 字段 this.$set(this.person, 'sex', 'male'); ``` 同样适用于处理多维数组的情况,只需指定确切路径即可[^4]: ```javascript for (var i = 0; i < ary.length; ++i){ for(var j=0;j<ary[i].length;++j){ this.$set(ary[i], j, newValue); } } ``` 以上两种方式都可以有效地解决因 `this.$set` 导致的数据变动未被反映至界面上的问题。建议优先考虑第二种做法,除非确实有必要才采用第一种全局性的刷新手段。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值