1

TNTWeb-the full name of Tencent News front-end team, the small partners in the group have practiced and accumulated in the front-end fields such as Web front-end, NodeJS development, UI design, and mobile APP.

At present, the team mainly supports the front-end development of Tencent News's various businesses. In addition to business development, it has also accumulated some front-end infrastructure to empower business efficiency and product innovation.

The team advocates open source and co-construction, has a variety of technical experts, the team Github address: https://github.com/tnfe

The author of this article ancai , project address: https://github.com/ancai/nvm

image.png

I. Introduction

This article is a practical summary of a small project I have done in my spare time. It mainly introduces the design and implementation ideas of modern Web front-end frameworks, referring to the design ideas of the Vue2.x version.

Two, MVVM mode

The programmers of web development should be no strangers to the design ideas of MVC, and there are many related articles on the Internet. M(model)-V(view)-C(Controller) represents a mode of program organization structure, which realizes the effective decoupling of data, view and logic. M represents the data state, V represents the view interface, and the Controller is used to process the interaction logic between the data and the view. Back-end web frameworks (such as springMVC and Struts2 in Java; express and koa in nodejs) still use this design pattern to this day.
However, in the front-end field, when it comes to user interface programming, the MVC architecture pattern is no longer mainstream. The main reasons are as follows:

  • Business logic and UI are mixed together
  • Not conducive to expansion and reuse
  • Unable to verify test
  • Increase the complexity of the data

image.png

Later, Microsoft proposed the MVVM architecture pattern. The difference from MVC is that VM replaces C, that is, ViewModel (view model) replaces the controller. Mainly used in the field of user interface programming, it provides a two-way data binding function. View changes are automatically reflected on the ViewModel, and the model is notified through the ViewModel. When the data model Model changes, the view is also associated with the view through the VM. The emergence of MVVM architecture pattern brings new vitality to front-end development, making it easier to write unit tests for front-end development. At the same time, with the help of the middle bridge of ViewModel, developers no longer need to pay attention to the interactive details of some DOM operations, the program is more concise and elegant, combined with the componentized programming design idea, the front-end module is easier to reuse and expand.
ViewModel, generally implemented by the framework, mainly provides two-way data binding function.
More about the recommended two articles: What is the MVVM framework? MVC vs MVVM: Key Differences with Examples

Three, process architecture

The project involves the management of templates, views, data, instructions, and dependencies.

image.png
From a big point of view, the framework mainly completes the two-way binding between the template and the data. Use the related technology of data hijacking to track the changes of the data, and at the same time introduce the publish and subscribe model to complete the dependency management on the attributes. On the other hand, it involves parsing the template, extracting the instructions and expressions in the template, and linking them to the data to initialize the view. The template and data are connected through the watcher, so that data changes are directly mapped to the view; at the same time, it is necessary to monitor input-related events on the view, so that when the input changes, it is directly mapped to the data model.

image.png
From the perspective of engineering processing, it can be divided into four steps: initialization, data monitoring, template compilation and framework functions. The initialization process is mainly to obtain the configuration information passed by the caller, the preprocessing of model data and templates, and some key attributes are delegated to the upper layer. The link of data monitoring involves the hijacking of ordinary JavaScript objects, and the enhanced processing of arrays, through a publish-subscribe model to complete dependency injection of data attributes, and at the same time it is associated with watchers. In the template compilation process, an HTML-like template is parsed, the variable expressions and related instructions in it are extracted, and the data model is associated with the watcher.

image.png
The core class diagram in the project is given above. Observer implements hijacking of data. Dep is equivalent to a publish-subscriber connected to Watcher and Observer at the same time. Compile is responsible for parsing the template, and further extracts and obtains the Directives class and associates it with Parser and Watcher. Parser is used to parse the command to produce the view UI, and Watcher uses a Batcher to process update changes in batches.

image.png
The directory structure of the project code is relatively simple, there are a total of 14 code files in the src directory, and the total number of lines of code is about a thousand lines, which is not very difficult to understand. index.js is the entry file, the processing logic related to template compilation is placed in the compile folder, the observer.js file contains the processing logic related to data hijacking, and value.js contains the attribute expressions of string type converted into object data. Processing logic, dep.js implements a simple publish-subscribe model to associate data state changes and watcher instances. There are detailed comments in watcher.js to indicate which link is called. In addition, the entire project is simply built using webpack, and the packaged volume is also very small.

Fourth, the realization of data hijacking

image.png
Use the object.defineProperty API provided in ES5 to redefine get and set property accessors to hijack data. Mainly to enhance the processing of ordinary objects and arrays, monitor data changes, and notify dependencies. The dependency is injected when the attribute is accessed for the first time, usually when the template is initialized for the first time, the expression of the state attribute is obtained, and the dependency of the state attribute is injected at this time. The dependency here is the watcher instance; when the data changes, it is released through dep- The subscription mode notifies the watcher instance to update the view state.

Five, template compilation implementation

image.png
The template is compiled without using virtual DOM nodes, starting directly from the original html template, traversing the string template, and collecting the instructions inside. At the same time, the expression is parsed, and the dependency injection on the model data is obtained. When it is loaded for the first time, it will be associated with the watcher. There are different types of instructions corresponding to different parsing processors, which are divided into ordinary instructions, event instructions, two-way binding instructions, if/for instructions, and so on. Among them, if/for instructions are involved, a new execution context needs to be created to associate the child's environment data.

Six, key code implementation

depwatcher

The above two figures are about the simple implementation of the dependency manager and watcher. The dependency manager can be regarded as a publish-subscribe model design, that is, the model data is subscribed through the Dep class watcher. When the model data changes, the watcher knows. The simple processing logic of the watcher when there is a face map. When the template is compiled and parsed to obtain an expression, an instance of the watcher will be created, and when the value of the model data is accessed at the same time, the newly created watcher instance will be injected. In this way, the watcher instance acts as a bridge between template compilation and model data.

Seven, summary

This project does not use the virtual node (virtual DOM node), and directly compiles the view part from the string template. The part that is a bit difficult to understand: extraction and analysis of attribute expressions, dependency injection, processing of if and for instructions, and implementation of watchers.
As a relatively weak programmer, it is still impossible to create a mature front-end framework like a front-end technology expert. Through the simple explanation of this article, I hope to help those who have the same confusion to deepen their understanding of the principles of MVVM and the front-end framework. Daniel please ignore it automatically. For the complete source code of this project, see the last part, and a detailed example is given.

Eight, code example

source code

example

Nine, the team

TNTWeb-Tencent news front-end team, TNTWeb is committed to the industry's cutting-edge technology exploration and the improvement of team members' personal capabilities. For front-end developers, we have compiled the latest high-quality content in the field of small programs and web front-end technology, updated weekly✨, welcome to star, github address: https://github.com/tnfe/TNT-Weekly

logo.png


TNTWEB
3.8k 声望8.5k 粉丝

腾讯新闻前端团队