Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。这使得状态管理非常简单直接

如何追踪变化

当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setterObject.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。

这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。这里需要注意的是不同浏览器在控制台打印数据对象时对 getter/setter 的格式化并不同,所以建议安装 vue-devtools 来获取对检查数据更加友好的用户界面。

每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
let oldArrPrototype = Array.prototype;
// 继承
let proto = Object.create(oldArrPrototype);
['push', 'shift', 'unshift','splice'].forEach(method => {
proto[method] = function() {
// 切片编程
// 更新视图
updateView();
oldArrPrototype[method].call(this, ...arguments)
}
}) // 观察函数
function observer(target) {
if (typeof target !== 'object' || target === null) {
return target;
}
if (Array.isArray(target)) {
target.__proto__ = proto;
// target.constructor.prototype = proto;
}
for (let key in target) {
/*
target:对象本身
key:对象的属性
target[key]:对象的值
*/
definedReactive(target, key, target[key])
}
} // defineProperty函数
function definedReactive(target, key, value) {
// 重新观察一下传过来的值
observer(value); //递归
Object.defineProperty(target, key, {
// get 读取属性值触发
get() {
return value;
},
// 修改属性值触发,默认有参数,是最新值
set(newValue) {
// 为了方式更改后的值也是对象
observer(newValue);
// 判断新值和旧值是否相同
// 如果不同,改变旧值,更新视图
if (newValue !== value) {
value = newValue;
updateView(value);
} else {
return newValue;
}
}
})
} // 更新视图方法
function updateView(value) {
console.log("更新视图" + value)
}
// 使用Object.defineProperty可以给属性重新定义属性,给属性增加getter,setter
// 这样给属性增加或者读取属性是都会触发getter 或者 setter
let data = {
name: "oldValue",
onj: {
name: "szx"
},
a: null,
n:[1,2,3]
}
// 定义一个观察函数,只要数据发生变动会触发更新视图的方法
observer(data) // data.name = "newValue" // data.a = {
// name: "100"
// },
// data.a.name = 200
data.n.splice(0)
console.log(data) // 如果属性不存在,即没有事先在data里面定义,赋值不存在的属性值的时候不会触发更新
</script>
</body>
</html>

VUE响应式原理-如何追踪变化的更多相关文章

  1. 详解Vue响应式原理

    摘要: 搞懂Vue响应式原理! 作者:浪里行舟 原文:深入浅出Vue响应式原理 Fundebug经授权转载,版权归原作者所有. 前言 Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是 ...

  2. 深入Vue响应式原理

    深入Vue.js响应式原理 一.创建一个Vue应用 new Vue({ data() { return { name: 'yjh', }; }, router, store, render: h =& ...

  3. 深度解析 Vue 响应式原理

    深度解析 Vue 响应式原理 该文章内容节选自团队的开源项目 InterviewMap.项目目前内容包含了 JS.网络.浏览器相关.性能优化.安全.框架.Git.数据结构.算法等内容,无论是基础还是进 ...

  4. Vue源码--解读vue响应式原理

    原文链接:https://geniuspeng.github.io/2018/01/05/vue-reactivity/ Vue的官方说明里有深入响应式原理这一节.在此官方也提到过: 当你把一个普通的 ...

  5. 深入解析vue响应式原理

    摘要:本文主要通过结合vue官方文档及源码,对vue响应式原理进行深入分析. 1.定义 作为vue最独特的特性,响应式可以说是vue的灵魂了,表面上看就是数据发生变化后,对应的界面会重新渲染,那么响应 ...

  6. vue响应式原理,去掉优化,只看核心

    Vue响应式原理 作为写业务的码农,几乎不必知道原理.但是当你去找工作的时候,可是需要造原子弹的,什么都得知道一些才行.所以找工作之前可以先复习下,只要是关于vue的,必定会问响应式原理. 核心: / ...

  7. vue响应式原理解析

    # Vue响应式原理解析 首先定义了四个核心的js文件 - 1. observer.js 观察者函数,用来设置data的get和set函数,并且把watcher存放在dep中 - 2. watcher ...

  8. 浅析Vue响应式原理(三)

    Vue响应式原理之defineReactive defineReactive 不论如何,最终响应式数据都要通过defineReactive来实现,实际要借助ES5新增的Object.definePro ...

  9. 浅谈vue响应式原理及发布订阅模式和观察者模式

    一.Vue响应式原理 首先要了解几个概念: 数据响应式:数据模型仅仅是普通的Javascript对象,而我们修改数据时,视图会进行更新,避免了繁琐的DOM操作,提高开发效率. 双向绑定:数据改变,视图 ...

随机推荐

  1. Promise核心基础

    基础 Promise 抽象表达:是js中进行异步编程的新的解决方案 具体解释:1.从语法上来说是一个构造函数 2.从功能上来说promise对象用来封装一个异步操作并可以获取其结果 状态改变:0.ne ...

  2. bzoj 题目选做

    这里将记录着我在接下来的日子里在bzoj上遇到的各种 毒瘤题目 1.轮状病毒 题目是很没意思的 列出状态 显然无法递推 我简单推了一下加动态加点的状态 嗯发现规律没有那么简单 打表 也不太能发现吧 正 ...

  3. Android menu菜单的深入了解。。。

    今天补充刚开始的菜单控件,这是基于: https://www.cnblogs.com/aolong/p/12868015.html 里面的菜单写的. 今天学的后面部分是结合昨天的Fragment一起的 ...

  4. MyFirstJavaWeb

    源代码: Register.jsp <%@ page language="java" contentType="text/html; charset=utf-8&q ...

  5. 文件上传Upload 漏洞挖掘思路

    1:尽可能多的找出网站存在的上传点2:尝试使用如上各种绕过方法3:尝试 geshell4:无法上传webshel的情况下: 尝试上传html等,或可造成存储XSS漏洞 上传点构造XSS等,结合上传后的 ...

  6. 字节跳动:[编程题]万万没想到之聪明的编辑 Java

    时间限制:1秒 空间限制:32768K 我叫王大锤,是一家出版社的编辑.我负责校对投稿来的英文稿件,这份工作非常烦人,因为每天都要去修正无数的拼写错误.但是,优秀的人总能在平凡的工作中发现真理.我发现 ...

  7. Python 3.x pip安装报错ERROR: No matching distribution found for PIL

    安装完成即可解决无法引入PIL的问题.

  8. Mybatis如何在插入(ID是后台生成的)后返回ID?

    获得ID方法:

  9. 计算itable的大小

    在ClassFileParser::parseClassFile()函数中计算vtable和itable所需要的大小,之前已经介绍过vtable大小的计算,这一篇将详细介绍itable大小的计算过程. ...

  10. 前端 go.js 流程图基于vue开发项目案例

    一.流程图效果 最近一段时间在研究go.js,它是一款前端开发画流程图的一个插件,也是一个难点,要说为什么是难点,首先,它是依赖画布canvas知识开发.其次,要依赖于内部API开发需求,开发项目需求 ...