Skip to content

Первый рендеринг и API createApp

С чего начать? 🤔

Теперь давайте начнем пошагово реализовывать chibivue. Как нам следует подойти к реализации?

Вот о чем автор всегда думает при создании чего-то нового: сначала подумайте о том, как будет использоваться это программное обеспечение.
Для удобства назовем это "Интерфейсом разработчика".

Здесь "разработчик" относится к человеку, который разрабатывает веб-приложения с использованием chibivue, а не к разработчику самого chibivue.
Другими словами, давайте будем ссылаться на интерфейс разработчика оригинального Vue.js как на справочник при разработке chibivue.
В частности, давайте посмотрим, что нужно писать при разработке веб-приложений с помощью Vue.js.

Уровни интерфейса разработчика? 🤔

На что нужно обратить внимание, так это то, что Vue.js имеет несколько интерфейсов разработчика, каждый с разным уровнем. Здесь уровень относится к тому, насколько близко это к чистому JavaScript.
Например, вот примеры интерфейсов разработчика для отображения HTML с помощью Vue:

  1. Написать шаблон в однофайловом компоненте (Single File Component)
vue
<!-- App.vue -->
<template>
  <div>Hello world.</div>
</template>
ts
import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
app.mount('#app')
  1. Использовать опцию template
ts
import { createApp } from 'vue'

const app = createApp({
  template: '<div>Hello world.</div>',
})

app.mount('#app')
  1. Использовать опцию render и функцию h
ts
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.
Вместо этого начнем с реализации простой функции рендеринга, которая возвращает сообщение для отображения.

Изображение ↓

ts
import { createApp } from 'vue'

const app = createApp({
  render() {
    return 'Hello world.'
  },
})

app.mount('#app')

Сразу же реализуем

Давайте создадим функцию createApp в ~/packages/index.ts.
Примечание: Поскольку вывод "Hello, World" не нужен, мы удалим его.

ts
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

ts
import { createApp } from 'chibivue'

const app = createApp({
  render() {
    return 'Hello world.'
  },
})

app.mount('#app')

Мы смогли отобразить сообщение на экране! Отлично!

hello_createApp

Исходный код до этого момента:
chibivue (GitHub)

Released under the MIT License.