Home  >  Article  >  Web Front-end  >  How to make vue responsive

How to make vue responsive

WBOY
WBOYOriginal
2023-05-24 10:48:37831browse

Vue.js is a popular JavaScript framework that provides a convenient way to build interactive web applications. One of the most prominent features is reactive data binding. So how is Vue responsive data binding implemented? This article will delve into the implementation principles of Vue responsiveness.

  1. The core principle of Vue’s responsiveness

The core principle of Vue’s responsiveness is the dependency collection and observer pattern.

In Vue, each component instance has a corresponding watcher instance. When reactive data is used in a component, this watcher instance will automatically bind it to the corresponding data.

When the data changes, the watcher instance will automatically detect and trigger the component to re-render. Vue uses virtual DOM technology to optimize rendering and update component views efficiently.

So how does the Vue component know which data is responsive? This needs to rely on the collection mechanism to achieve.

  1. Implementation of dependency collection

Vue uses a class named Dep to implement dependency collection. Each reactive data (such as an object or array) has a corresponding Dep instance.

The Dep instance stores all watcher instances that depend on this responsive data. When the data changes, the Dep instance will notify all watcher instances that depend on it to perform update operations.

If responsive data is used in the component, the created hook function will be executed when the component is instantiated. In this function, Vue will collect dependencies where responsive data is used in the component.

Specifically, Vue uses Object.defineProperty() to implement responsive data. This function can hijack the properties of an object. When the properties are read or written, the get and set methods will be automatically triggered.

When the component is rendered, accessing the properties of the responsive data will trigger the get method. Vue collects dependencies in this method and adds the current watcher instance to the Dep instance of this responsive data. When the data changes, the Dep instance notifies the relevant watcher instance to perform an update operation.

The following is a simple example that demonstrates how to use Object.defineProperty() to implement responsive data.

function defineReactive(obj, key, val) {
  var dep = new Dep();

  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function() {
      dep.depend(); // 将当前watcher实例添加到Dep实例中
      return val;
    },
    set: function(newVal) {
      if (val === newVal) {
        return;
      }
      val = newVal;
      dep.notify(); // 通知所有watcher实例进行更新
    }
  });
}

function observe(obj) {
  if (!obj || typeof obj !== "object") {
    return;
  }

  Object.keys(obj).forEach(function(key) {
    defineReactive(obj, key, obj[key]);
  });
}

// 示例代码
var data = { name: "Bob", age: 18 };
observe(data);

// 在组件中使用
var vm = new Vue({
  data: data,
  created: function() {
    // 访问数据的属性会触发get方法,实现依赖收集
    console.log("My name is " + this.name + ", I'm " + this.age + " years old.");
  }
});

In this example, we define the defineReactive() function and observe() function, which are used to hijack object properties and traverse the object and hijack all properties respectively.

When we use responsive data in a component, vue will automatically collect dependencies and add the current watcher instance to the Dep instance of the responsive data. When the responsive data changes, the Dep instance will notify the relevant watcher instance to perform the update operation.

  1. Implementation of Observer Pattern

As mentioned before, each component instance has a corresponding watcher instance. This watcher instance will automatically perform update operations when any reactive data changes.

Vue uses the observer pattern to implement this mechanism. Specifically, Vue stores all watcher instances in the component in a class called Watcher. Each watcher instance can be used to monitor data changes and execute callback functions.

When the component is rendered, Vue will parse and compile the template in the component and generate a rendering function. This rendering function creates a watcher instance and passes the current component instance and rendering function to the watcher instance.

Whenever the responsive data changes, the Dep instance will notify all watcher instances that depend on it to perform update operations. The update operation includes executing the get method of the watcher instance to calculate the new component state, and then executing the callback function of the watcher instance to update the component view.

The following is a simple example that demonstrates how to use the Watcher class to monitor changes in data and execute callback functions.

function Watcher(vm, exp, cb) {
  this.vm = vm;
  this.exp = exp;
  this.cb = cb;
  this.value = this.get(); // 保存初始状态的值
}

Watcher.prototype = {
  constructor: Watcher,

  get: function() {
    Dep.target = this; // 将当前watcher实例设置到Dep类的静态属性中
    var value = this.vm[exp]; // 访问数据的属性,实现依赖收集
    Dep.target = null; // 重置Dep类的静态属性
    return value;
  },

  update: function() {
    var value = this.get();
    if (value !== this.value) { // 值发生变化时执行回调函数
      this.cb(value);
      this.value = value;
    }
  }
};

// Dep类
function Dep() {
  this.subs = [];
}

Dep.prototype = {
  constructor: Dep,

  addSub: function(sub) {
    this.subs.push(sub);
  },

  removeSub: function(sub) {
    var index = this.subs.indexOf(sub);
    if (index !== -1) {
      this.subs.splice(index, 1);
    }
  },

  depend: function() {
    if (Dep.target) {
      this.addSub(Dep.target); // 将当前watcher实例添加到依赖列表中
    }
  },

  notify: function() {
    this.subs.forEach(function(sub) {
      sub.update(); // 通知所有watcher实例进行更新操作
    });
  }
};

Dep.target = null; // 静态属性,用于保存当前watcher实例

// 示例代码
var vm = new Vue({
  data: { name: "Bob", age: 18 },
  created: function() {
    // 创建一个watcher实例,用于监听数据变化并执行回调函数
    new Watcher(this, "name", function(value) {
      console.log("My name is " + value);
    });
    new Watcher(this, "age", function(value) {
      console.log("I'm " + value + " years old.");
    });
  }
});

// 改变数据的值,会触发回调函数的执行
vm.name = "Alice";
vm.age = 20;

In this example, we define the Watcher class and Dep class to monitor data changes and notify all watcher instances for update operations.

When we use reactive data in a component, Vue will automatically create a watcher instance to listen for data changes and execute the callback function. Whenever the data changes, the watcher instances in the dependency list will automatically perform update operations.

  1. Summary

The implementation principle of responsive data in Vue is very complex, which involves multiple concepts and mechanisms such as dependency collection, observer mode, and virtual DOM. This article only briefly introduces some of them.

Because Vue automatically implements responsive binding of data, developers can directly use these data in components for programming. This greatly simplifies the difficulty of programming and improves development efficiency. At the same time, Vue's data-responsive system also provides us with the opportunity to deeply study and research front-end framework design.

The above is the detailed content of How to make vue responsive. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn