目录

Vue的响应式效果:

Vue的响应式原理:

数组元素单独修改页面不会响应式改变的原因:

Vue内置API:Vue.set():

Vue中的数组操作方法:

一些需要注意的点:

欢迎指正!


Vue的响应式效果:

我们知道,当Vue的实例对象中的data元素发生改变时,页面中用到该元素的地方会进行重新解析模板。即更改数据会影响页面的显示。但对 数组元素中的元素 通过数组下标的形式进行更改时,页面不会进行响应式变化。即:

    <div id="root"><button @click="changehobby">将第一个爱好改为打游戏</button><ul><li v-for="h in hobby">{{h}}</li></ul></div><script>new Vue({el: '#root',data: {hobby: ['吃饭', '睡觉', '打豆豆']},methods: {changehobby() {this.hobby[0] = '打游戏'}}})</script>

当按下按钮时,页面不会响应式地将 “吃饭” 改为 “打游戏”,但通过控制台我们可以发现,在hobby数组内部已经进行了修改。

但我们将该数组以对象的形式储存时会发现,页面又会正常进行响应式变化。

    <div id="root"><button @click="changehobby">将第一个爱好改为打游戏</button><ul><li v-for="h in hobby">{{h}}</li></ul></div><script>const vm = new Vue({el: '#root',data: {hobby: {h1: '吃饭',h2: '睡觉',h3: '打豆豆'}},methods: {changehobby() {this.hobby.h1 = '打游戏'}}})</script>

Vue的响应式原理:

通过控制台可知,进行vm._data === data 的判断结果为true,但显然初始化时 data 与vm._data 不相同。所以一定是Vue在进行数据处理时对data进行了操作。

        let data = {name: 'baciii',age: 20}console.log(data);let obs = new Obs(data);let vm = {};vm._data = data = obs;console.log(data);console.log(data === vm._data);function Obs(data) {Object.keys(data).forEach((e) => {Object.defineProperty(this, e, {get() {return data[e];},set(val) {console.log('The data has been modified');data[e] = val;}})})}

内部进行的操作大致如上述代码所述,Obs 是一个构造函数,很容易可以看出来 Obs 对原始数据 data 进行了一次数据代理,并在 data 的属性被修改时发出提示信息。

vm可以理解为Vue的实例化对象,在进行数据代理后,将其结果返回给 vm._data 与原数据 data. Vue还另外将数据中的每个属性单独添加到了自身的实例化对象中,并在数据被修改时进行响应式操作。

数组元素单独修改页面不会响应式改变的原因:

通过对Vue响应式原理的大致了解,我们知道了Vue主要是通过数据代理的 set() 方法让页面进行响应式改变的。所以我们用控制台找到该数组,便可以发现其中的端倪:

可以看到,数组 hobby 是带有get() set()方法的,但数组中的每一个元素是没有这两个方法的。

我们再找到同样写法的对象:

可以发现,对象中的每一个元素都是带有get()、set()方法的。这就可以解释为什么直接改变数组元素不会引起页面响应式变化而对象可以。

Vue内置API:Vue.set():

