1. Introduction

Hello, I am Ruochuan, wechat search “Ruochuan Vision” to follow me, focus on front-end technology sharing, a vision is to help the front-end broaden vision to the forefront of the public account in 5 years. Welcome to add my wechat ruochuan12 for long-term communication and learning.

This is the study of the source code overall architecture series of Vex4 source code (chapter 10). Underscore (jQuery, Lodash, Sentry, vuex, Axios, KOa, Redux, vuE-devTools)

10 source code series of articles small achievement, from 19 July began to write, 19 years to write 6, 20 years to write 2, this year to write 2. Kind of an end. We should not update this series for a while. The main reason is that the investment of time and energy is more, less people read, get less feedback. Write other articles first. Welcome to keep following me (Wakawa).

In this paper, the warehouse address: git clone https://github.com/lxchuan12/vuex4-analysis.git, best way to read in this paper, cloning warehouse do-it-yourself debug, easy to digest.

If someone talks about how to read the source code, you, who are reading the article, would recommend my source code series, that would be a great reward.

My article, as far as possible to write so that want to see the source code and do not know how to see the reader can understand. I am recommended to build environment breakpoint debugging source code learning, where will not point where, while debugging while looking, rather than hard to see. It is better to teach a man to fish than to teach a man to fish.

After reading this article you will learn:

    1. git subtreeManage sub-warehouse
    1. How to learnVuex 4Source code, understandingVuexThe principle of
    1. Vuex 4Vuex 3The similarities and differences
    1. Vuex 4 composition APIHow to use
    1. Vue.provide / Vue.injectAPI usage and principles
    1. How to write oneVue3The plug-in
  • , etc.

For those of you who are not familiar with Google Chrome debugging, check out this articleChrome DevTools Source panelIt’s written in great detail. By the way, the Settings I opened, the Source panel supports expanding search blocks (not supported by default), a picture is worth a thousand words.

Google Browser is our common front-end tools, so I suggest you learn, after all, to do a good job, must first sharpen its tools.

Before writing Vuex 3 source code article to learn Vuex source code overall architecture, to create their own state management library, Ruochuan blog Vuex source code, the warehouse has a very detailed annotations and look at the source code method, so this article will not be too redundant with Vuex 3 source code the same place.

1.1 The best way to read this article

My vuex4 source warehouse git clone https://github.com/lxchuan12/vuex4-analysis.git clone, star, by the way my warehouse ^_^ vuex4 source study. Follow the pace of debugging and sample code debugging, hands-on debugging with Chrome more impressive. Article long section of code do not have to look at, you can debug and then look at. See this kind of source code article 100 times, may not be as good as their own debugging several times, bold speculation, careful verification. Also welcome to add my wechat exchange ruochuan12.

2. Principle of Vuex

Conclusion first: The Vuex principle can be broken down into three key points. The first is that every component instance is injected with a Store instance. Second, the various methods in the Store instance serve properties in the Store. Third, property changes in the Store trigger view updates.

This article focuses on the first point. Second point in my last article to learn vuex source code overall architecture, to create their own state management library in detail, this article will not be repeated. The third point is not covered in detail in either article.

The following is a short code that illustrates how Vuex works.

/ / Jane version
class Store{
  constructor(){
    this._state = 'Store instance';
  }
  dispatch(val){
    this.__state = val;
  }
  commit(){}
  / / to omit
}


const store = new Store();
var rootInstance = {
  parent: null.provides: {
    store: store,
  },
};
var parentInstance = {
  parent: rootInstance,
  provides: {
    store: store,
  }
};
var childInstance1 = {
  parent: parentInstance,
  provides: {
    store: store,
  }
};
var childInstance2 = {
  parent: parentInstance,
  provides: {
    store: store,
  }
};

