谈谈对vue响应式数据更新的误解


Posted in Javascript onAugust 01, 2017

对于刚接触vue的同学会经常遇到数据更新了但是模板没有更新的问题,下面将结合vue的响应式特性以及异步更新机制分析常见的错误:

异步更新带来的数据响应式误解

异步数据的处理基本是一定会遇到的,处理不好就会遇到数据不更新的问题,但有一种情况是在未正确处理的情况下也能正常更新,这就会造成一种误解,详情如下所示:

模板

<div id="app">
    <h2>{{dataObj.text}}</h2>
</div>

js

new Vue({
      el: '#app',
      data: {
        dataObj: {}
      },
      ready: function () {
        var self = this;

        /**
         * 异步请求模拟
         */
        setTimeout(function () {
          self.dataObj = {}; 
          self.dataObj['text'] = 'new text';
        }, 3000);
      }
    })

上面的代码非常简单,我们都知道vue中在data里面声明的数据才具有响应式的特性,所以我们一开始在data中声明了一个dataObj空对象,然后在异步请求中执行了两行代码,如下:

self.dataObj = {}; 
self.dataObj['text'] = 'new text';

首先清空原始数据,然后添加一个text属性并赋值。到这里为止一切都如我们所想的,数据和模板都更新了。

那么问题来了,dataObj.text具有响应式的特性吗?

模板更新了,应该具有响应式特性,如果这么想那么你就已经走入了误区,一开始我们并没有在data中声明.text属性,所以该属性是不具有响应式的特性的。

但模板切切实实已经更新了,这又是怎么回事呢?

那是因为vue的dom更新是异步的,即当setter操作发生后,指令并不会立马更新,指令的更新操作会有一个延迟,当指令更新真正执行的时候,此时.text属性已经赋值,所以指令更新模板时得到的是新值。

具体流程如下所示:

  1. self.dataObj = {};发生setter操作
  2. vue监测到setter操作,通知相关指令执行更新操作
  3. self.dataObj['text'] = 'new text';赋值语句
  4. 指令更新开始执行

所以真正的触发更新操作是self.dataObj = {};这一句引起的,所以单看上述例子,具有响应式特性的数据只有dataObj这一层,它的子属性是不具备的。

对比示例:

模板

<div id="app">
    <h2>{{dataObj&&dataObj.text}}</h2>
</div>

js

new Vue({
      el: '#app',
      data: {
        dataObj: {}
      },
      ready: function () {
        var self = this;

        /**
         * 异步请求模拟
         */
        setTimeout(function () {
          self.dataObj['text'] = 'new text';
        }, 3000);
      }
    })

上述例子的模板是不会更新的。

Vue.$set

通过$set方法可以将添加一个具备响应式特性的属性,并且其子属性也具备响应式特性,但是必须是新属性才可以,如果是本身已有的属性该方法是不起作用的。

new Vue({
      el: '#app',
      data: {
        dataObj: {}
      },
      ready: function () {
        var self = this;

        /**
         * 异步请求模拟
         */
        setTimeout(function () {
          var data = {
            name: 'xiaofu',
            age: 18
          };
          var data01 = {
            name: 'yangxiaofu',
            age: 19
          };
          self.dataObj['person'] = {};
          self.$set('dataObj.info', data);
          self.$set('dataObj.person', data01); 
        }, 3000);
      }
    })

如上所示, .person属性是不具备响应式特性的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Android中资源文件(非代码部分)的使用概览
Dec 18 Javascript
jQuery不间断滚动效果(模拟百度新闻支持文字/图片/垂直滚动)
Feb 05 Javascript
Javascript Web Slider 焦点图示例源码
Oct 10 Javascript
jquery实现预览提交的表单代码分享
May 21 Javascript
用JS中split方法实现彩色文字背景效果实例
Aug 24 Javascript
简单谈谈ES6的六个小特性
Nov 18 Javascript
node.js 和HTML5开发本地桌面应用程序
Dec 13 Javascript
JavaScript解析JSON格式数据的方法示例
Jan 24 Javascript
webpack 2的react开发配置实例代码
Jul 28 Javascript
打造通用的匀速运动框架(实例讲解)
Oct 17 Javascript
使用JQuery实现图片轮播效果的实例(推荐)
Oct 24 jQuery
React diff算法的实现示例
Apr 20 Javascript
详解jquery选择器的原理
Aug 01 #jQuery
浅谈node中的exports与module.exports的关系
Aug 01 #Javascript
Vue2.0 组件传值通讯的示例代码
Aug 01 #Javascript
谈谈VUE种methods watch和compute的区别和联系
Aug 01 #Javascript
Angular4学习笔记之实现绑定和分包
Aug 01 #Javascript
详解js静态资源文件请求的处理
Aug 01 #Javascript
Angular4学习笔记之准备和环境搭建项目
Aug 01 #Javascript
You might like
Terran兵种介绍
2020/03/14 星际争霸
文件系统基本操作类
2006/11/23 PHP
php类
2006/11/27 PHP
PHP实现数字补零功能的2个函数介绍
2014/05/12 PHP
PHP session文件独占锁引起阻塞问题解决方法
2015/05/12 PHP
PHP生成唯一订单号
2015/07/05 PHP
php类的定义与继承用法实例
2015/07/07 PHP
CI框架(CodeIgniter)实现的导入、导出数据操作示例
2018/05/24 PHP
关于laravel5.5的定时任务详解(demo)
2019/10/23 PHP
Thinkphp5+Redis实现商品秒杀代码实例讲解
2020/12/29 PHP
jquery中dom操作和事件的实例学习 下拉框应用
2011/12/01 Javascript
javascript控制swfObject应用介绍
2012/11/29 Javascript
jQuery 事件的命名空间简单了解
2013/11/22 Javascript
javascript根据像素点取位置示例
2014/01/27 Javascript
表单序列化与jq中的serialize使用示例
2014/02/21 Javascript
js实现动画特效的文字链接鼠标悬停提示的方法
2015/03/02 Javascript
JavaSacript中charCodeAt()方法的使用详解
2015/06/05 Javascript
jQuery绑定事件的几种实现方式
2016/05/09 Javascript
纯JS焦点图特效实例(可一个页面多用)
2016/12/07 Javascript
JavaScript中三种常见的排序方法
2017/02/24 Javascript
vue省市区三联动下拉选择组件的实现
2017/04/28 Javascript
详解Node中导入模块require和import的区别
2017/08/11 Javascript
webpack将js打包后的map文件详解
2018/02/22 Javascript
vue通过点击事件读取音频文件的方法
2018/05/30 Javascript
小程序:授权、登录、session_key、unionId的详解
2019/05/15 Javascript
[01:19:34]2014 DOTA2国际邀请赛中国区预选赛 New Element VS Dream time
2014/05/22 DOTA
Python中操作符重载用法分析
2016/04/29 Python
用python实现的线程池实例代码
2018/01/06 Python
Python设计模式之工厂模式简单示例
2018/01/09 Python
Python Tkinter模块 GUI 可视化实例
2019/11/20 Python
python基于celery实现异步任务周期任务定时任务
2019/12/30 Python
pyspark 随机森林的实现
2020/04/24 Python
浅谈HTML5 defer和async的区别
2016/06/07 HTML / CSS
zooplus德国:便宜地订购动物用品、动物饲料、动物食品
2020/05/06 全球购物
如何从一个文件档案的尾端新增记录
2016/12/02 面试题
大专生自我评价
2014/01/28 职场文书