Vue2.0 $set()的正确使用详解


Posted in Javascript onJuly 28, 2020

vue2.0 给data对象新增属性,并触发视图更新

如下代码,给 student对象新增 age 属性

data () {
  return {
    student: {
      name: '',
      sex: ''
    }
  }
}

众所周知,直接给student赋值操作,虽然可以新增属性,但是不会触发视图更新

mounted () {
  this.student.age = 24
}

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

要处理这种情况,我们可以使用$set()方法,既可以新增属性,又可以触发视图更新。

但是,值得注意的是,网上一些资料写的$set()用法存在一些问题,导致在新接触这个方法的时候会走一些弯路!

错误写法:this.$set(key,value)(ps: 可能是vue1.0的写法)

mounted () {
  this.$set(this.student.age, 24)
}

正确写法:this.$set(this.data,”key”,value')

mounted () {
  this.$set(this.student,"age", 24)
}

补充知识:Vue 中 $set() 与 Vue.set() 原理及使用

1. 前言

问题: 在使用 vue 进行开发的过程中,可能会遇到一种情况:当生成vue实例后,再次给数据赋值时,有时候并不会自动更新到视图上去。也就是如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。

案例:

<template>
 <div class="home">
  <div v-for="(item,index) in items" :key="index">{{item}}</div>
 <button @click="btn()">修改</button>
 </div>
</template>

<script>
export default {
 name: 'Home',
 data(){
  return{
  items:[1, 2, 3]
   }
 },
 methods:{
 btn(){
     this.items[1] = 'two'
  console.log(this.items);
 }
  }
}
</script>

页面:

Vue2.0 $set()的正确使用详解

控制台:

Vue2.0 $set()的正确使用详解

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

因此: Vue 不能检测以下变动的数组:

当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue

当你修改数组的长度时,例如:vm.items.length = newLength

例如:使用 this.arr[0] 去更新 array 的内容,视图没有刷新

使用 Vue.set(this.arr, 0, !this.arr[0]) 去更新 array 的内容,视图被刷新

使用 this.arr[0] = !this.arr[0] 和 this.obj.a = !this.obj.a 同时更新,视图被刷新

结论:

如果方法里面单纯的更新数组 Array 的话,要使用 Vue.set();

如果方法里面同时有数组和对象的更新,直接操作 data 即可;

2. 原理

每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

Vue2.0 $set()的正确使用详解

受现代 JavaScript 的限制 (而且 Object.observe 也已经被废弃),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

3. $set() 与 Vue.set() 的使用

3.1 通过 Vue.set() 改写

语法:

Vue.set( target, propertyName/index, value )

参数:

{Object | Array} target

{string | number} propertyName/index

{any} value

返回值:设置的值。

用法:

向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。

它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = 'hi')

注意:

对象不能是 Vue 实例,或者 Vue 实例的根数据对象。

<template>
 <div class="home">
  <div v-for="(item,index) in items" :key="index">{{item}}</div>
  <button @click="btn()">修改</button>
 </div>
</template>

<script>
import Vue from 'vue' // 别忘了引入
export default {
 name: 'Home',
 data(){
  return{
  items:[1, 2, 3]
  }
 },
 methods:{
 btn(){
      Vue.set(this.items, 1, 'two')
  console.log(this.items);
 }
 }
}
</script>

3.2 通过 $set() 改写

语法:

vm.$set( target, propertyName/index, value )

参数:

{Object | Array} target

{string | number} propertyName/index

{any} value

返回值:设置的值。

用法:

这是全局 Vue.set 的别名。

参考:Vue.set

<template>
 <div class="home">
  <div v-for="(item,index) in items" :key="index">{{item}}</div>
 <button @click="btn()">修改</button>
 </div>
</template>

<script>
export default {
 name: 'Home',
 data(){
  return{
  items:[1, 2, 3]
   }
 },
 methods:{
 btn(){
    this.$set(this.items, 1, 'two')
  console.log(this.items);
 }
 }
}
</script>

页面:

Vue2.0 $set()的正确使用详解

控制台:

Vue2.0 $set()的正确使用详解

3.3 Vue.set() 和 this.$set() 的区别

Vue.set() 源码:

import { set } from '../observer/index'
...
Vue.set = set
...

this.$set() 源码

import { set } from '../observer/index'
...
Vue.prototype.$set = set
...

可以发现 Vue.set() 和 this.$set() 这两个 api 的实现原理基本一模一样,都是使用了set函数。

