1 Introduction
Hello, I’m , WeChat search Vision" 160a478394ab2a Follow me, focus on front-end technology sharing, a vision is to help the front-end to broaden its horizons to the forefront of the public account within 5 years. Welcome to add me on WeChatruochuan12
for long-term exchange and learning.This is the vuex4 source code (the tenth part)
learning source code overall architecture series. Learning Source overall architecture series ( What are the must-see JS library ): jQuery , Underscore , lodash , Sentry , vuex , Axios , KOA , Redux , vue-devtools directly open the file function to reveal the secret .
10 source code series articles, small achievements reached , started writing in July 19th, wrote 6 articles in 19 years, 2 articles in 20 years, and 2 articles this year. It's an end. This series should not be updated for a short time. The main reason is that more time and energy are invested, few people see it, and less feedback is received. Then write other articles first. Welcome to continue to follow me ( ).
address of the warehouse of this article is :
git clone https://github.com/lxchuan12/vuex4-analysis.git
, the best way to read this article, clone the warehouse and debug by yourself, easy to absorb and digest.If someone talks about how to read the source code, if you are reading the article, you can recommend my source code series articles, that would be really .
My article is written as far as possible so that readers who want to read the source code but don't know how to read it can understand. I always recommend using build the environment breakpoint debugging source code to learn , where will not be where , watch while debugging, rather than just look at . As the goes: 160a478394aced is better to teach people to fish than to teach people to fish .
After reading this article, you will learn:
git subtree
Manage sub-repositories
- How to learn the source code of
Vuex 4
and understand the principle ofVuex
- How to learn the source code of
Vuex 4
and differences betweenVuex 3
- How to use
Vuex 4
composition API
- How to use
Vue.provide / Vue.inject
API usage and principle
- How to write a
Vue3
plug-in
- How to write a
- and many more
If you are not familiar with Google browser debugging, you can read this article chrome devtools source panel , which is written in great detail. By the way, in the settings I opened, the search code block is supported in the source panel (not supported by default), and a picture is worth a thousand words.
Google Chrome is a commonly used tool in our front-end, so we recommend that you learn more. After all, must first sharpen its .
Written before Vuex 3
source article learning vuex source overall architecture, to create their own state management library , if Sichuan blog Vuex source , warehouses have very detailed notes and look at the source code method, so this article will not go into too much Same place as the source code of Vuex 3
1.1 The best way to read this article
Clone my vuex4
source code warehouse git clone https://github.com/lxchuan12/vuex4-analysis.git
, by the way, star my vuex4 source code learning warehouse ^_^. Follow the rhythm of the article to debug and sample code debugging, and use chrome to debug the impression more deeply . You don’t need to look closely at the long code of the article, you can look at it carefully when debugging. Reading this kind of source code articles a hundred times may not as good as debugging a few times by yourself, making bold guesses and carefully verifying. Also welcome to add me on WeChat to exchange ruochuan12
.
2. Brief description of Vuex principle
Conclusion First : The Vuex
can be disassembled into three key points.
The first point is that each component instance is injected with Store
instance of 060a478394afb3.
The second point is that the various methods in the Store
instance all serve the attributes in Store
The third point is that the attribute change in Store
This article mainly explains the first point. The second point is in my last article, learning the overall architecture of vuex source code, and creating your own state management library . I will not go into details in this article. The third point is not described in detail in the two articles.
The following is a short code to explain the principle of Vuex
// 简版
class Store{
constructor(){
this._state = 'Store 实例';
}
dispatch(val){
this.__state = val;
}
commit(){}
// 省略
}
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('我被修改了');
// store Store {_state: "我被修改了"}
// rootInstance、parentInstance、childInstance1、childInstance2 这些对象中的provides.store都改了。
// 因为共享着同一个store对象。
Read the above official document map, probably know is provide
provide parent component Store
example, with inject
to get to Store
instance.
Then, with the question:
1. Why is the attribute in the instance store
modified? After the change, the view update will be triggered.
2, Vuex4
as Vue
plug-in how to implement and Vue
combination.
3. provide
and inject
, and how to obtain Store
in the component instance for each component.
4. Why is there a Store
instance object in each component object (the process of rendering the component object).
provide
written in the component can be obtained by the sub-component.
3. Vuex 4 major changes
Before looking at the source code, let’s take a look at the Vuex 4
released by release
and the major changes mentioned in the official document migration, Vuex 4 release .
The focus of Vuex 4
Vuex 4
supports Vue 3
, and directly provides Vuex 3
exactly the same as API
, so users can reuse the existing Vuex
code Vue 3
Compared to the Vuex 3
version. The major changes are as follows (the others are in the link above):
3.1 Installation process
Vuex 3
is Vue.use(Vuex)
Vuex 4
is app.use(store)
import { createStore } from 'vuex'
export const store = createStore({
state() {
return {
count: 1
}
}
})
import { createApp } from 'vue'
import { store } from './store'
import App from './App.vue'
const app = createApp(App)
app.use(store)
app.mount('#app')
3.2 The core module exports the createLogger
function
import { createLogger } from 'vuex'
Next, we will look at these major changes from the perspective of the source code.
4. View the major changes in Vuex 4 from the source code point of view
4.1 chrome debugging Vuex 4 source code preparation
git subtree add --prefix=vuex https://github.com/vuejs/vuex.git 4.0
This way retains the git
record information of vuex4
warehouse. For more git subtree
use 060a478394b428, please see this article Use Git Subtree to synchronize sub-projects between multiple Git projects in both directions, with a concise user manual .
As a reader friend, you only need to clone my Vuex 4
source code repository https://github.com/lxchuan12/vuex4-analysis.git
, and welcome star
.
Add vuex/examples/webpack.config.js
to devtool: 'source-map'
, so that you can turn on the sourcemap
debugging source code.
We use the example of the shopping cart in the project to debug, throughout the whole text.
git clone https://github.com/lxchuan12/vuex4-analysis.git
cd vuex
npm i
npm run dev
# 打开 http://localhost:8080/
# 选择 composition 购物车的例子 shopping-cart
# 打开 http://localhost:8080/composition/shopping-cart/
# 按 F12 打开调试工具,source面板 => page => webpack:// => .
It is said that a picture is worth a thousand words. At this time, simply cut a picture for debugging.
Find the createStore
function to hit 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'
const debug = process.env.NODE_ENV !== 'production'
export default createStore({
modules: {
cart,
products
},
strict: debug,
plugins: debug ? [createLogger()] : []
})
Find app.js
entrance, in app.use(store)
, app.mount('#app')
and other marked breakpoint.
// 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')
Next, we will explain from two aspects: createApp({})
and app.use(Store)
4.2 Vuex.createStore function
Compared to Vuex 3
, new Vuex.Store
is actually the same. Just in order to Vue 3
unified with Vuex 4
an additional createStore
function.
export function createStore (options) {
return new Store(options)
}
class Store{
constructor (options = {}){
// 省略若干代码...
this._modules = new ModuleCollection(options)
const state = this._modules.root.state
resetStoreState(this, state)
// 省略若干代码...
}
}
function resetStoreState (store, state, hot) {
// 省略若干代码...
store._state = reactive({
data: state
})
// 省略若干代码...
}
Monitoring data
And Vuex 3
difference is that the data is no longer listening is new Vue()
, but Vue 3
provided reactive
method.
Vue.reactive
function method will not be explained in this article. Because in terms of expansion, you can write a new article again. Just need to know that the main function is to monitor data changes and change the view.
This is the answer to the first question raised at the beginning.
Following the breakpoint, we continue to look at the app.use()
method, the plug-in mechanism provided by Vue
4.3 app.use() method
use
does is easy to say, adding the passed plug-ins to the plug-in collection to prevent duplication.
Execute the plug-in, if it is an object, install
is a function, then pass the parameter app and other parameters to the install function for execution. If it is a function, execute it directly.
// webpack:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js
function createAppAPI(render, hydrate) {
return function createApp(rootComponent, rootProps = null) {
// 代码有删减
const installedPlugins = new Set();
const app = (context.app = {
use(plugin, ...options) {
// 已经有插件,并且 不是生产环境,报警告。
if (installedPlugins.has(plugin)) {
(process.env.NODE_ENV !== 'production') && warn(`Plugin has already been applied to target app.`);
}
// 插件的install 是函数,则添加插件,并执行 install 函数
else if (plugin && isFunction(plugin.install)) {
installedPlugins.add(plugin);
// 断点
plugin.install(app, ...options);
}
// 插件本身 是函数,则添加插件,并执行 插件本身函数
else if (isFunction(plugin)) {
installedPlugins.add(plugin);
plugin(app, ...options);
}
// 如果都不是报警告
else if ((process.env.NODE_ENV !== 'production')) {
warn(`A plugin must either be a function or an object with an "install" ` +
`function.`);
}
// 支持链式调用
return app;
},
provide(){
// 省略... 后文再讲
}
});
}
}
In the above code, the breakpoint line plugin.install(app, ...options);
Follow the breakpoint to the next step, the install
function.
4.4 install function
export class Store{
// 省略若干代码...
install (app, injectKey) {
// 为 composition API 中使用
// 可以传入 injectKey 如果没传取默认的 storeKey 也就是 store
app.provide(injectKey || storeKey, this)
// 为 option API 中使用
app.config.globalProperties.$store = this
}
// 省略若干代码...
}
Vuex4
in install
function of the relative ratio Vuex3
a lot simpler in.
The first sentence is for Composition API
. Inject into the root instance object.
The second sentence is for option API
.
Then break the two sentences, press F11
see the realization app.provide
4.4.1 app.provide
Is simply to context
of provides
attribute added store
= Store instance object .
provide(key, value) {
// 如果已经有值了警告
if ((process.env.NODE_ENV !== 'production') && key in context.provides) {
warn(`App already provides property with key "${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;
}
context
from the code above, you can find this code:
const context = createAppContext();
Then we look at the function createAppContext
.context
is the 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)
};
}
Vue3 document application configuration (app.config)
4.4.2 app.config.globalProperties
app.config.globalProperties official document
usage:
app.config.globalProperties.$store = {}
app.component('child-component', {
mounted() {
console.log(this.$store) // '{}'
}
})
It can also explain why each component can use this.$store.xxx
access the methods and properties in vuex
That is to appContext.provides
Store instance object is injected into 060a478394b94e. At this time, it is equivalent to the root component instance and config
global configuration globalProperties
with Store instance object .
So far we have finished reading, createStore(store)
, app.use(store)
two API
.
app.provide
is actually used for composition API
.
But this is just what the document says. Why is it accessible to every component instance? Let's continue to explore the principle in depth.
Next, let's look at the specific implementation of the source code and why it can be obtained in each component instance.
Prior to this first look at the combined API
in how we use Vuex4
, this is a clue.
4.5 How to use Vuex 4 in the 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()
// 我加的这行代码
window.ShoppingCartStore = store;
// 省略了若干代码
}
}
Then press F11
breakpoint, and single-step debugging, you will find that the Vue.inject
method is finally 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) {
return inject(key !== null ? key : storeKey)
}
4.5.2 Vue.inject source code implementation
Next, look at the inject
function and look at a lot of codes. In fact, the principle is very simple, that is, to find the value provide
If there is no parent, that is, the root instance, vnode.appContext.provides
in the instance object is taken.
Otherwise, take the value instance.parent.provides
In the source code of Vuex4
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
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];
}
// 如果参数大于1个 第二个则是默认值 ,第三个参数是 true,并且第二个值是函数则执行函数。
else if (arguments.length > 1) {
return treatDefaultAsFactory && isFunction(defaultValue)
? defaultValue()
: defaultValue;
}
// 警告没找到
else if ((process.env.NODE_ENV !== 'production')) {
warn(`injection "${String(key)}" not found.`);
}
}
// 如果没有当前实例则说明则报警告。
// 也就是是说inject必须在setup中调用或者在函数式组件中使用
else if ((process.env.NODE_ENV !== 'production')) {
warn(`inject() can only be used inside setup() or functional components.`);
}
}
Then we continue to look inject
the corresponding provide
.
4.5.3 Vue.provide source code implementation
provide
function of the 060a478394bb4b function is actually quite simple, 1. That is, add the key-value pair key/value
provides
object attribute on the current component instance.
2. Another function is that when the provides
of the current component and the parent component are the same, the provides
object in the current component instance and the parent will establish a link, which is the prototype [[prototype]]
( __proto__
).
// 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 type
provides[key] = value;
}
}
provide
in the 060a478394bbaf function may not be so easy to understand.
if (parentProvides === provides) {
provides = currentInstance.provides = Object.create(parentProvides);
}
Let's take an example to digest it.
var currentInstance = { provides: { store: { __state: 'Store实例' } } };
var provides = currentInstance.provides;
// 这句是我手动加的,在后文中则是创建实例时就是写的同一个对象,当然就会相等了。
var parentProvides = provides;
if(parentProvides === provides){
provides = currentInstance.provides = Object.create(parentProvides);
}
After executing this once, currentInstance
becomes like this.
{
provides: {
// 可以容纳其他属性,比如用户自己写的
__proto__ : { store: { __state: 'Store实例' } }
}
}
In the second execution, currentInstance
is:
{
provides: {
// 可以容纳其他属性,比如用户自己写的
__proto__: {
// 可以容纳其他属性,比如用户自己写的
__proto__ : { store: { __state: 'Store实例' } }
}
}
}
By analogy, execute provide
more times, the longer the prototype chain will be.
In the above inject
and provide
functions, there is a variable currentInstance
current instance, so how did the current instance object come from?
Why each component can be accessed, the idea of dependency injection.runtime-core.esm-bundler.js
is to search for provides
in the file 060a478394bc83, then you can search for the createComponentInstance
function
Next, how do we create a component instance with the createComponentInstance
4.6 createComponentInstance creates a component instance
You can disable other breakpoints, separate breakpoints here,
For example: const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
Look at the specific 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;
}
When you break the point, you will find that vnode
has been generated when the root component instance is generated. As for when it was generated, I have compiled a simplified version.
// 把上文中的 appContext 赋值给了 `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;
}
},
Among them, Object.create
is actually to establish a prototype relationship. Put a picture at this time, a picture is worth a thousand words.
It is from the column of Teacher Huang Yi Lagou. I wanted to draw a picture by myself, but I think this one is quite good.
4.6.1 The component instance is generated, how to combine them?
At this time, there is also a runtime-core.esm-bundler.js
method. In the 060a478394bd87 file, searching for provide(
can find the following code:
This code actually looks very complicated. In fact, it mainly provides
object or function return value written by the user in the component, and generates an instance object like this:
// 当前组件实例
{
parent: '父级的实例',
provides: {
// 可以容纳其他属性,比如用户自己写的
__proto__: {
// 可以容纳其他属性,比如用户自己写的
__proto__ : { store: { __state: 'Store实例' } }
}
}
}
// 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 可以是对象或者是函数
const provides = isFunction(provideOptions)
? provideOptions.call(publicThis)
: provideOptions;
Reflect.ownKeys(provides).forEach(key => {
provide(key, provides[key]);
});
});
}
// ...
}
app.provide
from top to bottom are injected into each component instance. At the same time, the provides
provided by the component itself has also been injected into the instance.
Then we followed the project to verify the statement above. Vue3
at the 060a478394be09 document, you can find that there is a API
to get the current component instance.
4.7 getCurrentInstance Get 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 // 访问 globalProperties
}
}
After knowing this API, we can add some code to the code of the shopping cart example. It is 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', '微信搜索「若川视野」关注我,专注前端技术分享。')
window.AppStore = store;
window.AppCurrentInstance = getCurrentInstance();
},
// vuex/examples/composition/shopping-cart/components/ProductList.vue
setup(){
const store = useStore()
// 若川加入的调试代码--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, '介绍-ProductList'); // 微信搜索「若川视野」关注我,专注前端技术分享。
// 若川加入的调试代码---end
}
// vuex/examples/composition/shopping-cart/components/ShoppingCart.vue
setup () {
const store = useStore()
// 若川加入的调试代码--start
window.ShoppingCartStore = store;
window.ShoppingCartCurrentInstance = getCurrentInstance();
provide('weixin', 'ruochuan12');
provide('weixin1', 'ruochuan12');
provide('weixin2', 'ruochuan12');
const mp = inject('ruochuan12');
console.log(mp, '介绍-ShoppingList'); // 微信搜索「若川视野」关注我,专注前端技术分享。
// 若川加入的调试代码--start
}
Output these values in the console
AppCurrentInstance
AppCurrentInstance.provides
ShoppingCartCurrentInstance.parent === AppCurrentInstance // true
ShoppingCartCurrentInstance.provides
ShoppingCartStore === AppStore // true
ProductListStore === AppStore // true
AppStore // store实例对象
Look at the example of the console screenshot output, which is actually similar to the one written above. At this time, if you write and inject a provide('store':'empty string') by store
, you must find the 060a478394bef0 written by the user first along the prototype chain. At this time, Vuex cannot be used normally, and an error is reported.
Of course, the injected vuex4
key
may not be store
, and there is no conflict with the user at this time.
export class Store{
// 省略若干代码...
install (app, injectKey) {
// 为 composition API 中使用
// 可以传入 injectKey 如果没传取默认的 storeKey 也就是 store
app.provide(injectKey || storeKey, this)
// 为 option API 中使用
app.config.globalProperties.$store = this
}
// 省略若干代码...
}
export function useStore (key = null) {
return inject(key !== null ? key : storeKey)
}
5. Answer the 5 questions raised at the beginning of the next
Unified answer to the 5 questions raised at the beginning:
1. Why is the attribute in the instance store
modified? After the change, the view update will be triggered.
A: Use Vue
in reactive
method for monitoring changes in the data.
class Store{
constructor (options = {}){
// 省略若干代码...
this._modules = new ModuleCollection(options)
const state = this._modules.root.state
resetStoreState(this, state)
// 省略若干代码...
}
}
function resetStoreState (store, state, hot) {
// 省略若干代码...
store._state = reactive({
data: state
})
// 省略若干代码...
}
2, Vuex4
as Vue
how and plug Vue
combination.
A: app.use(store)
be executed when Store
in install
methods, one is composition API
used, provided Store
instance of the object instance to the root. One sentence is injected into the global attributes of the root instance and is option API
in 060a478394bfd6. They will be injected into each component instance when the component is generated.
export class Store{
// 省略若干代码...
install (app, injectKey) {
// 为 composition API 中使用
// 可以传入 injectKey 如果没传取默认的 storeKey 也就是 store
app.provide(injectKey || storeKey, this)
// 为 option API 中使用
app.config.globalProperties.$store = this
}
// 省略若干代码...
}
3. provide
and inject
, and how to obtain Store
in the component instance for each component.
provide
written in the component can be obtained by the sub-component.
Answer: The provide
function establishes the prototype chain to distinguish the attributes written by the user of the component instance and the attributes injected by the system. inject
function uses the prototype chain to find provides
object in the parent instance.
// 有删减
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;
}
// 有删减
function inject(){
const provides = instance.parent == null
? instance.vnode.appContext && instance.vnode.appContext.provides
: instance.parent.provides;
if (provides && key in provides) {
return provides[key];
}
}
That is, an example like this:
// 当前组件实例
{
parent: '父级的实例',
provides: {
// 可以容纳其他属性,比如用户自己写的
__proto__: {
// 可以容纳其他属性,比如用户自己写的
__proto__ : { store: { __state: 'Store实例' } }
}
}
}
4. Why is there a Store
instance object in each component object (the process of rendering the component object).
Answer: When rendering a component instance, call createComponentInstance
and inject it into provides
of the component instance.
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;
}
- How do you know so much
Answer: Because someone in the community wrote Vue4
source code article .
6. Summary
This article mainly describes the Vuex4
of Store
injecting the 060a478394c1a0 instance into each component, Vuex3
on the change of the installation method of Vuex4
relative to Vuex.createStore
, app.use(store)
, and in-depth source code analysis Vue.inject
, Vue.provide
implementation principle.
Vuex4
addition to the installation and use of monitoring data changes in the way the Vue.reactive
, and other basic Vuex3.x
version makes no difference.
Finally, review the picture at the beginning of the article, which can be said to be the magical effect of the prototype chain.
Do you feel that it is suddenly clear.
Vuex
actually Vue
a plug-in, knowing the Vuex
principle, for himself to Vue
write plug-ins also will ease.
If readers find something improper or can be improved, or if there is no clear place, please comment and point out, and welcome to add me to ruochuan12
communicate. In addition, I feel that it is well written, and it is a little helpful to you. You can like, comment, forward and share. It is also a kind of support for me. Thank you very much. If you can pay attention to my front-end public Vision" 160a478394c25d, it would be even better.
on
Hello, I am , WeChat search Vision" 160a478394c2cd Follow me, focus on front-end technology sharing, a vision is to help the front-end to broaden its horizons to the forefront of the public account within 5 years. Welcome to add me on WeChatruochuan12
for long-term exchange and learning.
There are mainly the following series of articles: learning source code overall architecture series , annual summary , JS basic series
Reference link
Official website document Provide / Inject
github warehouse provide/inject source code
github warehouse provide/inject test
Vuex 4 official Chinese document
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。