предисловие
Расстояние от предыдущего постаРазминка интерпретации исходного кодаПрошло больше двух недель.Прошли Национальный день и Праздник Середины Осени.Всех с Праздником Середины Осени и Национальным Днем.Желаю вам никаких багов,не звоните в полицию онлайн,и уходите с работы пораньше каждый день.
Серия статей VUE3 будет объяснена вокруг папки. После завершения основной линии будет выполнена часть объяснения, и исходный код Vue3 будет прочитан и проанализирован один за другим согласно этому принципу.
текст
Здесь начинается текст, и здесь начинается путь к анализу исходного кода Vue3.
createApp
Способ создания приложения в Vue3 — через createApp, который в основном такой же, как и предыдущий метод нового Vue.
@file packages/runtime-dom/src/index.ts
export const createApp = ((...args) => {
const app = ensureRenderer().createApp(...args)
if (__DEV__) {
injectNativeTagCheck(app)
}
const { mount } = app
app.mount = (containerOrSelector: Element | string): any => {
const container = normalizeContainer(containerOrSelector)
if (!container) return
const component = app._component
if (!isFunction(component) && !component.render && !component.template) {
component.template = container.innerHTML
}
container.innerHTML = ''
const proxy = mount(container)
container.removeAttribute('v-cloak')
container.setAttribute('data-v-app', '')
return proxy
}
return app
}) as CreateAppFunction<Element>
Приведенный выше код createApp — это метод, который мы вызываем при создании приложения.
- sureRenderer — это функция одноэлементного режима, которая возвращает средство визуализации. Если средство визуализации отсутствует, она вызывает createRenderer для получения средства визуализации и получения экземпляра приложения;
- Зарегистрируйте метод в среде разработки: isNativeTag, смонтируйте его под app.config;
- Получите метод монтирования экземпляра и сохраните его;
- Переопределить метод монтажа экземпляра;
-
- Вызовите normalizeContainer, чтобы получить контейнер корневого элемента;
-
- Оцените шаблон и получите шаблон, который необходимо отрендерить;
-
- Очистите innerHTML контейнера;
-
- Вызовите метод монтирования вышеуказанного экземпляра;
-
- Удалите атрибут v-cloak и добавьте атрибут data-v-app;
-
- Действует после обратного крепления;
- вернуть экземпляр;
// 上面代码中所使用到的两个简单的函数源码
// @file packages/runtime-dom/src/index.ts
// 获取renderer
let renderer: Renderer<Element> | HydrationRenderer
function ensureRenderer() {
return renderer || (renderer = createRenderer<Node, Element>(rendererOptions))
}
// normalizeContainer,获取元素
function normalizeContainer(container: Element | string): Element | null {
if (isString(container)) {
return document.querySelector(container)
}
return container
}
На этом этапе объясняется метод createAPP. Ядро состоит из двух частей, первая часть — реализация вызова createRenderer, вторая часть — реализация метода монтирования экземпляра.
createRenderer
Как упоминалось выше, этот метод вызывается в createAPP для получения объекта рендерера Давайте посмотрим на его реализацию. createRenderer принимает параметр объекта rendererOptions,const rendererOptions = extend({ patchProp, forcePatchProp }, nodeOps)
NodeOps и node-ops в Vue2 имеют схожие функции, но они были оптимизированы в Vue3, добавлены патчи и клоны к nodeOps и удалены некоторые функции;
// @file packages/runtime-core/src/renderer.ts
export function createRenderer<HostNode = RendererNode,
HostElement = RendererElement>(options: RendererOptions<HostNode, HostElement>) {
return baseCreateRenderer<HostNode, HostElement>(options)
}
Реализация baseCreateRenderer выглядит следующим образом:
// @file packages/runtime-core/src/renderer.ts
function baseCreateRenderer(
options: RendererOptions,
createHydrationFns?: typeof createHydrationFunctions
): any {
// balabala,一堆函数的声明
return {
render,
hydrate,
createApp: createAppAPI(render, hydrate)
}
}
Вы можете видеть приведенный выше код, окончательный результат — это функция рендеринга, функция гидрата и функция createApp Функция createApp получается путем вызова createAppAPI.
// @file packages/runtime-core/src/apiCreateApp.ts
export function createAppContext(): AppContext {
return {
app: null as any,
config: {
isNativeTag: NO,
performance: false,
globalProperties: {},
optionMergeStrategies: {},
isCustomElement: NO,
errorHandler: undefined,
warnHandler: undefined
},
mixins: [],
components: {},
directives: {},
provides: Object.create(null)
}
}
export function createAppAPI<HostElement>(
render: RootRenderFunction,
hydrate?: RootHydrateFunction
): CreateAppFunction<HostElement> {
return function createApp(rootComponent, rootProps = null) {
if (rootProps != null && !isObject(rootProps)) {
__DEV__ && warn(`root props passed to app.mount() must be an object.`)
rootProps = null
}
const context = createAppContext()
const installedPlugins = new Set()
let isMounted = false
const app: App = (context.app = {
_uid: uid++,
_component: rootComponent as ConcreteComponent,
_props: rootProps,
_container: null,
_context: context,
version,
get config() {
return context.config
},
set config(v) {
if (__DEV__) {
warn(
`app.config cannot be replaced. Modify individual options instead.`
)
}
},
use() {},
mixin() {},
component() {},
directive() {},
mount() {},
unmount() {},
provide() {}
})
return app
}
}
Как указано выше, это исходный код CreateAppapi, и напрямую возвращает функцию Cretapp. CreateApp:
- Проверьте второй переданный параметр, который является root props;
- Вызовите createAppContext, чтобы создать объект appContext и присвоить его контексту;
- Создайте переменную InstallPlugins, Set type, для хранения установленных плагинов;
- isMounted имеет значение false;
- Создать приложение, смонтировать свойства и функции;
- вернуть приложение;
Приложение в настоящее время находится на стадии подготовки Vue, и функции, которые необходимо использовать, подготовлены для следующих операций, таких как монтирование.
mount
Самые основные (тривиальные) операции находятся в монтировании, которое включает в себя все основные функции Vnode, рендеринга, патча и так далее. Давайте сначала посмотрим на процесс вызова mount.
- Первый шаг: вызовите функцию монтирования в index.ts под runtime-dom;
- Шаг 2: Вызовите функцию монтирования в apiCreateApp под runtime-core;
Первые два шага аналогичны вызовам в Vue 2. Сначала вызывается монтирование, связанное с платформой, а затем вызывается монтирование, связанное с ядром;
- Шаг 3: вызов createVNode напрямую; в отличие от Vue2, 2 не вызывает напрямую, а создает наблюдатель, который вызывается, когда наблюдатель используется для вызова get, подробности можно увидетьИнтерпретация исходного кода Vue2 (семь) — крепление
- Шаг 4: Вызовите рендеринг, чтобы определить, следует ли удалить или рендерить;
- Шаг 5: Вызовите patch, выполните dom diff и визуализируйте страницу.
Эпилог
Эта статья представляет собой простое начало, а затем будет подробно проанализирована и интерпретирована часть крепления.
Дорога длинна и длинна, я буду ходить вверх и вниз искать
Я слышал, что компания React недавно выпустила официальную библиотеку управления состоянием для recoil, которая упрощает управление состоянием Я с нетерпением жду продолжения Vue.