添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

一、为什么需要使用Vue.set?

vue中不能检测到数组的一些变化,比如一下两种:

1、数组长度的变化 vm.arr.length = 100

2、数组通过索引值修改内容 vm.arr[1] = ‘aa’

那么为什么vue要做成这样,不去监听数组的变化,数组在日常中使用频率还是比较高的,这个问题其实尤大说过,是为了性能,假设我们新建了一个数组,长度是1000 但是只使用了前几个 ,去实现页面的响应式监听,从数组改变到页面输出一共需要遍历两遍数组,会增加性能消耗,这可能就是不去监听某一项数组数据变化的原因吧。
以下是vue observer的的源码,判断是数组了,会停止对数据属性的监测。
在这里插入图片描述
所以vue提供了Vue.set 方法弥补这些不足,Vue.set同vm.$set(target,key,value):可以动态的给数组、对象添加和修改数据,并更新视图中数据的显示。

vue在构造函数new Vue()时,就通过Object.defineProperty中的getter和setter 这两个方法,完成了对数据的绑定。所以直接通过vm.arr[1] = ‘aa’的方法,无法修改值去触发vue中视图的更新,必须还得通过Object.defineProperty的方法去改变,而Vue.set()就封装了js底层的Object.defineProperty方法。

所以我们需要利用Vue.set() 响应式新增与修改数据。

二、最近项目中使用到了树形表格,即多层嵌套的数据,类似于这样的页面展示。数据结构如下:

obj:[
          id:'1',
          type:'1',
          children:[
              id:'1-1',
              type:'1-1',

在这里插入图片描述
在每一层数据的数据量都比较大的时候,不能使用一次性加载所有数据,需要优化加载,点击table的expand,即@expand-change方法获取下一层数据,那么就需要给下一层数据增加children属性,那么我们肯定会想到一下几种方法:

  1. this.$set(this.obj[index],‘children’,[…res.items])
  2. this.obj[index].children = []
    this.obj[index].children.splice(0,0,…res.items) //或者push方法
    3.使用foreach方法,循环res.items使用 this.$set(this.obj[index].children,index,res.items[index])
    我使用了这几种方法,甚至是组合使用了,但是结果不是很好,数据是增加上了,但是并没有响应式的增加上,页面都没有展示出相应的数据,查看结构时,发现到第三层的时候,增加的children已经没有{ob:Observer},ob_: Observer是vue这个框架对数据设置的监控器,有这个属性,才能监听到数据的变化。
    找了很久都不可以。最终尝试了以下方法才得以解决:
//给第三层增加数据
this.$set(this.obj[level1Index].children[level2Index],'children',[])
//使用foreach 将数组的每一项添加为响应式数据
res.items.forEach((item,index)=>{
	this.obj[level1Index].children[level2Index]
	this.$set(this.obj[level1Index].children[level2Index].children,index,item)

首先先添加children数组为响应式,再去将数组中的每一项也添加为响应式,页面变可以正常显示啦 。

属性多层数组数据的添加修改一、为什么需要使用Vue.set?vue中不能检测到数组的一些变化,比如一下两种:1、数组长度的变化 vm.arr.length = 100  2、数组通过索引值修改内容 vm.arr[1] = ‘aa’那么为什么vue要做成这样,不去监听数组的变化,数组在日常中使用频率还是比较高的,这个问题其实尤大说过,是为了性能,假设我们新建了一个数组,长度是1000 但...
在解决问题之前,我们先来了解下 vue响应性原理: Vue最显著的一个功能是响应系统– 模型只是一个普通对象,修改对象则会更新视图。 受到javascript的限制,Vue不能检测到对象属性添加或删除,因为vue在初始化实列时将属性转为getter/setter,所以属性必须在data对象上才能让vue转换它。 但是vue可以使用 Vue.set(object, key, value)方法将响应属性添加到嵌套的对象上:如下代码: Vue.set(obj, '_isHover', true); 或者可以使用vm.$set的实列方法,也是Vue.set方法的别名: this.$set(o
回答: 在Vue中,可以使用Vue.set()或this.$set()来给data选项中的数组。根据官方文档的写法,可以使用以下方式来操作数组并让页面重新渲染:Vue.set(vueInstance.$data.arr, 0, 3)或this.$set(vueInstance.$data.arr, 0, 3)。\[1\]这两种方式都可以实现相同的效果。其中,target参数是要操作的数组,propertyName/index参数是要修改的元素的索引或属性名,value参数是要赋给该元素的新。\[2\]例如,如果要给data选项中的数组添加一个新的元素,可以使用以下代码:this.$set(this.person, "score", "60")。\[3\]这样就可以给对象添加一个属性并赋。 #### 引用[.reference_title] - *1* [Vue.set()和this.$set()](https://blog.csdn.net/weixin_42169395/article/details/122193230)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [vue中this.$set修改数组,数据改变视图层不更新](https://blog.csdn.net/qq_38951259/article/details/122249151)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [vue中this.$set()的用法----更新数组对象](https://blog.csdn.net/m0_67391521/article/details/123304430)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]