谈谈对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 相关文章推荐
jquery form表单提交插件asp.net后台中文解码
Jun 12 Javascript
JS 实现Json查询的方法实例
Apr 12 Javascript
JSON.stringify转换JSON时日期时间不准确的解决方法
Aug 08 Javascript
JS实现一个列表中包含上移下移删除等功能
Sep 24 Javascript
jQuery $命名冲突解决方案汇总
Nov 13 Javascript
AngularJS服务service用法总结
Dec 13 Javascript
jquery插件treegrid树状表格的使用方法详解(.Net平台)
Jan 03 Javascript
vue拦截器实现统一token,并兼容IE9验证功能
Apr 26 Javascript
微信小程序实现跑马灯效果
Oct 21 Javascript
vue微信分享出来的链接点开是首页问题的解决方法
Nov 28 Javascript
vscode中eslint插件的配置(prettier配置无效)
Sep 10 Javascript
vue-property-decorator用法详解
Dec 12 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
咖啡的传说和历史
2021/03/03 新手入门
php解析xml提示Invalid byte 1 of 1-byte UTF-8 sequence错误的处理方法
2013/11/14 PHP
适用于抽奖程序、随机广告的PHP概率算法实例
2014/04/09 PHP
CodeIgniter采用config控制的多语言实现根据浏览器语言自动转换功能
2014/07/18 PHP
JavaScript 面向对象的之私有成员和公开成员
2010/05/04 Javascript
在JavaScript中操作时间之getMonth()方法的使用
2015/06/10 Javascript
js文本框走动跑马灯效果代码分享
2015/08/25 Javascript
基于javascript实现全国省市二级联动下拉选择菜单
2016/01/28 Javascript
js纯数字逐一停止显示效果的实现代码
2016/03/16 Javascript
基于JS实现EOS隐藏错误提示层代码
2016/04/25 Javascript
js弹出窗口简单实现代码
2017/03/22 Javascript
vue动态生成dom并且自动绑定事件
2017/04/19 Javascript
JS按条件 serialize() 对应标签的使用方法
2017/07/24 Javascript
Node.js笔记之process模块解读
2018/05/31 Javascript
React-router4路由监听的实现
2018/08/07 Javascript
学习使用ExpressJS 4.0中的新Router的用法
2018/11/06 Javascript
小程序测试后台服务的方法(ngrok)
2019/03/08 Javascript
vue-cli脚手架打包静态资源请求出错的原因与解决
2019/06/06 Javascript
Centos7 安装Node.js10以上版本的方法步骤
2019/10/15 Javascript
JS操作字符串转数字的常见方法示例
2019/10/29 Javascript
js实现滚动条自动滚动
2020/12/13 Javascript
K-近邻算法的python实现代码分享
2017/12/09 Python
Python实现Pig Latin小游戏实例代码
2018/02/02 Python
解决Python pandas df 写入excel 出现的问题
2018/07/04 Python
tensorflow使用CNN分析mnist手写体数字数据集
2020/06/17 Python
html5使用canvas画空心圆与实心圆
2014/12/15 HTML / CSS
Kent & Curwen:与大卫·贝克汉姆合作
2017/06/13 全球购物
Annoushka英国官网:英国奢侈珠宝品牌
2018/10/20 全球购物
澳大利亚巧克力花束和礼品网站:Tastebuds
2019/03/15 全球购物
Invicta手表官方商店:百年制表历史的瑞士腕表品牌
2019/09/26 全球购物
物业电工岗位职责
2013/11/20 职场文书
总会计师岗位职责
2014/02/19 职场文书
2014年护士长工作总结
2014/11/11 职场文书
2014年幼儿园德育工作总结
2014/12/17 职场文书
个性与发展自我评价
2015/03/06 职场文书
使用Golang的channel交叉打印两个数组的操作
2021/04/29 Golang