应用实例

Vitarx 应用的起点是创建一个应用实例。应用实例是整个应用的核心,负责将根组件挂载到 DOM、管理全局配置、注册指令、提供依赖注入以及安装插件。

createApp — 创建应用

createApp 是创建应用的入口函数,接收一个根组件和可选的配置对象,返回一个应用实例。

typescript
declare function createApp(root: Component | View, config?: AppConfig): App
  • root:根组件或视图对象,即应用的顶层函数组件或视图对象
  • config:可选的应用配置,包含 errorHandleridPrefix
tsx
import { createApp } from 'vitarx'

function App() {
  return <div>Hello Vitarx!</div>
}

// 创建应用实例
const app = createApp(App)

// 创建时传入配置
const app2 = createApp(App, {
  errorHandler: (error, info) => {
    console.error('全局错误:', error)
  },
  idPrefix: 'my-app'
})

app.mount — 挂载应用

mount 将应用挂载到指定的 DOM 容器中。支持传入 DOM 元素或 CSS 选择器字符串。

typescript
app.mount(container: Element | string): this

mount 返回应用实例本身,支持链式调用。

tsx
import { createApp } from 'vitarx'

function App() {
  return <div>Hello Vitarx!</div>
}

const app = createApp(App)

// 通过 CSS 选择器挂载
app.mount('#app')

// 通过 DOM 元素挂载
app.mount(document.getElementById('app')!)

// 链式调用
createApp(App).mount('#app')

app.unmount — 卸载应用

unmount 会卸载应用,释放所有资源,包括组件树、副作用和 DOM 节点。

typescript
app.unmount(): void
tsx
import { createApp } from 'vitarx'

function App() {
  return <div>Hello</div>
}

const app = createApp(App)
app.mount('#app')

// 5 秒后卸载应用
setTimeout(() => {
  app.unmount()
}, 5000)

app.config — 配置对象

config 是应用的全局配置对象,包含以下属性:

属性类型默认值说明
errorHandler(error: unknown, info: ErrorInfo) => void控制台打印错误全局错误处理函数
idPrefixstring'v'useId() 生成的 ID 前缀
tsx
import { createApp } from 'vitarx'

function App() {
  return <div>Hello</div>
}

const app = createApp(App, {
  // 自定义全局错误处理器
  errorHandler: (error, info) => {
    console.error(`[#123;info.source}]`, error)
    // 可以在这里上报错误到监控平台
  },
  // 自定义 ID 前缀,useId() 将生成 my-0、my-1 ...
  idPrefix: 'my'
})

app.mount('#app')

config 是只读的,创建应用后不能重新赋值,但 config.errorHandler 可以直接修改。

app.version — 版本号

version 返回当前 Vitarx 的版本号字符串。

typescript
readonly version: string
tsx
import { createApp } from 'vitarx'

const app = createApp(App)
console.log('Vitarx 版本:', app.version)

app.rootView — 根视图

rootView 返回应用的根视图对象,即根组件对应的视图实例或者构造函数传入的根视图。

typescript
readonly rootView: View

一般不需要直接操作根视图,它主要用于框架内部或高级场景。

app.directive — 注册/获取指令

directive 用于注册或获取自定义指令,支持链式调用。

typescript
// 注册指令,返回 this(支持链式调用)
app.directive(name: string, directive: Directive): this

// 获取已注册的指令
app.directive(name: string): Directive | undefined
tsx
import { createApp } from 'vitarx'

// 定义一个自动聚焦指令
const focusDirective = {
  mounted(el: HTMLElement) {
    el.focus()
  }
}

const app = createApp(App)

// 注册指令
app.directive('focus', focusDirective)

// 链式注册多个指令
app.directive('focus', focusDirective).directive('lazy', lazyDirective)

// 获取已注册的指令
const existing = app.directive('focus')

注册后的指令可以在模板中通过 v-focus 等方式使用。

app.provide — 应用级依赖注入

provide 在应用级别提供依赖数据,所有组件都可以通过 inject 获取。返回应用实例,支持链式调用。

typescript
app.provide(name: string | symbol, value: unknown): this
tsx
import { createApp } from 'vitarx'

