SoFunction
Updated on 2025-04-10

Detailed analysis of the implementation principle of Vue components

Rendering components

A component must be rendered internally and returns a virtual DOM

This is the simplest component instance

const MyComponent = {
  // Component name, optional  name: "MyComponent",
  // The rendering function of the component must be a virtual DOM  render() {
    // Return to virtual DOM    return {
      type: "div",
      children: `I'm text content`,
    };
  },
};

The mountComponent function in the renderer completes the rendering of the component

function mountComponent(vnode, container, anchor) {
  // Get the component's option object through vnode, that is  const componentOptions = ;
  // Get the render function of the component  const { render } = componentOptions;
  // Execute the render function to get the content to be rendered by the component, that is, the virtual returned by the render function  const subTree = render();
  // Finally, call the patch function to mount the content described by the component, that is, subTree  patch(null, subTree, container, anchor);
}

Component update

Component initialization steps:

  • After obtaining the data function, use reactive to turn it into a reactive
  • In the render function, point this to state and pass state as the first parameter into the render function

Wrap the rendering task into a side effect function to achieve responsive update of data

To make the effect execute only once after each responsive data modification, the concept of a scheduler needs to be introduced.

This is the simplest scheduler example given in the book

That is, put the effect into the micro task queue first, wait until the execution stack is cleared before calling it out to execute

// Task cache queue, set can automatically dereloadconst queue = new Set();
// A flag that indicates whether the task queue is being refreshedlet isFlushing = false;
// Create a Promise instance that resolves immediatelyconst p = ();
// The main function of the scheduler is used to add a task to the buffer queue and start refreshing the queuefunction queueJob(job) {
  // Add job to the task queue  (job);
  // If the queue has not started to be refreshed, refresh it  if (!isFlushing) {
    // Set this flag to true to avoid repeated refreshes    isFlushing = true;
    // Refresh the buffer queue in microtasks    (() => {
      try {
        // Execute tasks in the task queue        ((job) => job());
      } finally {
        // Reset status        isFlushing = false;
         = 0;
      }
    });
  }
}

Parent-child component

This is a simple parent-child component code

// Subcomponents<template>
  <MyComponent :title="title" />
</template>
// Parent componentconst vnode = {
  type: MyComponent,
  props: {
    title: 'A Big Title'
  }
}

Parent component update causes child component update (passive update) process:

  • Parent component self-update
  • The renderer checks that subTree finds that there is a vnode, and then calls patchComponent to achieve subcomponent update

setup function

The setup function is introduced in conjunction with the combination API

It has the following two return value forms

// Return functionconst comp = {
  setup() {
    return () => {
      return {
        type: "div",
        children: "give up for vuejs",
      };
    };
  },
};
// Return objectconst comp = {
  setup() {
    const count = ref(0);
    return {
      count,
    };
  },
  render() {
    return {
      type: "div",
      children: `count is ${}`,
    };
  },
};

setup receives two parameters, namely props and setupContext

setupContext contains the following four main objects

  • slots slots
  • emit custom events
  • attrs custom attributes
  • expose

emit implementation

Just implement an emit function and add it to the setupContext object

This is the end of this article about the detailed analysis of the implementation principles of Vue components. For more related contents of implementation principles of Vue components, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!