Vue中内置的API--Vue.set(target, PropertyName/index, value)可以给响应式元素添加/修改一个对象,并保证该对象也是响应式的。根据此原理,便可以直接改变数组中的元素并使改变后的元素仍然有响应式效果。

    changehobby() {Vue.set(this.hobby, 0, '打游戏');// this.hobby[0] = '打游戏';}

值得注意的是,Vue.set的对象不能是 Vue 实例本身,也不能直接给 data 直接添加属性,只能添加到 data 内的某个对象。

Vue 官网的原话为:Vue.set() 的对象不能是 Vue 实例,或者 Vue 实例的跟数据对象。

Vue中的数组操作方法:

通过查阅 Vue 官网可以发现,Vue 对以下七个能够直接改变数组本身的方法进行了包装(即与数组原型对象上的同名方法不一样),并让使用了这些方法的数组中的元素能够保持响应式效果。

所以,通过splice()方法对元素进行修改同样可以保持其响应式属性。

    changehobby() {this.hobby.splice(0, 1, '打游戏');// Vue.set(this.hobby, 0, '打游戏');// this.hobby[0] = '打游戏';}

一些需要注意的点:

若数组中的元素是对象的话,那么对象中的属性(不是对象本身!)可以直接更改,因为对象中的属性同样拥有 get()、set() 方法。

数组常用的方法如 filter() 等没有被 Vue 重新包装(因为没有直接改变数组的元素而是生成了一个新数组),但是可以直接将其新数组赋予原数组。因为数组本身是有 get()、set() 方法的,所以直接对数组本身进行改变也会保持其页面响应式属性。

欢迎指正!

Vue.js---响应式原理相关推荐

  1. Vue.js响应式原理

    Vue.js响应式原理 框架 浏览数:659 2017-9-20 关于Vue.js Vue.js是一款MVVM框架,上手快速简单易用,通过响应式在修改数据的时候更新视图.Vue.js的响应式原理依赖于 ...

  2. vue.js响应式原理解析与实现

    从很久之前就已经接触过了angularjs了,当时就已经了解到,angularjs是通过脏检查来实现数据监测以及页面更新渲染.之后,再接触了vue.js,当时也一度很好奇vue.js是如何监测数据更新 ...

  3. Vue.js 响应式原理

    文章目录 Vue 数据响应式原理 `Object.defineProperty()` 数据响应式原理 `Proxy` 相关设计模式 观察者模式 发布-订阅模式 Vue 响应式原理模拟 Vue 类 Ob ...

  4. 从 JavaScript 属性描述器剖析 Vue.js 响应式视图

    学习每一门语言,一般都是从其数据结构开始,JavaScript也是一样,而JavaScript的数据结构中对象(Object)是最基础也是使用最频繁的概念和语法,坊间有言,JavaScript中,一切 ...

  5. 从JavaScript属性描述器剖析Vue.js响应式视图

    学习每一门语言,一般都是从其数据结构开始,JavaScript也是一样,而JavaScript的数据结构中对象(Object)是最基础也是使用最频繁的概念和语法,坊间有言,JavaScript中,一切 ...

  6. Vue 的响应式原理

    数据发生改变,界面跟着更新,如图所示: <!DOCTYPE html> <html lang="en"> <head><meta char ...

  7. 彻底理解Vue数据响应式原理

    彻底理解Vue数据响应式原理 当创建了一个实例后,通过将数据传入实例的data属性中,会将数据进行劫持,实现响应式,也就是说当这些数据发生变化时,对应的视图也会发生改变. const data = { ...

  8. 深入了解Vue 2响应式原理,并手写一个简单的Vue

    1. Vue 2的响应式原理 Vue.js 一个核心思想是数据驱动.所谓数据驱动是指视图是由数据驱动生成的,对视图的修改,不会直接操作 DOM,而是通过修改数据.vue.js里面只需要改变数据,Vue ...

  9. 通过Proxy和Reflect实现vue的响应式原理

    vue3通过Proxy+Reflect实现响应式,vue2通过defineProperty来实现 Proxy Proxy是什么 Proxy是ES6中增加的类,表示代理. 如果我们想要监听对象的操作过程 ...

  10. vue 获取响应头里set-cookie的值_最简化 VUE的响应式原理

    前言 前端目前两个当家花旦框架 VUE React,它们能够流行开来,响应式原理做出了巨大贡献.毕竟,它通过数据的变更就能够更新相应的视图,极大的将我们从繁琐的DOM操作中解放出来. 所以掌握它们的响 ...

最新文章

  1. Matlab实现连通域标记算法求图像连通域
  2. 下载python后怎样打开-下载python后如何启动
  3. python单例类命名_单例模式(java/python/c++)
  4. Docker的网络模式和跨主机通信
  5. [CXF REST标准实战系列] 一、JAXB xml与javaBean的转换(转)
  6. javaweb学习总结(十)——HttpServletRequest对象(一)(转)
  7. IBASE write buffer
  8. 探索未知种族之osg类生物---呼吸分解之更新循环一
  9. 简要分析unity3d中剪不断理还乱的yield
  10. 当前时间加30分钟_男性早晨坚持慢跑30分钟,一段时间后,或许这些变化不请自来...
  11. [转载] python怎么将十进制转换为二进制_python十进制和二进制的转换方法(含浮点数)
  12. 关于U盘被写保护无法格式化的解决方法
  13. 恶意软件相似度检测过程
  14. Python经典书籍推荐
  15. Linux高清壁纸软件,十个小众的 Linux 桌面软件
  16. Auto.jsMIUI小米手机锁屏界面无法上滑输入密码解锁的问题 以及如何输入密码进行解锁
  17. 关于电梯运行逻辑原理的思路分析
  18. excel小写转大写公式_Excel办公技巧:快速将单元格中小写字母全部转换为大写字母...
  19. 解决 “ISO C++ 不允许比较指针和整数的值 “
  20. 小红书主页爬取_小红书数据爬取教程

热门文章

  1. 介绍3种ssh远程连接的方式
  2. 安卓设置均衡器 Equalizer
  3. 什么是客户端容器化?
  4. SAP 未计划交货费-MIRO发票校验
  5. 模拟IC设计——简单放大器的直流仿真
  6. 联想微型计算机开机密码忘记了,联想笔记本忘记开机密码怎么办
  7. 如何确认软件测试结束
  8. 新版Chrome自动禁用第三方插件的解决办法[转]
  9. Python之pandas库--基础
  10. 请使用netty框架实现高效稳定的websocket通信