const app = createApp(App)

// 提供全局 API 客户端
app.provide('apiBase', 'https://api.example.com')

// 提供全局配置对象
app.provide('config', { theme: 'dark', locale: 'zh-CN' })

// 链式调用
app.provide('apiBase', 'https://api.example.com').provide('config', { theme: 'dark' })

应用级依赖的优先级低于组件级依赖。当两者提供相同名称的依赖时,组件级优先。

app.inject — 获取注入值

inject 获取应用级提供的依赖数据。通常在组件中使用 inject 函数,app.inject 主要用于插件中获取其他插件提供的依赖。

typescript
app.inject<T>(name: string | symbol, defaultValue?: T): T
tsx
import { createApp } from 'vitarx'

const app = createApp(App)
app.provide('apiBase', 'https://api.example.com')

// 获取已提供的依赖
const apiBase = app.inject<string>('apiBase') // 'https://api.example.com'

// 获取不存在的依赖,返回默认值
const missing = app.inject<string>('missing', 'default-value')

app.hasProvide — 检查依赖是否存在

hasProvide 检查应用级别是否提供了指定名称的依赖。

typescript
app.hasProvide(name: string | symbol): boolean
tsx
import { createApp } from 'vitarx'

const app = createApp(App)
app.provide('apiBase', 'https://api.example.com')

app.hasProvide('apiBase') // true
app.hasProvide('unknown') // false

app.use — 安装插件

use 安装一个插件,插件可以是一个函数或带有 install 方法的对象。返回应用实例,支持链式调用。

typescript
app.use<T extends {}>(plugin: AppPlugin<T>, options?: T): this
tsx
import { createApp } from 'vitarx'

const app = createApp(App)

// 安装函数式插件
app.use(myPlugin, { prefix: 'my' })

// 安装对象式插件
app.use(routerPlugin, { routes: [...] })

// 链式安装多个插件
app
  .use(pluginA)
  .use(pluginB, { option: true })

关于插件的详细用法,请参阅插件系统

多应用实例

Vitarx 支持在同一页面创建多个应用实例,每个实例拥有独立的配置、指令、依赖注入和插件。它们互不干扰。

tsx
import { createApp } from 'vitarx'

function App1() {
  return <div>应用 1</div>
}

function App2() {
  return <div>应用 2</div>
}

// 创建两个独立的应用实例
const app1 = createApp(App1, { idPrefix: 'app1' })
const app2 = createApp(App2, { idPrefix: 'app2' })

// 分别挂载到不同的容器
app1.mount('#app1')
app2.mount('#app2')

// 各自拥有独立的依赖注入
app1.provide('theme', 'dark')
app2.provide('theme', 'light')

完整示例

下面是一个展示应用实例核心 API 的完整示例:

tsx
import { createApp, inject, ref } from 'vitarx'

// 自动聚焦指令
const focusDirective = {
  mounted(el: HTMLElement) {
    el.focus()
  }
}

// 简单的日志插件
function loggerPlugin(app, options) {
  const prefix = options?.prefix ?? '[App]'
  app.provide('logger', {
    info: (msg) => console.log(`#123;prefix} #123;msg}`),
    error: (msg) => console.error(`#123;prefix} #123;msg}`)
  })
}

// 根组件
function App() {
  const logger = inject<{ info: (msg: string) => void }>('logger')
  const count = ref(0)

  const handleClick = () => {
    count.value++
    logger?.info(`计数器:#123;count.value}`)
  }

  return (
    <div>
      <h1>Vitarx 应用示例</h1>
      <p>当前计数:{count}</p>
      <input v-focus placeholder="自动聚焦的输入框" />
      <button onClick={handleClick}>+1</button>
    </div>
  )
}

// 创建应用并配置
const app = createApp(App, {
  errorHandler: (error, info) => {
    console.error(`[#123;info.source}] 发生错误:`, error)
  },
  idPrefix: 'demo'
})

// 注册指令
app.directive('focus', focusDirective)

// 安装插件
app.use(loggerPlugin, { prefix: '[Demo]' })

// 挂载应用
app.mount('#app')

下一步