Build the development environment with Rollup
1. What is Rollup?
Rollup is a JavaScript module wrapper that compiles small pieces of code into large, complex pieces of code. Rollup. js is more focused on JavaScript library packaging (use WebPack for application development, Rollup for library development).
2. Environment construction
Install the rollup environment
npm install @babel/preset-env @babel/core rollup rollup-plugin-babel rollup-plugin-serve cross-env -D
Copy the code
Rollup.config. js file
import babel from 'rollup-plugin-babel'; import serve from 'rollup-plugin-serve'; Export default {input: './ SRC /index.js', output: {format: 'umd', // Module type file: 'dist/umd/vue.js', name: 'Vue', // the name of the packaged global variable sourcemap: true}, plugins: [Babel ({exclude: 'node_modules/**' }), process.env.ENV === 'development'?serve({ open: true, openPage: '/public/index.html', port: 3000, contentBase: '' }):null ] }Copy the code
Configure the. Babelrc file
{
"presets": [
"@babel/preset-env"
]
}
Copy the code
Executing script Configuration
"scripts": {
"build:dev": "rollup -c",
"serve": "cross-env ENV=development rollup -c -w"
}
Copy the code
Vue response principle
Export the vue constructor
import {initMixin} from './init'; function Vue(options) { this._init(options); } initMixin(Vue); // Add the _init method export default Vue to the prototype;Copy the code
Initialize the VUE state in the init method
import {initState} from './state'; export function initMixin(Vue){ Vue.prototype._init = function (options) { const vm = this; $options = options // initialization state initState(VM)}}Copy the code
Initialize operations based on different attributes
export function initState(vm){ const opts = vm.$options; if(opts.props){ initProps(vm); } if(opts.methods){ initMethod(vm); } if(opts.data){// Initialize data initData(vm); } if(opts.computed){ initComputed(vm); } if(opts.watch){ initWatch(vm); } } function initProps(){} function initMethod(){} function initData(){} function initComputed(){} function initWatch(){}Copy the code
1. Initialize data
import {observe} from './observer/index.js'
function initData(vm){
let data = vm.$options.data;
data = vm._data = typeof data === 'function' ? data.call(vm) : data;
observe(data);
}
Copy the code
2. Recursive attribute hijacking
Class Observer {// Constructor (value){this.walk(value); } walk(data){let keys = object.keys (data); for(let i = 0; i < keys.length; i++){ let key = keys[i]; let value = data[key]; defineReactive(data,key,value); } } } function defineReactive(data,key,value){ observe(value); Object.defineProperty(data,key,{ get(){ return value }, set(newValue){ if(newValue == value) return; observe(newValue); value = newValue } }) } export function observe(data) { if(typeof data ! == 'object' || data == null){ return; } return new Observer(data); }Copy the code
3. Hijacking of array methods
import {arrayMethods} from './array'; Constructor (value){if(array.isarray (value)){value.__proto__ = arrayMethods; // Override the array prototype method this.observeArray(value); }else{ this.walk(value); } } observeArray(value){ for(let i = 0 ; i < value.length ; i ++){ observe(value[i]); }}}Copy the code
Overrides array prototype methods
let oldArrayProtoMethods = Array.prototype; export let arrayMethods = Object.create(oldArrayProtoMethods); let methods = [ 'push', 'pop', 'shift', 'unshift', 'reverse', 'sort', 'splice' ]; methods.forEach(method => { arrayMethods[method] = function (... args) { const result = oldArrayProtoMethods[method].apply(this, args); const ob = this.__ob__; let inserted; switch (method) { case 'push': case 'unshift': inserted = args; break; case 'splice': inserted = args.slice(2) default: break; } if (inserted) ob.observeArray(inserted); Return result}})Copy the code
Add OB attributes
class Observer { constructor(value){ Object.defineProperty(value,'__ob__',{ enumerable:false, configurable:false, value:this }); / /... }}Copy the code
Add identifiers to all reactive data and get methods on Observer instances on reactive data
4.Data brokers
function proxy(vm,source,key){ Object.defineProperty(vm,key,{ get(){ return vm[source][key]; }, set(newValue){ vm[source][key] = newValue; }}); } function initData(vm){ let data = vm.$options.data; data = vm._data = typeof data === 'function' ? data.call(vm) : data; For (let key in data){proxy(vm,'_data',key)} observe(data); }Copy the code