个人摄影网站制作,手机版网站开发实例,百度开户渠道商哪里找,南昌网站建设技术托管Vue.js 是一个渐进式的 JavaScript 框架#xff0c;其中最重要的一个特性就是响应式#xff08;Reactivity#xff09;。Vue 借助数据劫持#xff08;Data Observation#xff09;技术实现了对数据的响应式更新#xff0c;当数据发生变化时#xff0c;它会自动重新渲染视… Vue.js 是一个渐进式的 JavaScript 框架其中最重要的一个特性就是响应式Reactivity。Vue 借助数据劫持Data Observation技术实现了对数据的响应式更新当数据发生变化时它会自动重新渲染视图这使得构建复杂的用户界面变得更加容易。 在本文中我们将介绍 Vue.js 中的响应式原理和数据劫持机制让你了解 Vue.js 是如何通过监听数据变化来实现视图更新。 响应式原理
Vue.js 的响应式原理是基于数据驱动的它的核心是将数据和视图进行关联并且在数据发生变化时更新视图。Vue.js 通过数据劫持技术实现了响应式原理。
所谓数据劫持就是通过一些手段来劫持 JavaScript 对象的访问和修改以便在数据发生变化时能够自动更新视图。
Vue.js 中的响应式原理流程如下
1. Vue 组件中有一个 data 属性它是一个对象。
2. Vue 在初始化组件时会通过 Object.defineProperty() 方法将 data 中的所有属性都转化成 getter 和 setter。
3. 当访问或者修改这些属性时会触发对应的 getter 和 setter 方法。
4. 在 setter 方法中Vue 会通知相关的 Watcher一个观察者对象去更新视图。
5. 当组件中的 data 发生变化时会触发对应属性的 setter 方法然后通知相关的 Watcher 更新视图。
下面我们将详细介绍 Vue.js 中的数据劫持技术。
数据劫持
数据劫持是 Vue.js 实现响应式的核心技术之一它主要通过 Object.defineProperty() 方法来实现。Object.defineProperty() 方法是 JavaScript 原生提供的 API它可以用来定义对象上的属性。这个方法有三个参数
Object.defineProperty(obj, prop, descriptor) * obj要定义属性的对象。 * prop要定义或修改的属性的名称。 * descriptor要定义或修改的属性的描述符。 descriptor 是一个包含属性的特性的对象它具有以下几个属性 * configurable当且仅当该属性的 configurable 为 true 时该属性描述符才能够被改变同时该属性也能够被删除默认为 false。 * enumerable当且仅当该属性的 enumerable 为 true 时该属性才会出现在对象的枚举属性中默认为 false。 * value该属性对应的值默认为 undefined。 * writable当且仅当该属性的 writable 为 true 时该属性才能被赋值运算符改变默认为 false。 * get表示该属性的 getter 函数默认为 undefined。 * set表示该属性的 setter 函数默认为 undefined。 通过 Object.defineProperty() 方法可以给对象的属性设置 getter 和 setter。这样一来我们就可以在属性被访问或者修改时触发对应的 getter 和 setter 方法达到数据劫持的目的。
在 Vue.js 中当初始化组件时Vue.js 会对组件中所有的 data 属性使用 Object.defineProperty() 方法将其转化为 getter 和 setter。这样一来当组件中的 data 属性被访问或者修改时Vue.js 就能够捕获到这些操作并在内部执行相应的逻辑。这就实现了 Vue.js 中的响应式机制。
下面是一个简单的示例我们将使用 Object.defineProperty() 方法来实现一个响应式对象
var obj {};Object.defineProperty(obj, name, {get: function() {console.log(访问了属性 name);return this._name;},set: function(value) {console.log(修改了属性 name新值为 value);this._name value;}
});obj.name Vue.js;
console.log(obj.name);
在这个示例中我们使用 Object.defineProperty() 方法定义了一个对象 obj 的属性 name。在 getter 和 setter 中我们分别输出了访问和修改属性的操作并打印出了属性的值。当我们执行 obj.name Vue.js 时会触发 setter 方法并输出修改操作的信息。当我们访问 obj.name 时会触发 getter 方法并输出访问操作的信息。
响应式实现
在了解了数据劫持的原理之后我们来看看 Vue.js 是如何实现响应式的。
我们先来看一个简单的示例下面是一个 Vue 组件的代码
div idappp{{ message }}/p
/div
script
new Vue({el: #app,data: {message: Hello, Vue.js!}
});
/script
在这个组件中我们使用了 Vue.js 的数据绑定语法 {{ message }} 来显示 data 中的 message 属性。在初始化时Vue.js 会将组件中的 data 属性转化为 getter 和 setter代码如下
function defineReactive(obj, key, val) {Object.defineProperty(obj, key, {get: function() {console.log(访问了属性 key);return val;},set: function(newVal) {console.log(修改了属性 key 新值为 newVal);val newVal;}});
}function observe(obj) {if (!obj || typeof obj ! object) {return;}Object.keys(obj).forEach(function(key) {defineReactive(obj, key, obj[key]);});
}function Vue(options) {this._data options.data;observe(this._data);
}
在这个代码中我们定义了三个函数defineReactive()、observe() 和 Vue()。
* defineReactive()这个函数用来给对象添加 getter 和 setter实现数据劫持。
* observe()这个函数会递归遍历对象中的所有属性将其转化为 getter 和 setter。
* Vue()这个函数用来初始化 Vue 组件其中 options.data 属性就是我们要响应式的数据。
我们在 Vue() 函数中调用了 observe()将 data 属性转化为 getter 和 setter。在 defineReactive() 函数中我们调用了 Object.defineProperty() 方法将 data 中的每个属性都转化为 getter 和 setter。这样一来当我们访问或者修改组件中的 data 属性时就会触发相应的 getter 和 setter 方法打印出访问或者修改属性的信息。 我们来运行一下这个示例在控制台中可以查看到输出的信息 访问了属性 message Hello, Vue.js! 修改了属性 message新值为Hello, Vue.js! 访问了属性 message Hello, Vue.js! 在这个示例中我们成功地将组件中的 data 属性转化为了响应式的数据。当我们访问或者修改属性时都会触发对应的 getter 和 setter 方法并输出相应的信息。
数据更新
数据劫持的目的是为了在数据发生变化时能够自动更新视图。在 Vue.js 中当数据发生变化时会触发相应的 getter 和 setter 方法然后通知相关的 Watcher 更新视图。
Watcher 是 Vue.js 中核心的观察者对象它可以监听数据的变化当数据发生变化时会触发更新视图的操作。
当一个 Vue 组件被创建时会创建一个渲染 Watcher它会监听组件中的模板template和 data 数据。当组件中的 data 数据发生变化时渲染 Watcher 就会重新渲染组件。
当我们在组件中访问 data 数据时就会触发一次 getter 方法并将当前的 Watcher 添加到一个全局的栈中。这个栈叫做 Dep依赖它会保存当前的 Watcher 实例。
当 data 数据发生变化时会触发对应的 setter 方法并通知 Dep 中保存的所有 Watcher 实例进行更新操作。
在更新时渲染 Watcher 会先将组件的 VNode虚拟 DOM重新渲染然后再将新的 VNode 与旧的 VNode 进行比对找出需要更新的部分最后将差异更新到真实的 DOM 上。
总结
Vue.js 的响应式原理是基于数据驱动的它通过数据劫持技术实现了对数据的响应式更新。当数据发生变化时会自动重新渲染视图。
Vue.js 的数据劫持技术是通过 Object.defineProperty() 方法来实现的这个方法可以定义对象上的属性并给属性设置 getter 和 setter达到数据劫持的目的。
在 Vue.js 中当组件中的 data 数据发生变化时会触发对应的 setter 方法并通知相关的 Watcher 更新视图。
在更新视图时Vue.js 会先重新渲染 VNode然后进行差异比对更新差异部分到真实的 DOM 上。