1. app.component
1.1 基本概念
app.component 用于注册或获取全局组件。
// 注册全局组件
app.component('my-component', {
// 组件选项
props: ['title'],
template: `
<div class="my-component">
<h2>{{ title }}</h2>
<slot></slot>
</div>
`
})
// 获取已注册的组件
const MyComponent = app.component('my-component')
1.2 使用场景
- 注册常用基础组件
- 注册第三方组件库
- 创建可复用的通用组件
// 批量注册基础组件
import BaseButton from './components/BaseButton.vue'
import BaseInput from './components/BaseInput.vue'
import BaseCard from './components/BaseCard.vue'
const app = createApp(App)
app.component('BaseButton', BaseButton)
.component('BaseInput', BaseInput)
.component('BaseCard', BaseCard)
2. app.config
2.1 基本概念
app.config 用于配置应用级别的选项。
const app = createApp(App)
// 配置全局属性
app.config.globalProperties.$http = axios
app.config.globalProperties.$format = {
date(value) {
return new Date(value).toLocaleDateString()
}
}
// 配置错误处理
app.config.errorHandler = (err, vm, info) => {
console.error('全局错误:', err)
// 发送到错误追踪服务
}
// 配置警告处理
app.config.warnHandler = (msg, vm, trace) => {
console.warn('全局警告:', msg)
}
// 性能追踪
app.config.performance = true
2.2 使用场景
- 配置全局错误处理
- 添加全局属性和方法
- 配置性能追踪
- 自定义组件选项合并策略
3. app.directive
3.1 基本概念
app.directive 用于注册或获取全局自定义指令。
// 注册全局指令
app.directive('focus', {
mounted(el) {
el.focus()
}
})
// 带参数的指令
app.directive('color', {
mounted(el, binding) {
el.style.color = binding.value
},
updated(el, binding) {
el.style.color = binding.value
}
})
3.2 使用场景
- DOM 操作封装
- 复用常见的交互行为
- 第三方库集成
// 示例:点击外部关闭指令
app.directive('click-outside', {
mounted(el, binding) {
el._clickOutside = (event) => {
if (!(el === event.target || el.contains(event.target))) {
binding.value(event)
}
}
document.addEventListener('click', el._clickOutside)
},
unmounted(el) {
document.removeEventListener('click', el._clickOutside)
}
})
4. app.mount
4.1 基本概念
app.mount 用于将应用实例挂载到一个容器元素中。
// 基本用法
const app = createApp(App)
app.mount('#app')
// 带配置的挂载
app.mount('#app', true) // 强制挂载
// 自定义渲染器
const app = createApp(App)
app.mount('#app', false, (container) => {
// 自定义挂载逻辑
})
4.2 使用场景
- 应用初始化
- 动态挂载组件
- 多应用实例管理
5. app.unmount
5.1 基本概念
app.unmount 用于卸载应用实例。
const app = createApp(App)
app.mount('#app')
// 卸载应用
app.unmount()
5.2 使用场景
- 清理应用实例
- 动态切换应用
- 单页应用路由切换
6. app.use
6.1 基本概念
app.use 用于安装 Vue.js 插件。
// 基本用法
app.use(VueRouter)
app.use(Vuex)
// 带选项的插件安装
app.use(MyPlugin, {
option1: true,
option2: 'value'
})
// 自定义插件
const myPlugin = {
install(app, options) {
// 添加全局属性
app.config.globalProperties.$myPlugin = {
// 插件方法
}
// 注册全局组件
app.component('my-component', {
// 组件选项
})
// 注册全局指令
app.directive('my-directive', {
// 指令选项
})
}
}
app.use(myPlugin, { /* 选项 */ })
6.2 使用场景
- 安装路由插件
- 安装状态管理插件
- 安装UI组件库
- 安装自定义插件
7. 最佳实践
7.1 插件开发
// 创建插件
export default {
install(app, options = {}) {
// 注册全局组件
app.component('MyGlobalComponent', {/*...*/})
// 添加全局属性
app.config.globalProperties.$helper = {/*...*/}
// 注册全局指令
app.directive('my-directive', {/*...*/})
// 扩展应用实例
app.mixin({
created() {
// 混入逻辑
}
})
}
}
7.2 应用配置
// main.js
const app = createApp(App)
// 配置全局错误处理
app.config.errorHandler = (err) => {
console.error(err)
// 错误上报逻辑
}
// 注册全局组件
app.component('BaseButton', BaseButton)
// 注册全局指令
app.directive('focus', {/*...*/})
// 使用插件
app.use(router)
app.use(store)
// 挂载应用
app.mount('#app')
8. 注意事项
- 全局注册的影响
// ❌ 过度使用全局注册
app.component('MyComponent', {/*...*/})
// ✅ 按需注册
import MyComponent from './components/MyComponent.vue'
export default {
components: {
MyComponent
}
}
- 插件的依赖顺序
// ✅ 正确的插件安装顺序
app.use(router) // 先安装路由
.use(store) // 再安装状态管理
.use(myPlugin) // 最后安装自定义插件
- 性能考虑
// ✅ 合理使用全局配置
app.config.performance = process.env.NODE_ENV !== 'production'
9. 在组件中使用全局 API
9.1 使用全局组件
<!-- 使用全局注册的基础组件 -->
<template>
<div class="user-form">
<base-input
v-model="username"
label="用户名"
/>
<base-button @click="submit">
提交
</base-button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const username = ref('')
const submit = () => {
// 处理提交逻辑
}
</script>
9.2 使用全局配置
<!-- 使用全局属性和方法 -->
<template>
<div class="user-profile">
<p>注册时间: {{ $format.date(user.registerTime) }}</p>
<button @click="fetchData">刷新数据</button>
</div>
</template>
<script setup>
import { ref, getCurrentInstance } from 'vue'
// 获取全局属性
const { proxy } = getCurrentInstance()
const user = ref({})
const fetchData = async () => {
try {
// 使用全局配置的 http 实例
const response = await proxy.$http.get('/api/user')
user.value = response.data
} catch (error) {
// 全局错误处理会自动捕获
console.error(error)
}
}
</script>
9.3 使用全局指令
<!-- 使用全局自定义指令 -->
<template>
<div class="form-group">
<!-- 自动聚焦指令 -->
<input v-focus v-model="searchText">
<!-- 带参数的颜色指令 -->
<p v-color="'red'">这是红色文本</p>
<!-- 点击外部关闭指令 -->
<div
v-click-outside="closeDropdown"
class="dropdown"
>
<button @click="toggleDropdown">
打开下拉菜单
</button>
<div v-if="isOpen" class="dropdown-menu">
<!-- 下拉菜单内容 -->
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const searchText = ref('')
const isOpen = ref(false)
const toggleDropdown = () => {
isOpen.value = !isOpen.value
}
const closeDropdown = () => {
isOpen.value = false
}
</script>
9.4 动态组件挂载
<!-- 动态挂载组件示例 -->
<script setup>
import { h, render } from 'vue'
import NotificationComponent from './NotificationComponent.vue'
// 动态创建并挂载通知组件
const showNotification = (message, type = 'info') => {
// 创建容器
const container = document.createElement('div')
document.body.appendChild(container)
// 创建虚拟节点
const vnode = h(NotificationComponent, {
message,
type,
onClose: () => {
// 清理组件
render(null, container)
container.remove()
}
})
// 渲染组件
render(vnode, container)
}
// 使用方法
const handleClick = () => {
showNotification('操作成功!', 'success')
}
</script>
9.5 插件功能使用
<!-- 使用插件提供的功能 -->
<template>
<div class="plugin-demo">
<!-- 使用插件注册的全局组件 -->
<my-component />
<!-- 使用插件提供的指令 -->
<div v-my-directive="options">
<!-- 内容 -->
</div>
<!-- 使用插件提供的方法 -->
<button @click="handleAction">
执行插件方法
</button>
</div>
</template>
<script setup>
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const handleAction = () => {
// 调用插件提供的方法
proxy.$myPlugin.doSomething()
}
// 使用插件提供的配置
const options = {
// 插件选项
}
</script>
9.6 组合式 API 中的使用
<script setup>
import { onMounted, inject } from 'vue'
// 注入插件提供的数据
const theme = inject('theme', 'light')
// 使用插件提供的组合式函数
const { useMyFeature } = inject('myPlugin')
const { data, methods } = useMyFeature()
onMounted(() => {
// 使用插件功能
methods.initialize()
})
</script>
9.7 实际应用示例
<!-- 完整的表单组件示例 -->
<template>
<div class="advanced-form">
<!-- 使用全局基础组件 -->
<base-card>
<template #header>
<h2>{{ $t('form.title') }}</h2>
</template>
<base-form
v-model="formData"
:rules="validationRules"
>
<base-input
v-model="formData.name"
v-focus
:label="$t('form.name')"
/>
<base-select
v-model="formData.type"
:options="typeOptions"
/>
<!-- 使用自定义指令 -->
<div
v-click-outside="closePopover"
class="help-section"
>
<base-button @click="toggleHelp">
{{ $t('form.help') }}
</base-button>
<div v-if="showHelp" class="popover">
<!-- 帮助内容 -->
</div>
</div>
</base-form>
<template #footer>
<base-button
type="primary"
@click="handleSubmit"
>
{{ $t('form.submit') }}
</base-button>
</template>
</base-card>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useForm } from '@/composables/form'
// 使用插件提供的功能
const { t } = useI18n()
const { validateForm } = useForm()
// 表单数据
const formData = ref({
name: '',
type: ''
})
// 帮助弹窗状态
const showHelp = ref(false)
// 选项数据
const typeOptions = computed(() => [
{ label: t('options.type1'), value: 'type1' },
{ label: t('options.type2'), value: 'type2' }
])
// 验证规则
const validationRules = {
name: [
{ required: true, message: t('validation.nameRequired') }
],
type: [
{ required: true, message: t('validation.typeRequired') }
]
}
// 方法
const toggleHelp = () => {
showHelp.value = !showHelp.value
}
const closePopover = () => {
showHelp.value = false
}
const handleSubmit = async () => {
try {
// 验证表单
await validateForm(formData.value)
// 提交数据
await proxy.$http.post('/api/submit', formData.value)
// 显示成功提示
proxy.$notify({
type: 'success',
message: t('messages.submitSuccess')
})
} catch (error) {
// 错误会被全局错误处理捕获
console.error(error)
}
}
</script>
<style scoped>
.advanced-form {
max-width: 600px;
margin: 0 auto;
}
.help-section {
position: relative;
margin-top: 1rem;
}
.popover {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
/* 其他样式 */
}
</style>
这个完整示例展示了如何在实际组件中综合使用各种全局 API 和功能,包括:
- 全局基础组件
- 自定义指令
- 全局属性和方法
- 插件提供的功能
- 国际化支持
- 表单验证
- HTTP 请求
- 通知提示
- 错误处理