set 函数是从 …/observer/index 文件中导出的。

区别在于 Vue.set( ) 是将 set 函数绑定在 Vue 构造函数上,this.$set() 是将 set 函数绑定在 Vue原型上。

以上这篇Vue2.0 $set()的正确使用详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery学习笔记 操作jQuery对象 属性处理
Sep 19 Javascript
网页加载时页面显示进度条加载完成之后显示网页内容
Dec 23 Javascript
javascript学习(二)javascript常见问题总结
Jan 02 Javascript
jQuery过滤选择器:not()方法使用介绍
Apr 20 Javascript
window resize和scroll事件的基本优化思路
Apr 29 Javascript
JavaScript Ajax编程 应用篇
Jul 02 Javascript
PHP抓取HTTPS内容和错误处理的方法
Sep 30 Javascript
React组件之间的通信的实例代码
Jun 27 Javascript
vue 微信授权登录解决方案
Apr 10 Javascript
vue实现自定义H5视频播放器的方法步骤
Jul 01 Javascript
turn.js异步加载实现翻书效果
Jul 25 Javascript
JS轻量级函数式编程实现XDM二
Jun 16 Javascript
JavaScript 监听组合按键思路及代码实现
Jul 28 #Javascript
JavaScript动画实例之粒子文本的实现方法详解
Jul 28 #Javascript
Vue $emit()不能触发父组件方法的原因及解决
Jul 28 #Javascript
vue 遮罩层阻止默认滚动事件操作
Jul 28 #Javascript
JavaScript实现沿五角星形线摆动的小圆实例详解
Jul 28 #Javascript
处理JavaScript值为undefined的7个小技巧
Jul 28 #Javascript
vue中touch和click共存的解决方式
Jul 28 #Javascript
You might like
PHP中使用memcache存储session的三种配置方法
2014/04/05 PHP
PHP SESSION的增加、删除、修改、查看操作
2015/03/20 PHP
PHP实现的链式队列结构示例
2017/09/15 PHP
jQuery Deferred和Promise创建响应式应用程序详细介绍
2013/03/05 Javascript
jQuery中:checked选择器用法实例
2015/01/04 Javascript
javascript中setAttribute()函数使用方法及兼容性
2015/07/19 Javascript
node.js插件nodeclipse安装图文教程
2020/10/19 Javascript
JQuery的attr 与 val区别
2016/06/12 Javascript
AngularJs页面筛选标签小功能
2016/08/01 Javascript
jquery层级选择器(匹配父元素下的子元素实现代码)
2016/09/05 Javascript
简单理解vue中实例属性vm.$els
2016/12/01 Javascript
jQuery阻止移动端遮罩层后页面滚动
2017/03/15 Javascript
无限循环轮播图之运动框架(原生JS实现)
2017/10/01 Javascript
在小程序中集成redux/immutable/thunk第三方库的方法
2018/08/12 Javascript
Vue实现拖放排序功能的实例代码
2019/07/08 Javascript
vue 动态添加的路由页面刷新时失效的原因及解决方案
2021/02/26 Vue.js
Python计算程序运行时间的方法
2014/12/13 Python
在Ubuntu系统下安装使用Python的GUI工具wxPython
2016/02/18 Python
python实现汉诺塔算法
2021/03/01 Python
Django开发的简易留言板案例详解
2018/12/04 Python
对python中xlsx,csv以及json文件的相互转化方法详解
2018/12/25 Python
Python 日期区间处理 (本周本月上周上月...)
2019/08/08 Python
基于python实现生成指定大小txt文档
2020/07/20 Python
python正则表达式re.match()匹配多个字符方法的实现
2021/01/27 Python
解决Pycharm 运行后没有输出的问题
2021/02/05 Python
CSS3弹性伸缩布局之box布局
2016/07/12 HTML / CSS
css3 按钮 利用css3实现超酷下载按钮
2013/03/18 HTML / CSS
惠普美国官方商店:HP Official Store
2016/08/28 全球购物
NHL官方在线商店:Shop.NHL.com
2020/05/01 全球购物
财务情况说明书范文
2014/05/06 职场文书
授权委托书协议书
2014/10/16 职场文书
艺术节开幕词
2015/01/28 职场文书
2015年社区妇联工作总结
2015/04/21 职场文书
赢在执行观后感
2015/06/16 职场文书
2016圣诞节贺卡寄语
2015/12/07 职场文书
五年级作文之成长
2019/09/16 职场文书