应用实例
每个 Vue 应用都是通过 createApp
函数创建一个新的应用实例开始的。
创建应用实例
import { createApp } from 'vue'
const app = createApp({
/* 根组件选项 */
})
根组件
我们传入 createApp
的对象实际上是一个组件,每个应用都需要一个"根组件",其他组件将作为其子组件。
import { createApp } from 'vue'
// 从一个单文件组件中导入根组件
import App from './App.vue'
const app = createApp(App)
如果你使用的是单文件组件,我们可以直接从另一个文件中导入根组件。
挂载应用
应用实例必须在调用了 .mount()
方法后才会渲染出来。该方法接收一个"容器"参数,可以是一个实际的 DOM 元素或是一个 CSS 选择器字符串:
<div id="app"></div>
app.mount('#app')
应用根组件的内容将会被渲染在容器元素里面。容器元素自己将不会被视为应用的一部分。
.mount()
方法应该始终在整个应用配置和资源注册完成后被调用。同时请注意,不同于其他资源注册方法,它的返回值是根组件实例而非应用实例。
应用配置
应用实例会暴露一个 .config
对象允许我们配置一些应用级的选项,例如定义一个应用级的错误处理器,用来捕获所有子组件上的错误:
app.config.errorHandler = (err) => {
/* 处理错误 */
}
应用实例还提供了一些方法来注册应用范围内可用的资源,例如注册一个组件:
app.component('TodoDeleteButton', TodoDeleteButton)
这使得 TodoDeleteButton
在应用的任何地方都是可用的。
多个应用实例
应用实例并不只限于一个。createApp
API 允许你在同一个页面中创建多个共存的 Vue 应用,而且每个应用都拥有自己的用于配置和全局资源的作用域。
const app1 = createApp({
/* ... */
})
app1.mount('#container-1')
const app2 = createApp({
/* ... */
})
app2.mount('#container-2')
如果你正在使用 Vue 来增强服务端渲染 HTML,并且只想要 Vue 去控制一个大型页面中特定的一小部分,应避免将一个单独的 Vue 应用实例挂载到整个页面上,而是应该创建多个小的应用实例,将它们分别挂载到所需的元素上去。
完整示例
基本示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 应用实例</title>
</head>
<body>
<div id="app">
<h1>{{ message }}</h1>
<button @click="changeMessage">改变消息</button>
</div>
<script src="https://unpkg.com/vue@next/dist/vue.global.js"></script>
<script>
const { createApp } = Vue
const app = createApp({
data() {
return {
message: 'Hello Vue!'
}
},
methods: {
changeMessage() {
this.message = this.message === 'Hello Vue!'
? 'Hello World!'
: 'Hello Vue!'
}
}
})
app.mount('#app')
</script>
</body>
</html>
使用单文件组件
// main.js
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
// 全局配置
app.config.globalProperties.$http = axios
app.config.errorHandler = (err) => {
console.error('全局错误:', err)
}
// 注册全局组件
app.component('MyButton', {
template: '<button><slot></slot></button>'
})
// 挂载应用
app.mount('#app')
<!-- App.vue -->
<template>
<div id="app">
<header>
<h1>{{ title }}</h1>
</header>
<main>
<Counter />
<UserList />
</main>
</div>
</template>
<script>
import Counter from './components/Counter.vue'
import UserList from './components/UserList.vue'
export default {
name: 'App',
components: {
Counter,
UserList
},
data() {
return {
title: '我的 Vue 应用'
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
</style>
应用级配置选项
errorHandler
用于为应用内抛出的未捕获错误指定一个全局处理函数。
app.config.errorHandler = (err, instance, info) => {
// 处理错误,例如:报告给一个服务
console.error('错误:', err)
console.error('组件实例:', instance)
console.error('错误信息:', info)
}
globalProperties
添加一个可以在应用的任何组件实例中访问的全局属性。
app.config.globalProperties.$http = axios
app.config.globalProperties.$translate = (key) => {
// 翻译逻辑
}
在组件中使用:
export default {
mounted() {
this.$http.get('/api/users').then(response => {
// 处理响应
})
}
}
performance
设置为 true
以在浏览器开发工具的性能/时间线面板中启用对组件初始化、编译、渲染和打补丁的性能追踪。
app.config.performance = true
应用 API
component()
注册或检索全局组件。
// 注册组件
app.component('MyComponent', {
template: '<div>A custom component!</div>'
})
// 检索组件
const MyComponent = app.component('MyComponent')
directive()
注册或检索全局指令。
// 注册指令
app.directive('focus', {
mounted(el) {
el.focus()
}
})
// 检索指令
const focusDirective = app.directive('focus')
use()
安装 Vue.js 插件。
import router from './router'
import store from './store'
app.use(router)
app.use(store)
mixin()
应用一个全局 mixin。
app.mixin({
created() {
console.log('全局 mixin 被调用')
}
})
provide()
提供一个值,可以在应用中的所有后代组件中注入使用。
app.provide('message', 'hello!')
在组件中注入:
export default {
inject: ['message'],
created() {
console.log(this.message) // 'hello!'
}
}
生命周期
应用实例的生命周期与组件生命周期不同。应用实例主要关注的是创建、配置和挂载的过程。
// 1. 创建应用实例
const app = createApp(App)
// 2. 配置应用
app.config.globalProperties.$api = api
app.use(router)
app.use(store)
// 3. 挂载应用
const vm = app.mount('#app')
// 4. 应用运行中...
// 5. 卸载应用(如果需要)
// app.unmount()
最佳实践
1. 应用配置集中管理
// config/app.js
export function configureApp(app) {
// 全局属性
app.config.globalProperties.$http = axios
// 错误处理
app.config.errorHandler = (err) => {
console.error('应用错误:', err)
}
// 性能监控(仅开发环境)
if (process.env.NODE_ENV === 'development') {
app.config.performance = true
}
}
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import { configureApp } from './config/app'
const app = createApp(App)
configureApp(app)
app.mount('#app')
2. 插件注册
// plugins/index.js
import router from '../router'
import store from '../store'
import i18n from '../i18n'
export function registerPlugins(app) {
app.use(router)
app.use(store)
app.use(i18n)
}
3. 全局组件注册
// components/global.js
import BaseButton from './BaseButton.vue'
import BaseInput from './BaseInput.vue'
import BaseModal from './BaseModal.vue'
export function registerGlobalComponents(app) {
app.component('BaseButton', BaseButton)
app.component('BaseInput', BaseInput)
app.component('BaseModal', BaseModal)
}
下一步
现在你已经了解了如何创建和配置 Vue 应用实例,让我们继续学习:
应用实例是 Vue 应用的基础,掌握它将帮助你更好地组织和管理你的应用!