store.dispatch('I've been modified.');
// store store {_state: "I have been modified "}

// rootInstance, parentInstance, childInstance1, childInstance2, etc.
// Because we share the same store object.
Copy the code

Store instance is provided by provide parent component and Store instance is obtained by Inject component.

So next, with the question:

1. Why a view update is triggered when a property in the instance store is changed?

2. How to combine Vue with Vuex4 as a plug-in of Vue.

3, provide, how to implement inject, how each component gets Store in component instance.

4. Why does every component object have Store instance objects?

5. Why the data provided by the component written in the component can be retrieved by the comfort-level component?

3. Major changes to Vuex 4

Before looking at the source code, let’s take a look at the Vuex 4 release and the major change mentioned in the official documentation migration, Vuex 4 Release.

Migrate from 3.x to 4.0

Vuex 4 is all about compatibility. Vuex 4 supports development using Vue 3 and directly provides the same API as Vuex 3, so users can reuse existing Vuex code in Vue 3 projects.

Compared to Vuex 3 version. The major changes are as follows (others are linked above) :

3.1 Installation Process

Vuex 3 is a Vue. Use (Vuex)

Vuex 4 is app.use(Store)

import { createStore } from 'vuex'

export const store = createStore({
  state() {
    return {
      count: 1}}})Copy the code
import { createApp } from 'vue'
import { store } from './store'
import App from './App.vue'

const app = createApp(App)

app.use(store)

app.mount('#app')
Copy the code

3.2 Core modules are exportedcreateLoggerfunction

import { createLogger } from 'vuex'
Copy the code

Let’s look at these major changes from a source code perspective.

4. Major changes in Vuex 4 from a source perspective

4.1 Chrome debugging Vuex 4 source code preparation

Git subtree add -- prefix = vuex https://github.com/vuejs/vuex.git 4.0Copy the code

This approach preserves git record information from the Vex4 repository. Git subtree can be used to bidirectionally synchronize sub-projects between multiple Git projects.

As readers friend of you, need to clone my Vuex source warehouse 4 https://github.com/lxchuan12/vuex4-analysis.git, welcome to star, too.

The vuex/examples/webpack. Config. Js, add a devtool: ‘the source – the map, so you can open sourcemap debugging the source code.

We use an example of a shopping cart in the project for debugging throughout the article.

git clone https://github.com/lxchuan12/vuex4-analysis.git
cd vuex
npm i
npm run dev
# open http://localhost:8080/
# Select composition shopping cart for example
# open http://localhost:8080/composition/shopping-cart/
# Press F12 to open the debugging tool, source panel => Page => webpack:// =>
Copy the code

It is said that a graph wins thousands of words, then simply cut a debugging graph.

Find the createStore function and set a breakpoint.

// webpack:///./examples/composition/shopping-cart/store/index.js
import { createStore, createLogger } from 'vuex'
import cart from './modules/cart'
import products from './modules/products'

constdebug = process.env.NODE_ENV ! = ='production'

export default createStore({
  modules: {
    cart,
    products
  },
  strict: debug,
  plugins: debug ? [createLogger()] : []
})
Copy the code

Go to the app.js entry and hit a breakpoint on app.use(store), app.mount(‘#app’) etc.

// webpack:///./examples/composition/shopping-cart/app.js
import { createApp } from 'vue'
import App from './components/App.vue'
import store from './store'
import { currency } from './currency'

const app = createApp(App)

app.use(store)

app.mount('#app')
Copy the code

CreateApp ({}), app.use(Store)

4.2 Vuex createStore function

Compared to the new Vuex.Store in Vuex 3, it is the same. Just to be consistent with Vue 3, Vuex 4 has an additional createStore function.

export function createStore (options) {
  return new Store(options)
}
class Store{
  constructor (options = {}) {// omit some code...
    this._modules = new ModuleCollection(options)
    const state = this._modules.root.state
    resetStoreState(this, state)
    // omit some code...}}function resetStoreState (store, state, hot) {
  // omit some code...
  store._state = reactive({
    data: state
  })
  // omit some code...
}
Copy the code

Monitoring data

Unlike Vuex 3, new Vue() is no longer used to listen to data, but the reactive method provided by Vue 3.

Reactive function methods are not discussed in this article. Because, by extension, it’s time to write a new article. Just know that the main function is to monitor data changes and change the view.

That’s the answer to the first question.

Following the breakpoint we continue to look at the app.use() method, the plug-in mechanism provided by Vue.

4.3 app. Use () method

What use does is simple enough: add passed plug-ins to the plugin collection to prevent duplication.

Execute the plug-in, and if it is an object and Install is a function, pass the argument app and other arguments to the install function. If it’s a function that executes directly.

// webpack:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js
function createAppAPI(render, hydrate) {
    return function createApp(rootComponent, rootProps = null) {
      // The code is truncated
      const installedPlugins = new Set(a);const app = (context.app = {
        use(plugin, ... options) {
          // There are plug-ins already, and not in production environment, warning.
            if(installedPlugins.has(plugin)) { (process.env.NODE_ENV ! = ='production') && warn(`Plugin has already been applied to target app.`);
            }
            // If the plug-in's install is a function, add the plug-in and execute install
            else if (plugin && isFunction(plugin.install)) {
                installedPlugins.add(plugin);
                / / the breakpointplugin.install(app, ... options); }// If the plug-in itself is a function, the plug-in is added and the plug-in function is executed
            else if(isFunction(plugin)) { installedPlugins.add(plugin); plugin(app, ... options); }// If neither of these is a warning
            else if((process.env.NODE_ENV ! = ='production')) {
                warn(`A plugin must either be a function or an object with an "install" ` +
                    `function.`);
            }
            // Support chain calls
            return app;
        },
        provide(){ 
          / / to omit... Later to tell them}}); }}Copy the code

Plugin. Install (app,… options);

Follow the breakpoint to the next step, the install function.

4.4 install function

export class Store{
    // omit some code...
    install (app, injectKey) {
        // used in the Composition API
        InjectKey can be passed in if the default storeKey (store) is not passed in
        app.provide(injectKey || storeKey, this)
        // Used in the OPTION API
        app.config.globalProperties.$store = this
    }
    // omit some code...
}
Copy the code

The install function in VEX4 is much simpler than in Vex3. The first sentence is provided to the Composition API. Into the root instance object. The second sentence is provided for the Option API.

Next, press F11 to see the implementation of app.provide.

4.4.1 app. Dojo.provide

So basically we add store = store to the provides property of the context.

provide(key, value) {
    // Warning if there is already a value
    if((process.env.NODE_ENV ! = ='production') && key in context.provides) {
        warn(`App already provides property with key "The ${String(key)}". ` +
            `It will be overwritten with the new value.`);
    }
    // TypeScript doesn't allow symbols as index type
    // https://github.com/Microsoft/TypeScript/issues/24587
    context.provides[key] = value;
    return app;
}
Copy the code

Then search for the context in the code above, and you’ll find this:

const context = createAppContext();
Copy the code

Now let’s look at createAppContext. Context = context

// webpack:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js
function createAppContext() {
    return {
        app: null.config: {
            isNativeTag: NO,
            performance: false.globalProperties: {},
            optionMergeStrategies: {},
            isCustomElement: NO,
            errorHandler: undefined.warnHandler: undefined
        },
        mixins: [].components: {},
        directives: {},
        provides: Object.create(null)}; }Copy the code

Vue3 Document Application Configuration (app.config)

4.4.2 app. Config. GlobalProperties

App. Config. GlobalProperties official documentation

Usage:

app.config.globalProperties.$store = {}

app.component('child-component', {
  mounted() {
    console.log(this.$store) / / '{}'}})Copy the code

This explains why every component can use this.$store. XXX to access methods and properties in vuex.

This means that a Store instance object is injected into appContext.provides. This is equivalent to the root component instance and the Config global configuration globalProperties having the Store instance object.

CreateStore (Store), app.use(Store)

App.provide is actually for composition API use.

But that’s just what the documentation says, so why should every component instance be accessible? Let’s dig a little deeper.

Next, let’s take a look at the source code implementation and why it is available in every component instance.

Before we do that, let’s take a look at how we use Vex4 in the composite API, and that’s a clue.

4.5 How to use Vuex 4 in composition API

Then we find the following file, useStore is the object of our breakpoint.

// webpack:///./examples/composition/shopping-cart/components/ShoppingCart.vue
import { computed } from 'vue'
import { useStore } from 'vuex'
import { currency } from '.. /currency'

export default {
  setup () {
    const store = useStore()

    // I added this line of code
    window.ShoppingCartStore = store;
    // Omit some code}}Copy the code

Then break F11 and step through, you will find that the vue.Inject method is used.

4.5.1 Vuex. UseStore source code implementation

// vuex/src/injectKey.js
import { inject } from 'vue'

export const storeKey = 'store'

export function useStore (key = null) {
  returninject(key ! = =null ? key : storeKey)
}
Copy the code

4.5.2 Vue.inject source code implementation

Look at the inject function, there is a lot of code, in fact, the principle is very simple, is to find the value we provide with provide.

If there is no parent, which is the root instance, he took the vnode instance objects. The appContext. Provides. Otherwise, take the value of instance.parent. Provides from the parent.

Vex4 source code is: Store instance object.

// webpack:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js
function inject(key, defaultValue, treatDefaultAsFactory = false) {
    // fallback to `currentRenderingInstance` so that this can be called in
    // a functional component
    CurrentRenderingInstance if called by a functional component
    const instance = currentInstance || currentRenderingInstance;
    if (instance) {
        / / # 2400
        // to support `app.use` plugins,
        // fallback to appContext's `provides` if the intance is at root
        const provides = instance.parent == null
            ? instance.vnode.appContext && instance.vnode.appContext.provides
            : instance.parent.provides;
        if (provides && key in provides) {
            // TS doesn't allow symbol as index type
            return provides[key];
        }
        // If the second argument is greater than 1, the second argument is the default, the third argument is true, and the second value is a function, the function is executed.
        else if (arguments.length > 1) {
            return treatDefaultAsFactory && isFunction(defaultValue)
                ? defaultValue()
                : defaultValue;
        }
        // Warning not found
        else if((process.env.NODE_ENV ! = ='production')) {
            warn(`injection "The ${String(key)}" not found.`); }}// If there is no current instance, a warning is reported.
    Inject must be called in setup or used in functional components
    else if((process.env.NODE_ENV ! = ='production')) {
        warn(`inject() can only be used inside setup() or functional components.`); }}Copy the code

Then we move on to the provide of inject.

4.5.3 Vue.provide source code implementation

The provide function adds a key/value pair to the provides object property on the current component instance.

__proto__ is used to create a link between the component’s parent and the component’s provider object ([[prototype]]).

// webpack:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js
function provide(key, value) {
    if(! currentInstance) {if((process.env.NODE_ENV ! = ='production')) {
            warn(`provide() can only be used inside setup().`); }}else {
        let provides = currentInstance.provides;
        // by default an instance inherits its parent's provides object
        // but when it needs to provide values of its own, it creates its
        // own provides object using parent provides object as prototype.
        // this way in `inject` we can simply look up injections from direct
        // parent and let the prototype chain do the work.
        const parentProvides = currentInstance.parent && currentInstance.parent.provides;
        if (parentProvides === provides) {
            provides = currentInstance.provides = Object.create(parentProvides);
        }
        // TS doesn't allow symbol as index typeprovides[key] = value; }}Copy the code

This section of the provide function may not be easy to understand.

if (parentProvides === provides) {
    provides = currentInstance.provides = Object.create(parentProvides);
}
Copy the code

Let’s digest it with an example.

var currentInstance = { provides: { store: { __state: 'Store instance'}}};var provides = currentInstance.provides;
// Create an instance of the same object, of course, will be equal.
var parentProvides = provides;
if(parentProvides === provides){
    provides =  currentInstance.provides = Object.create(parentProvides);
}
Copy the code

After executing this once, currentInstance looks like this.

{
  provides: {
    // Can accommodate other attributes, such as user-written ones
    __proto__ : { store: { __state: 'Store instance'}}}}Copy the code

The second time, currentInstance is:

{
  provides: {
    // Can accommodate other attributes, such as user-written ones
    __proto__: {
        // Can accommodate other attributes, such as user-written ones
        __proto__ : { store: { __state: 'Store instance' }  }
    }
  }
}
Copy the code

Similarly, the more times you perform provide, the longer the prototype chain.

CurrentInstance = currentInstance = currentInstance = currentInstance = currentInstance = currentInstance = currentInstance

The idea of why every component has access to dependency injection. A neat way to do this is to search for the createComponentInstance function in the runtime-core.esm-bundler.js file for provides

Next we’ll see how the createComponentInstance function creates a component instance.

4.6 createComponentInstance Creates a component instance

You can disable other breakpoints, such as const appContext = (parent? parent.appContext : vnode.appContext) || emptyAppContext; Let’s look at the implementation.

// webpack:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js
const emptyAppContext = createAppContext();
let uid$1 = 0;
function createComponentInstance(vnode, parent, suspense) {
    const type = vnode.type;
    const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
    const instance = {
        uid: uid$1++,
        vnode,
        type,
        parent,
        appContext,
        root: null.next: null.subTree: null.// ...
        provides: parent ? parent.provides : Object.create(appContext.provides),
        // ...
    }
    instance.root = parent ? parent.root : instance;
    // ...
    return instance;
}
Copy the code

The breakpoint will show that the vNode has been generated when the root component instance is generated. I have compiled a simplified version of when the vNode was generated.

// Assign appContext to appContext
mount(rootContainer, isHydrate) {
    if(! isMounted) {const vnode = createVNode(rootComponent, rootProps);
        // store app context on the root VNode.
        // this will be set on the root instance on initial mount.vnode.appContext = context; }},Copy the code

Object. Create creates the prototype relationship. Now put a picture, a picture is worth a thousand words.

From teacher Huang Yi’s column, I wanted to draw a picture by myself, but I think this one is quite good.

4.6.1 Component instances are generated, so how do you combine them

A neat way to do this is to search for provide in runtime-core.esm-bundler.js.

This code looks very complicated, but basically iterates through the provides object or function return value that the user wrote in the component to generate an instance object like this:

// The current component instance
{
  parent: 'Parent instance'.provides: {
    // Can accommodate other attributes, such as user-written ones
    __proto__: {
        // Can accommodate other attributes, such as user-written ones
        __proto__ : { store: { __state: 'Store instance' }  }
    }
  }
}
Copy the code
// webpack:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js
function applyOptions(instance, options, deferredData = [], deferredWatch = [], deferredProvide = [], asMixin = false) {
  // ...
  if (provideOptions) {
      deferredProvide.push(provideOptions);
  }
  if(! asMixin && deferredProvide.length) { deferredProvide.forEach(provideOptions= > {
          Provides can be an object or a function
          const provides = isFunction(provideOptions)
              ? provideOptions.call(publicThis)
              : provideOptions;
          Reflect.ownKeys(provides).forEach(key= > {
              provide(key, provides[key]);
          });
      });
  }
  // ...
}
Copy the code

In this way, objects provided by app.provide are injected into each component instance from top to bottom. The provides provided by the component itself are also injected into the instance.

Then we follow the project to verify the statement above. A look at the Vue3 documentation shows that there is an API to get the current component instance.

4.7 getCurrentInstance Obtains the current instance object

GetCurrentInstance supports access to internal component instances for high-level usage or library development.

import { getCurrentInstance } from 'vue'

const MyComponent = {
  setup() {
    const internalInstance = getCurrentInstance()

    internalInstance.appContext.config.globalProperties / / access globalProperties}}Copy the code

Now that we know this API, we can add some code to the shopping cart example. It’s easy for us to understand.

// vuex/examples/composition/shopping-cart/components/App.vue
import { getCurrentInstance, provide } from 'vue'
import { useStore } from 'vuex';
setup () {
  const store = useStore()
  provide('ruochuan12'.'Wechat search "Ruochuan Vision" to follow me, focus on front-end technology sharing. ')

  window.AppStore = store;
  window.AppCurrentInstance = getCurrentInstance();
},
Copy the code
// vuex/examples/composition/shopping-cart/components/ProductList.vue
setup(){
  const store = useStore()

  // Add the debugging code --start
  window.ProductListStore = store;
  window.ProductListCurrentInstance = getCurrentInstance();
  provide('weixin-2'.'ruochuan12');
  provide('weixin-3'.'ruochuan12');
  provide('weixin-4'.'ruochuan12');
  const mp = inject('ruochuan12');
  console.log(mp, 'introduction - ProductList'); // Search "Ruochuan Vision" on wechat to follow me and focus on front-end technology sharing.
  // Debug code added by Wakagawa --end
}
Copy the code
// vuex/examples/composition/shopping-cart/components/ShoppingCart.vue
setup () {
    const store = useStore()

    // Add the debugging code --start
    window.ShoppingCartStore = store;
    window.ShoppingCartCurrentInstance = getCurrentInstance();
    provide('weixin'.'ruochuan12');
    provide('weixin1'.'ruochuan12');
    provide('weixin2'.'ruochuan12');
    const mp = inject('ruochuan12');
    console.log(mp, 'introduction - ShoppingList'); // Search "Ruochuan Vision" on wechat to follow me and focus on front-end technology sharing.
    // Add the debugging code --start
}
Copy the code

Print these values on the console

AppCurrentInstance
AppCurrentInstance.provides
ShoppingCartCurrentInstance.parent === AppCurrentInstance // true
ShoppingCartCurrentInstance.provides
ShoppingCartStore === AppStore // true
ProductListStore === AppStore // true
AppStore // store instance object
Copy the code

Take a look at the console screenshot output example, actually with the article write similar. If Vuex fails to provide(‘store’: ’empty string ‘), Vuex will not work properly.

Of course, Vuex4 provides the injection key can not be written as store, then there is no conflict with the user.

export class Store{
    // omit some code...
    install (app, injectKey) {
        // used in the Composition API
        InjectKey can be passed in if the default storeKey (store) is not passed in
        app.provide(injectKey || storeKey, this)
        // Used in the OPTION API
        app.config.globalProperties.$store = this
    }
    // omit some code...
}
Copy the code
export function useStore (key = null) {
  returninject(key ! = =null ? key : storeKey)
}
Copy the code

5. Answer the following five questions

Answer the five questions from the beginning:

1. Why a view update is triggered when a property in the instance store is changed?

A: Using reactive methods in Vue to monitor data changes.

class Store{
  constructor (options = {}) {// omit some code...
    this._modules = new ModuleCollection(options)
    const state = this._modules.root.state
    resetStoreState(this, state)
    // omit some code...}}function resetStoreState (store, state, hot) {
  // omit some code...
  store._state = reactive({
    data: state
  })
  // omit some code...
}
Copy the code

2. How to combine Vue with Vuex4 as a plug-in of Vue.

A: App.use (store) executes the install method in Store, which is used in the Composition API and provides store instance objects to the root instance. A sentence is injected into the global property of the root instance for use in the Option API. They are injected into each component instance at component generation time.

export class Store{
    // omit some code...
    install (app, injectKey) {
        // used in the Composition API
        InjectKey can be passed in if the default storeKey (store) is not passed in
        app.provide(injectKey || storeKey, this)
        // Used in the OPTION API
        app.config.globalProperties.$store = this
    }
    // omit some code...
}
Copy the code

3, provide, how to implement inject, how each component gets Store in component instance.

5. Why the data provided by the component written in the component can be retrieved by the comfort-level component?

A: The provide function establishes a prototype chain that distinguishes component instance user-written properties from system-injected properties. The Inject function finds attributes in the provides object of the parent instance through the prototype chain.

/ / a cut
function provide(){
    let provides = currentInstance.provides;
    const parentProvides = currentInstance.parent && currentInstance.parent.provides;
    if (parentProvides === provides) {
        provides = currentInstance.provides = Object.create(parentProvides);
    }
    provides[key] = value;
}
Copy the code
/ / a cut
function inject(){
    const provides = instance.parent == null
        ? instance.vnode.appContext && instance.vnode.appContext.provides
        : instance.parent.provides;
    if (provides && key in provides) {
        returnprovides[key]; }}Copy the code

Here’s an example like this:

// The current component instance
{
  parent: 'Parent instance'.provides: {
    // Can accommodate other attributes, such as user-written ones
    __proto__: {
        // Can accommodate other attributes, such as user-written ones
        __proto__ : { store: { __state: 'Store instance' }  }
    }
  }
}
Copy the code

4. Why does every component object have Store instance objects?

A: When rendering a component instance, createComponentInstance is called and injected into the component instance’s provides.

function createComponentInstance(vnode, parent, suspense) {
    const type = vnode.type;
    const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
    const instance = {
        parent,
        appContext,
        // ...
        provides: parent ? parent.provides : Object.create(appContext.provides),
        // ...
    }
    // ...
    return instance;
}
Copy the code
  1. How do you know so much

A: Because someone in the community wrote a Vue4 source code article.

6. Summary

This article mainly describes the principle of Vuex4 to inject Store instance into each component, and then describes the changes of Vuex4 installation mode compared with Vuex3. Vuex.createstore, app.use(Store), In-depth source code analysis vue. inject, vue. provide implementation principle.

Vex4 is basically the same as vex3. x except that vuue. Reactive is used in the installation and monitoring of changes in data.

Finally, review the diagram at the beginning of this article, which can be said to be a useful prototype chain.

I don’t know if I just saw the light.

Vuex is actually a plug-in for Vue. Knowing the principle of Vuex, I can write plug-ins for Vue with ease.

If you find anything wrong or can be improved, or if you don’t understand it clearly, you are welcome to comment on it or add ruochuan12 on wechat. In addition, I think it is well written and helpful to you. You can like, comment, forward and share it, which is also a kind of support for me. Thank you very much. If you can pay attention to my front public number: “Ruochuan vision”, even better.

about

Hello, I am Ruochuan, wechat search “Ruochuan Vision” to follow me, focus on front-end technology sharing, a vision is to help the front-end broaden vision to the forefront of the public account in 5 years. Welcome to add my wechat ruochuan12 for long-term communication and learning.

There are mainly the following series of articles: learning the overall structure of the source code series, annual summary, JS basic series

Refer to the link

Provide/Inject Github repository Provide/Inject source code Github repository Provide/Inject test Vuex 4 official Chinese document