Goal: Handwritten Mini Version Vue
1: Use rollup to package, the packaged code is smaller and more suitable for writing framework source code packaging
npm i rollup -D
2: Install babel-related packages, implement static services, and set packages for environment variables
npm i @babel/core @babel/preset-env rollup-plugin-babel roullup-plugin-serve cross-env -D
Three: Related introduction to the package
- rollup (packaging tool)
- @babel/core (using babel core module)
- @babel/preset-env (babel converts high-level syntax to low-level syntax)
- rollup-plugin-serve (implements static services)
- cross-env (set environment variables)
- rollup-plugin-babel(bridge)
Four: Root Directory Writing
import babel from 'rollup-plugin-babel'; import serve from 'rollup-plugin-serve'; export default { input:'./src/', // Which file to use as the package entry output:{ file:'dist/umd/', // Exit path name:'Vue', // Specify the name of the global variable after packaging format: 'umd', // Unified module specifications sourcemap:true, // es6-> es5 Turn on source code debugging and you can find the error location of the source code }, plugins:[ // Plugin used babel({ exclude:"node_modules/**" }), === 'development'?serve({ open:true, openPage:'/public/', // The default path to open html port:3000, contentBase:'' }):null ] }
Configuration
{ "name": "vue_souce", "version": "1.0.0", "description": "", "main": "", "scripts": { "build:dev": "rollup -c", "serve": "cross-env ENV=development rollup -c -w" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.9.0", "@babel/preset-env": "^7.9.5", "cross-env": "^7.0.2", "rollup": "^2.6.1", "rollup-plugin-babel": "^4.4.0", "rollup-plugin-serve": "^1.0.1" } }
5: New (public/)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="/dist/umd/"></script> <script> let vm = new Vue({ el:'#app', // Give some data casually data(){ return { name:'Zhang San', age:11, address:{ number:0, name:'Li Si' }} }, }) vm._data.address = {a:1}; (vm._data) </script> </body> </html>
Six: Write the Vue entrance:
// Vue's core code is just a statement of Vueimport {initMixin} from './init'; function Vue(options){ // Initialize Vue this._init(options); } // Add a method to the Vue prototype by introducing filesinitMixin(Vue); // Add a _init method to the Vue prototypeexport default Vue
Seven: Write initialization operations
import {initState} from './state' // Add an init method to the prototypeexport function initMixin(Vue){ // Initialization process ._init = function (options) { // Hijacking of data const vm = this; // Use this.$options in vue refers to the attributes passed by the user vm.$options = options; // Initialization status initState(vm); // Split code } }
8: Initialize the data
import {observe} from './observer/' export function initState(vm){ const opts = vm.$options; // vue's data source Attribute Method Data Computing attribute watch if(){ initProps(vm); } if(){ initMethod(vm); } if(){ initData(vm); } if(){ initComputed(vm); } if(){ initWatch(vm); } } function initProps(){} function initMethod() {} function initData(vm){ // Data initialization work let data = vm.$; // User-passed data data = vm._data = typeof data === 'function'?(vm):data; // Object hijacking User changed the data I hope I can get notified =》 Refresh the page // MVVM mode Data changes can drive view changes // () Add a get method and set method to the attribute observe(data); // Responsive principle} function initComputed(){} function initWatch(){}
Nine: Core monitoring function of writing
// Redefine all data in data using es5// Not compatible with ie8 and below vue2 cannot be compatible with ie8 versionimport { isObject } from '../util/index' // I can tell if it is an observed data __ob__class Observer{ constructor(value){ // Just an initialization operation // vue If the data levels are too high, you need to recursively parse the properties in the object, and add set and get methods in turn. // Monitor array (value); // Observe the object } walk(data){ let keys = (data); // [name,age,address] // If this data is not configurable, return directly ((key)=>{ defineReactive(data,key,data[key]); }) } } function defineReactive(data,key,value){ observe(value); // Recursively implement deep detection (data,key,{ configurable:true, enumerable:false, get(){ // Do some operations when getting the value return value; }, set(newValue){ // You can also do some operations if(newValue === value) return; observe(newValue); // Continue to hijack the user set value, because it is possible that the user set value is an object value = newValue; } }); } export function observe(data) { let isObj = isObject(data); if (!isObj) { return } return new Observer(data); // Used to observe data}
10: Write tool files and store verification objects
/** * * @param {*} data Is the current data an object */ export function isObject(data) { return typeof data === 'object' && data !== null; }
Summarize:
1 Create a Vue constructor and receive all parameters options
2 Classification initialization options. This chapter mainly deals with data, so that the reference type data on data becomes responsive through . The initialization is sequential. First, initialize props, then initialize method and then initialize data computed watch
3 cores are as follows
function defineReactive(data,key,value){ observe(value); // Recursively implement deep detection (data,key,{ configurable:true, enumerable:false, get(){ // Do some operations when getting the value return value; }, set(newValue){ // You can also do some operations if(newValue === value) return; observe(newValue); // Continue to hijack the user set value, because it is possible that the user set value is an object value = newValue; } }); }
This is the end of this article about the implementation of the principle of object hijacking. For more related object hijacking content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!