SoFunction
Updated on 2025-04-11

Implementation of the principle of object hijacking

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!