vue3 createApp() 函数(千字长文)

Vue 3 中的 createApp() 函数

在 Vue 3 中,createApp() 是构建应用的起点,它替代了 Vue 2 中的 Vue 构造函数。如果你正在从 Vue 2 迁移,或者希望了解 Vue 3 的全新应用创建方式,那么理解 createApp() 函数至关重要。

核心概念

createApp() 是 Vue 3 的核心函数之一,用于创建一个可挂载的 Vue 应用实例。它接收一个根组件作为参数,并返回一个应用实例对象,该对象提供了 mount() 方法将组件挂载到 DOM 上。

Vue 3 采用组合式 API 和新的响应式系统,createApp() 是这一新架构的入口。通过它,你可以注册全局组件、指令、插件,以及配置应用的行为。

基础语法

创建一个 Vue 3 应用

最简单的用法如下:

const { createApp } = Vue;  // 从 Vue 中解构 createApp 函数

createApp({
  data() {
    return {
      message: 'Hello Vue 3!'
    };
  },
  template: `<h1>{{ message }}</h1>`  // 简单的模板
}).mount('#app');  // 将应用挂载到 id 为 app 的 DOM 元素上

使用脚本标签引入 Vue 3

如果你使用的是 CDN 引入方式,确保引入的是 Vue 3 的开发版或生产版:

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

挂载到 DOM 的过程

挂载是通过 mount() 方法完成的,它接受一个 DOM 选择器(如 #app)或 DOM 元素作为参数。挂载后,Vue 会接管该元素并将其作为应用的根容器。

进阶特性

全局注册组件

通过 createApp() 创建的应用实例,可以使用 component() 方法注册全局组件:

const app = createApp({ /* 根组件配置 */ });

// 全局注册一个组件
app.component('MyButton', {
  template: `<button>点击我</button>`
});

使用插件

Vue 3 支持插件机制,你可以通过 use() 方法将插件应用到当前实例:

app.use(VueRouter);  // 假设你已经导入了 VueRouter 插件

使用自定义指令

自定义指令在 Vue 3 中也通过 directive() 方法注册:

app.directive('focus', {
  mounted(el) {
    el.focus();  // 指令逻辑:在组件挂载时自动聚焦
  }
});

多实例支持

Vue 3 支持创建多个独立的应用实例,每个实例可以挂载到不同的 DOM 元素上:

const app1 = createApp({
  template: `<p>这是第一个应用</p>`
});
app1.mount('#app1');

const app2 = createApp({
  template: `<p>这是第二个应用</p>`
});
app2.mount('#app2');

实战应用

创建一个待办事项应用

下面是一个完整的 Vue 3 应用示例,使用 createApp() 创建一个简单的待办事项列表:

const { createApp, ref } = Vue;

createApp({
  setup() {
    const todos = ref([
      { text: '学习 Vue 3', done: false },
      { text: '写博客', done: false },
    ]);
    const newTodo = ref('');
    const addTodo = () => {
      if (newTodo.value.trim()) {
        todos.value.push({ text: newTodo.value, done: false });
        newTodo.value = '';
      }
    };
    return { todos, newTodo, addTodo };
  },
  template: `
    <div>
      <input v-model="newTodo" @keyup.enter="addTodo" placeholder="输入新任务" />
      <ul>
        <li v-for="(todo, index) in todos" :key="index">
          <input type="checkbox" v-model="todo.done" />
          <span :class="{ done: todo.done }">{{ todo.text }}</span>
        </li>
      </ul>
    </div>
  `
}).mount('#app');

使用 Vue Router 与 createApp

在 Vue 3 中,集成 Vue Router 时需要使用 createApp() 创建应用实例,然后使用 use() 方法注册 Router:

import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

const app = createApp({});

app.use(router);  // 使用 Vue Router 插件
app.mount('#app');

注意事项

不要混用 Vue 2 与 Vue 3 的 API

Vue 3 不再使用 Vue 2 的选项式 API 作为主要开发方式,虽然它仍然支持,但推荐使用组合式 API。createApp() 是 Vue 3 的 API,不能与 Vue 2 的 Vue.extend()new Vue() 一起使用。

避免重复挂载

确保一个应用实例不会被多次挂载到同一个 DOM 元素上,否则可能导致组件行为异常或内存泄漏。

不要遗漏 setup 函数

在组合式 API 中,setup() 是组件逻辑的核心入口。如果你在根组件中没有定义 setup(),某些响应式功能可能无法正常工作。

保持应用实例的唯一性

每个 createApp() 调用都会返回一个新的应用实例。如果你需要共享配置或状态,应考虑使用 Vue 的插件机制或 Pinia 状态管理库。

常见问题

Q1:为什么使用 createApp() 而不是 new Vue()?

在 Vue 3 中,createApp() 是用于创建应用的新 API,它返回一个应用实例对象,而不是 Vue 实例。Vue 3 引入了更清晰的模块化结构,createApp() 是这一结构的核心,提供了更好的组织方式和扩展性。

Q2:createApp() 和 mount() 的关系是什么?

createApp() 创建一个应用实例,mount() 则是将该实例挂载到 DOM 上。只有挂载后,组件才会被渲染并绑定响应式数据。

Q3:是否可以在 Vue 3 中使用多个 createApp 实例?

可以,Vue 3 支持多个独立应用实例同时运行。每个 createApp() 调用都会生成一个独立的实例,并通过 mount() 挂载到不同的 DOM 元素上。但应避免将多个实例挂载到同一个元素,这会导致冲突。

Q4:createApp() 是否必须使用 setup()?

不是必须,但推荐使用组合式 API。setup() 提供了更清晰的响应式逻辑组织方式,是 Vue 3 推荐的开发实践。

总结

createApp() 是 Vue 3 构建应用的核心函数,理解其用法和特性是掌握 Vue 3 的关键一步。本文通过基础语法、进阶特性和实际应用,展示了如何高效使用 createApp() 函数。