Первый рендеринг и API createApp
С чего начать? 🤔
Теперь давайте начнем пошагово реализовывать chibivue. Как нам следует подойти к реализации?
Вот о чем автор всегда думает при создании чего-то нового: сначала подумайте о том, как будет использоваться это программное обеспечение.
Для удобства назовем это "Интерфейсом разработчика".
Здесь "разработчик" относится к человеку, который разрабатывает веб-приложения с использованием chibivue, а не к разработчику самого chibivue.
Другими словами, давайте будем ссылаться на интерфейс разработчика оригинального Vue.js как на справочник при разработке chibivue.
В частности, давайте посмотрим, что нужно писать при разработке веб-приложений с помощью Vue.js.
Уровни интерфейса разработчика? 🤔
На что нужно обратить внимание, так это то, что Vue.js имеет несколько интерфейсов разработчика, каждый с разным уровнем. Здесь уровень относится к тому, насколько близко это к чистому JavaScript.
Например, вот примеры интерфейсов разработчика для отображения HTML с помощью Vue:
- Написать шаблон в однофайловом компоненте (Single File Component)
<!-- App.vue -->
<template>
<div>Hello world.</div>
</template>
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
- Использовать опцию template
import { createApp } from 'vue'
const app = createApp({
template: '<div>Hello world.</div>',
})
app.mount('#app')
- Использовать опцию render и функцию h
import { createApp, h } from 'vue'
const app = createApp({
render() {
return h('div', {}, ['Hello world.'])
},
})
app.mount('#app')
Есть и другие варианты, но давайте рассмотрим эти три интерфейса разработчика.
Какой из них ближе всего к чистому JavaScript? Ответ: "использование опции render и функции h" (вариант 3).
Вариант 1 требует реализации компилятора SFC и сборщика (или загрузчика), а вариант 2 требует компиляции HTML, переданного в шаблон (преобразование его в JavaScript-код), чтобы он заработал.
Для удобства назовем интерфейс разработчика, который ближе к чистому JS, "низкоуровневым интерфейсом разработчика".
И важно здесь "начать реализацию с низкоуровневой части".
Причина в том, что во многих случаях высокоуровневые описания преобразуются в низкоуровневые описания и выполняются.
Другими словами, и вариант 1, и вариант 2 в конечном итоге внутренне преобразуются в форму варианта 3.
Реализация этого преобразования называется "компилятором".
Итак, давайте начнем с реализации интерфейса разработчика, как в варианте 3!
API createApp и рендеринг
Хотя мы стремимся к форме варианта 3, мы все еще не хорошо понимаем функцию h, и поскольку эта книга нацелена на инкрементную разработку, давайте не будем сразу стремиться к форме варианта 3.
Вместо этого начнем с реализации простой функции рендеринга, которая возвращает сообщение для отображения.
Изображение ↓
import { createApp } from 'vue'
const app = createApp({
render() {
return 'Hello world.'
},
})
app.mount('#app')
Сразу же реализуем
Давайте создадим функцию createApp в ~/packages/index.ts
.
Примечание: Поскольку вывод "Hello, World" не нужен, мы удалим его.
export type Options = {
render: () => string
}
export type App = {
mount: (selector: string) => void
}
export const createApp = (options: Options): App => {
return {
mount: selector => {
const root = document.querySelector(selector)
if (root) {
root.innerHTML = options.render()
}
},
}
}
Это очень просто. Давайте попробуем это в playground.
~/examples/playground/src/main.ts
import { createApp } from 'chibivue'
const app = createApp({
render() {
return 'Hello world.'
},
})
app.mount('#app')
Мы смогли отобразить сообщение на экране! Отлично!
Исходный код до этого момента:
chibivue (GitHub)