全局API
应用实例
createApp()
createApp():(rootComponent, rootProps?)
,用于创建一个 Vue 应用实例,是 Vue 3 应用开发的入口函数。
rootComponent:
options | Component
,根组件,Vue 应用的入口组件。options
:{data,methods,...}
,选项式API中的组件选项。Component
:组合式API中包含setup()
方法的组件对象。
rootProps?:
Record<string, any>
,传递给根组件的props
对象,用于父组件向根组件传递数据。返回:
app:
App
,返回的Vue应用实例,提供多个用于配置和控制应用的实例方法。示例:
- script setup
jsimport { createApp } from 'vue' import App from './App.vue' import store from './store' import router from './router' import icons from './utils/register-icons' const app = createApp(App) app.use(store) app.use(router) app.use(icons) app.mount('#app')
特性:
TS:
tsfunction createApp(rootComponent: Component, rootProps?: object): App
TS:使用
defineComponent()
增强类型推断。tsimport { defineComponent } from 'vue'; const RootComponent = defineComponent({ data() { return { count: 0 }; } }); const app = createApp(RootComponent) app.mount('#app')
app.use()
app.use():(plugin,...options?)
,用于为 Vue 应用安装插件(如 Vue Router、Pinia等)或自定义功能扩展。
plugin:
Object | Function
,插件对象或函数。Object
:必须包含install()
方法。Function
:直接作为install()
方法调用。
...options?:
any[]
,传递给插件install
方法的额外参数(如插件配置项)。返回:
app:
App
,返回应用实例本身,支持链式调用。示例:
- 安装 Vue Router
jsimport { createApp } from 'vue'; import App from './App.vue'; import VueRouter from 'vue-router'; // 假设已安装 vue-router@4 const app = createApp(App); // 安装路由插件,并传递路由配置 const router = VueRouter.createRouter({ /* ...路由配置 */ }); app.use(router);
app.mount('#app'); 特性:
TS:
tsinterface App { use(plugin: Plugin, ...options: any[]): this }
自定义插件开发:插件必须提供
install()
方法(或自身为函数)。js// 1. 自定义插件(含 install 方法) const MyPlugin = { + install(app, options) { // 添加全局组件 app.component('CustomHeader', { template: `<header>{{ title }}</header>`, props: ['title'] }); // 添加全局属性 app.config.globalProperties.$log = (msg) => console.log(msg); } }; // 2. 使用插件并传递配置 const app = Vue.createApp({}); + app.use(MyPlugin, { debug: true }); // options 参数会传递给 install 方法 // 3. 使用插件功能 app.component('DemoComponent', { mounted() { + this.$log('Component mounted!'); // 调用全局属性 } });
app.mount()
app.mount():(containerSelector | element)
,将 Vue 应用实例挂载到 DOM 元素。
containerSelector:
string
,CSS 选择器字符串(如'#app'
),指定挂载的容器元素。element:
Element
,直接传入 DOM 元素对象(如document.getElementById('app')
)。返回:
instance:
ComponentPublicInstance
,返回根组件实例,可通过该实例访问组件属性/方法。示例:
- 挂载 app
jsimport { createApp } from 'vue'; import App from './App.vue'; // 创建应用实例 const app = createApp(App); // 挂载到 #app 元素 const rootInstance = app.mount('#app'); // 访问根组件数据 console.log(rootInstance.someData);
特性:
TS:
tsinterface App { mount(rootContainer: Element | string): ComponentPublicInstance }
TS类型注解:可以给instance添加TS类型注解。
tsinterface RootComponentInstance { someMethod: () => void } const instance = app.mount('#app') as unknown as RootComponentInstance;
选项式:
js// 1. Vue2选项式写法:自动挂载 new Vue({ el: '#app', // 自动挂载 render: h => h(App) }); // 2.Vue2选项式写法:手动挂载 const vm = new Vue({ render: h => h(App) }).$mount('#app'); // 等价于 app.mount()
挂载时机:需确保 DOM 已加载完成(通常在
DOMContentLoaded
事件后调用)。单次挂载限制:每个应用实例只能挂载一次,重复调用
.mount()
会抛出警告。SSR差异:服务端渲染时应使用
createSSRApp
+hydrate
而非直接mount
。访问实例:不推荐,通过返回的实例可直接操作组件的属性和方法。推荐优先使用 props/emits 通信。
app.component()
app.component():(name,component?)
,用于全局注册或获取组件。
name:
string
,组件的名称。命名遵循camelCase或kebab-case。component?:
Component
,包含组件配置的对象。返回:
- app:
App
,当传递component
参数时,表示注册全局组件。返回app,支持链式调用。 - component:
Component|undefined
,当省略component
参数时,表示获取已注册的组件。返回已注册的组件,未找到则返回undefined
。
- app:
示例:
- 注册/获取全局组件
jsimport { createApp } from 'vue' const app = createApp({}) // 1. 全局注册一个按钮组件 app.component('custom-button', { template: ` <button class="btn"> <slot></slot> </button> ` }) // 2. 获取已注册的组件 const cpn = app.component('custom-button')
特性:
TS:
tsinterface App { component(name: string): Component | undefined component(name: string, component: Component): this }
app.directive()
app.directive():(name, directive?)
,用于注册或获取全局自定义指令。
name:
string
,指令的名称。命名通常遵循kebab-case。directive?:
{mounted,...}
,包含指令定义的对象。指令定义在不同的生命周期钩子中,控制指令在不同阶段的行为。返回:
app:
App
,返回app,支持链式调用。示例:
- 自定义指令 v-focus
jsconst app = createApp(App); // 1. 自定义指令:`v-focus`,使元素获得焦点 const focusDirective = { mounted(el) { el.focus(); } }; // 2. 注册全局指令 app.directive('focus', focusDirective); app.mount('#app');
特性:
TS:
tsinterface App { directive(name: string): Directive | undefined directive(name: string, directive: Directive): this }
选项式:
jsimport { createApp } from 'vue'; const App = { // 1. 注册局部指令 directives: { focus: { mounted(el) { el.focus(); // 元素插入时获得焦点 } } }, template: ` <div> <input v-focus /> </div> ` }; createApp(App).mount('#app');
app.mixin()
app.mixin():(mixin)
,用来全局注册一个混入对象。会将该对象的所有组件选项(data,methods,...
)合并到每个组件中。
mixin:
{data,methods,...}
,该对象的组件选项会被合并到每个组件的选项中。返回:
app:
App
,返回app,支持链式调用。示例:
- 全局混入对象
jsconst globalMixin = { data() { return { mixinData: 'This is data from mixin', }; }, created() { console.log('Mixin created hook'); }, methods: { greet() { console.log('Hello from mixin method'); } } };
const app = Vue.createApp(App); // 2. 注册全局混入对象 app.mixin(globalMixin); app.mount('#app'); - 局部混入对象
jsconst localMixin = { data() { return { localMessage: 'This is local mixin data', }; } };
const app = Vue.createApp({ // 2. 注册局部混入对象 mixins: [localMixin], template: '<p>{{ localMessage }}</p>' }); app.mount('#app'); 特性:
TS:
tsinterface App { mixin(mixin: ComponentOptions): this }
生命周期钩子的合并:如果定义了多个相同的生命周期钩子,这些钩子会被合并,并按顺序依次调用。
数据合并:
- 如果data选项是一个函数,组件和混入中的data的返回值会被合并(推荐)。
- 如果data选项是一个普通对象,会出现合并冲突。
方法覆盖:组件的方法会覆盖混入中的方法。
不推荐:Mixins 在 Vue 3 支持主要是为了向后兼容,因为生态中有许多库使用到。在新的应用中应尽量避免使用 mixin,特别是全局 mixin。若要进行逻辑复用,推荐用组合式函数来替代。
通用
nextTick()
nextTick():(callback?)
,通常用来在下一次 DOM 更新刷新后执行某些操作。
callback?:
() => void
,在 DOM 更新后执行的回调函数。返回:
result:
Promise<void>
,在DOM更新完成后解析。示例:
- 在watch或onMounted中使用
jsimport { ref, watch, nextTick } from 'vue'; const count = ref(0); // 在watch或onMounted中使用 watch(count, async () => { await nextTick(); console.log('count 更新后,DOM 渲染完成'); });
- 与异步操作结合
jsimport { ref, nextTick } from 'vue'; const count = ref(0); const updateAndWait = async () => { count.value++; // 与异步操作结合 await nextTick(); console.log('DOM 更新后进行的操作'); };
特性:
TS:
tsfunction nextTick(callback?: () => void): Promise<void>
性能:
nextTick()
可能会影响性能,特别是在高频更新的情况下会造成任务队列拥挤。用途:
nextTick()
主要是为了解决 Vue 的异步渲染机制。在Vue内部,数据更新是异步的,DOM更新会在下一个“tick”内完成。