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 相关文章推荐
javascript div 遮罩层封锁整个页面
Jul 10 Javascript
javascript计时器事件使用详解
Jan 07 Javascript
JavaScript表单通过正则表达式验证电话号码
Mar 14 Javascript
Node.js刷新session过期时间的实现方法推荐
May 18 Javascript
js完整倒计时代码分享
Sep 18 Javascript
jQuery中的AjaxSubmit使用讲解
Sep 25 Javascript
浅谈javascript控制HTML5的全屏操控,浏览器兼容的问题
Oct 10 Javascript
B/S(Web)实时通讯解决方案分享
Apr 06 Javascript
node.JS md5加密中文与php结果不一致的解决方法
May 05 Javascript
JS+canvas绘制的动态机械表动画效果
Sep 12 Javascript
使用vue2.0创建的项目的步骤方法
Sep 25 Javascript
vue 给数组添加新对象并赋值
Apr 20 Vue.js
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
Thinkphp5.0框架使用模型Model的获取器、修改器、软删除数据操作示例
2019/10/11 PHP
JS代码格式化和语法着色V2
2006/10/14 Javascript
ExtJs GridPanel简单的增删改实现代码
2010/08/26 Javascript
js通过googleAIP翻译PHP系统的语言配置的实现代码
2011/10/17 Javascript
javascript简易缓动插件(源码打包)
2012/02/16 Javascript
Js 去掉字符串中的空格(实现代码)
2013/11/19 Javascript
基于jQuery实现复选框的全选 全不选 反选功能
2014/11/24 Javascript
基于jQuery通过jQuery.form.js插件实现异步上传
2015/12/13 Javascript
javascript实现倒计时跳转页面
2016/01/17 Javascript
利用React-router+Webpack快速构建react程序
2016/10/27 Javascript
浅谈html转义及防止javascript注入攻击的方法
2016/12/04 Javascript
Angular.js实现多个checkbox只能选择一个的方法示例
2017/02/24 Javascript
详解Vue 2.0封装axios笔记
2017/06/22 Javascript
微信小程序开发中的疑问解答汇总
2017/07/03 Javascript
jQuery实现根据身份证号获取生日、年龄、性别等信息的方法
2019/01/09 jQuery
Vue页面渲染中key的应用实例教程
2021/01/12 Vue.js
Python3基础之基本运算符概述
2014/08/13 Python
Python中用Decorator来简化元编程的教程
2015/04/13 Python
使用Python读写文本文件及编写简单的文本编辑器
2016/03/11 Python
Python实现简单的多任务mysql转xml的方法
2017/02/08 Python
Python3利用Dlib19.7实现摄像头人脸识别的方法
2018/05/11 Python
python 获取当天每个准点时间戳的实例
2018/05/22 Python
在PyCharm中三步完成PyPy解释器的配置的方法
2018/10/29 Python
python turtle 绘制太极图的实例
2019/12/18 Python
浅析CSS3 用text-overflow解决文字排版问题
2020/10/28 HTML / CSS
Ann Taylor官方网站:美国最大的女性产品制造商之一
2016/09/14 全球购物
马来西亚时装购物网站:ZALORA马来西亚
2017/03/14 全球购物
英国高级健康和美容产品零售商:Life and Looks
2019/08/01 全球购物
Marc O’Polo俄罗斯官方在线商店:德国高端时尚品牌
2019/12/26 全球购物
毕业生个人的求职信范文
2013/12/03 职场文书
本科毕业论文导师评语
2014/12/31 职场文书
悬空寺导游词
2015/02/05 职场文书
2015年毕业实习工作总结
2015/05/29 职场文书
三八妇女节新闻稿
2015/07/17 职场文书
生产车间管理制度
2015/08/04 职场文书
go web 预防跨站脚本的实现方式
2021/06/11 Golang