preface

This article has participated in the third “topic writing” track of the Denver Creators Training Camp. For details, check out: Digg Project | Creators Training Camp third is ongoing, “write” to make a personal impact.

This article will guide you to understand the core principles of VUE’s data-driven, responsive, publish-subscribe and observer patterns and their basic implementation.

First, data-driven

Data-driven is one of the most unique features of Vue. In the development process, we only need to pay attention to the data itself, and do not need to care about how the data is rendered to the view. For example, when using jQuery to achieve page data modification, DOM manipulation is required to obtain the elements that need to change the data. The vUE data model is just a common JS object, and when we modify the data, the view will be updated, avoiding the tedious DOM operation, improve the development efficiency.

Second, the core principle of responsiveness

When you pass an ordinary JavaScript object into a Vue instance as the data option, Vue iterates through all of the object’s properties, And use Object.defineProperty to turn all of these properties into getters/setters. Object.defineproperty is a non-shim feature in ES5, which is why Vue does not support IE8 and earlier browsers.

The data responsive principle of 2.0

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, Initial-scale =1.0"> <title>test</title> </head> <body> <div id="app"> hello </div> <script> // simulate Vue data option let data  = { msg: {}, count: Function proxyData(data){// Convert attributes in data to setters/getters for vm Object.defineproperty (vm," MSG ",{// The Settings can be enumerated Enumerable: True, // different is configurable, and runs without any additional information. The control works without any additional information is different. Return data.msg}, // Set (newValue){console.log('set:', newValue); If (newValue === data.msg) return data.msg= newValue // Data changes, update the DOM value document.QuerySelector ('#app').textContent = data.msg  } }) }) } vm.msg = 'hello1' console.log(vm.msg); </script> </body> </html>Copy the code

Open the console of the page to see

The set method is triggered when vm. MSG = ‘hello1’ is executed, printing set: hello1. Log (vm. MSG) fires the get method, prints get: hello1, and finally prints the value of vm. MSG.

3.0 data responsiveness principle

Vue 3.0 uses proxies to listen directly on objects, not properties

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, Initial-scale =1.0"> <title>test</title> </head> <body> <div id="app"> hello </div> <script> // simulate Vue data option let data  = { msg: {}, count: Let vm = new Proxy(data,{get(target, key){console.log('get,key',key,target[key]); Return target[key]}, // Set (target, key,newValue) {console.log('set,key:', key,newValue); If (newValue === target[key]) return target[key]= newValue // Data changes, update the DOM value document.QuerySelector ('#app').textContent = target[key] } }) vm.msg = 'hello1' console.log(vm.msg); </script> </body> </html>Copy the code

The same console that opens the page can see that the set method is triggered when vm. MSG = ‘hello1’ is executed, printing set,key: MSG hello1. Console. log(vm. MSG) fires the get method, prints get,key MSG hello1, and finally prints the value of vm. MSG.

Publish and subscribe mode and observer mode

Publish and subscribe model

We can assume that, you are in a WeChat subscribed to a public, will you go to see a new article, published in the public, the author in the public, will notify you when a new article, then you are a subscriber, the public, the author is the publisher, the public, the platform is “signal center” $on $emit the principle

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, </title> </head> <body> <script> Class EventEmitter {constructor(){// {'type1': [fn1,fn2],'type2': [fn]} this.subs = Object.create(null) } $on (eventType, handler){ this.subs[eventType] = this.subs[eventType] || [] this.subs[eventType].push(handler) } $emit (eventType){ if(this.subs[eventType]){ this.subs[eventType].forEach(handler=>{ handler() }) } } } let em = new EventEmitter() em.$on('test',()=>{ console.log('test1'); }) em.$on('test',()=>{ console.log('test2'); }) em.$emit('test') </script> </body> </html>Copy the code

Observer model

  • Observer (subscriber) — Watcher
    • Update (): Exactly what to do when an event occurs
  • Target (publisher) — Dep
    • Subs array: Stores all observations
    • AddSub (): Adds observing
    • Notify (): When an event occurs, all observed update() methods are called

The implementation principle of observer pattern

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta  name="viewport" content="width=device-width, Constructor (){this.subs =[]} </title> </head> <body> addSub(watch){ if(watch && watch.update){ this.subs.push(watch) } } nofity(){ this.subs.forEach(watch=>{ watch.update() })}} // Subscriber - watch class Watcher {update(){console.log('hello'); }} let dep = new dep () let wat = new Watcher() dep.addSub(wat) dep.nofity() </script> </body> </ HTML >Copy the code

Observe the difference between a pattern and a publish/subscribe pattern

  • The observed pattern has specific target scheduling. For example, when an event is triggered, the Dep calls the observed method, so there is a dependency between the subscribers and publishers observing the pattern
  • The publish/subscribe pattern is invoked by a unified dispatch center, so publishers and subscribers do not need to know of each other’s existence

conclusion

This article is just a simple introduction to the VUE implementation of response type in some simple principles, suitable for the source code without understanding of the front-end beginners, beginners can make the source code of the underlying implementation of the basic understanding. My writing level is limited, if there are mistakes or deficiencies, but also hope to correct, thank you.