Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the use of Vue2 responsive system

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)05/31 Report--

这篇文章主要讲解了"Vue2响应式系统有什么用",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Vue2响应式系统有什么用"吧!

一、响应式系统要干什么

回到最简单的代码:

data = { text: 'hello, world'}const updateComponent = () => { console.log('收到', data.text);}updateComponent()data.text = 'hello, liang'// 运行结果// 收到 hello, world

响应式系统要做的事情:某个依赖了 数据的函数,当所依赖的 数据改变的时候,该函数要重新执行。datadata

我们期望的效果:当上边 修改的时候, 函数再执行一次。data.textupdateComponent

为了实现响应式系统,我们需要做两件事情:

知道 中的数据被哪些函数依赖data

data中的数据改变的时候去调用依赖它的函数们

为了实现第 点,我们需要在执行函数的时候,将当前函数保存起来,然后在读取数据的时候将该函数保存到当前数据中。1

第 点就迎刃而解了,当修改数据的时候将保存起来的函数执行一次即可。2

在读取数据和修改数据的时候需要做额外的事情,我们可以通过 重写对象属性的 和 函数。Object.defineProperty()getset

二、响应式数据

我们来写一个函数,重写属性的 和 函数。getset

/** * Define a reactive property on an Object. */export function defineReactive(obj, key, val) { const property = Object.getOwnPropertyDescriptor(obj, key); // 读取用户可能自己定义了的 get、set const getter = property && property.get; const setter = property && property.set; // val 没有传进来话进行手动赋值 if ((!getter || setter) && arguments.length === 2) { val = obj[key]; } Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter() { const value = getter ? getter.call(obj) : val; /*********************************************/ // 1.这里需要去保存当前在执行的函数 /*********************************************/ return value; }, set: function reactiveSetter(newVal) { const value = getter ? getter.call(obj) : val; if (setter) { setter.call(obj, newVal); } else { val = newVal; } /*********************************************/ // 2.将依赖当前数据依赖的函数执行 /*********************************************/ }, });}

为了调用更方便,我们把第 步和第 步的操作封装一个 类。12Dep

export default class Dep { static target; //当前在执行的函数 subs; // 依赖的函数 constructor() { this.subs = []; // 保存所有需要执行的函数 } addSub(sub) { this.subs.push(sub); } depend() { // 触发 get 的时候走到这里 if (Dep.target) { // 委托给 Dep.target 去调用 addSub Dep.target.addDep(this); } } notify() { for (let i = 0, l = this.subs.length; i

< l; i++) { this.subs[i].update(); } }}Dep.target = null; // 静态变量,全局唯一 我们将当前执行的函数保存到 类的 变量上。Deptarget 三、保存当前正在执行的函数 为了保存当前的函数,我们还需要写一个 类,将需要执行的函数传入,保存到 类中的 属性中,然后交由 类负责执行。WatcherWatchergetterWatcher 这样在 类中, 中保存的就不是当前函数了,而是持有当前函数的 对象。DepsubsWatcher import Dep from "./dep";export default class Watcher { constructor(Fn) { this.getter = Fn; this.get(); } /** * Evaluate the getter, and re-collect dependencies. */ get() { Dep.target = this; // 保存包装了当前正在执行的函数的 Watcher let value; try { // 调用当前传进来的函数,触发对象属性的 get value = this.getter.call(); } catch (e) { throw e; } return value; } /** * Add a dependency to this directive. */ addDep(dep) { // 触发 get 后会走到这里,收集当前依赖 // 当前正在执行的函数的 Watcher 保存到 dep 中的 subs 中 dep.addSub(this); } /** * Subscriber interface. * Will be called when a dependency changes. */ // 修改对象属性值的时候触发 set,走到这里 update() { this.run(); } /** * Scheduler job interface. * Will be called by the scheduler. */ run() { this.get(); }} Watcher 的作用就是将正在执行的函数通过 包装后保存到 中,然后调用传进来的函数,此时触发对象属性的 函数,会收集当前 。WatcherDep.targetgetWatcher 如果未来修改对象属性的值,会触发对象属性的 ,接着就会调用之前收集到的 对象,通过 对象的 方法,来调用最初执行的函数。setWatcherWatcheruptate 四、响应式数据 回到我们之前没写完的 函数,按照上边的思路,我们来补全一下。defineReactive import Dep from "./dep";/** * Define a reactive property on an Object. */export function defineReactive(obj, key, val) { const property = Object.getOwnPropertyDescriptor(obj, key); // 读取用户可能自己定义了的 get、set const getter = property && property.get; const setter = property && property.set; // val 没有传进来话进行手动赋值 if ((!getter || setter) && arguments.length === 2) { val = obj[key]; } /*********************************************/ const dep = new Dep(); // 持有一个 Dep 对象,用来保存所有依赖于该变量的 Watcher /*********************************************/ Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter() { const value = getter ? getter.call(obj) : val; /*********************************************/ // 1.这里需要去保存当前在执行的函数 if (Dep.target) { dep.depend(); } /*********************************************/ return value; }, set: function reactiveSetter(newVal) { const value = getter ? getter.call(obj) : val; if (setter) { setter.call(obj, newVal); } else { val = newVal; } /*********************************************/ // 2.将依赖当前数据依赖的函数执行 dep.notify(); /*********************************************/ }, });}五、Observer 对象 我们再写一个 方法,把对象的全部属性都变成响应式的。Observer export class Observer { constructor(value) { this.walk(value); } /** * 遍历对象所有的属性,调用 defineReactive * 拦截对象属性的 get 和 set 方法 */ walk(obj) { const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { defineReactive(obj, keys[i]); } }} 我们提供一个 方法来负责创建 对象。observeObserver export function observe(value) { let ob = new Observer(value); return ob;}六、测试 将上边的方法引入到文章最开头的例子,来执行一下: import { observe } from "./reactive";import Watcher from "./watcher";const data = { text: "hello, world",};// 将数据变成响应式的observe(data);const updateComponent = () =>

{ console.log("Received", data.text);};//current function executed by Watcher new Watcher(updateComponent);data.text = "hello, liang";

This will be done twice.

Copy that. Hello, world.

Copy that. hello, liang.

Our responsive system worked.

Thank you for reading, the above is the content of "Vue2 responsive system has what to use", after the study of this article, I believe everyone has a deeper understanding of Vue2 responsive system has what to use this problem, the specific use situation still needs to be verified by practice. Here is, Xiaobian will push more articles related to knowledge points for everyone, welcome to pay attention!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report