Vue 项目全局资源注册与页面渲染完整流程
一、Vue 项目启动执行完整流程
1、index.html → 2、加载 main.js → 3、导入各类核心资源 → 4、创建 app 实例 → 5、注册插件/全局组件/自定义指令 → 6、挂载 DOM,渲染 App.vue
二、步骤详解
1. 入口文件:index.html
项目页面渲染容器,提供 <div id="app"></div> 挂载节点,是 Vue 组件渲染的载体。
2. 执行项目入口:main.js
整个 Vue 项目的启动入口,负责导入资源、创建应用实例、注册全局插件、最终挂载渲染页面。
3. 导入核心资源与全局依赖
在创建 Vue 实例前,统一导入 Vue API、根组件、样式、路由、状态管理、UI 库、工具脚本、全局组件等所有前置资源。
js
// 1.导入Vue核心API
import { createApp } from "vue";
// 2.导入根组件App
import App from "./App.vue";
// 3.导入全局样式
import "./style.scss";
// 导入路由、状态管理
import router from "./router";
import store from "./store";
// 导入页面适配工具
import './utils/rem.js';
// 导入全局公共组件、UI组件库、图标库
import PublicComponents from './components/common/index';
import ArcoVue from "@arco-design/web-vue";
import ArcoVueIcon from "@arco-design/web-vue/es/icon";
import "@arco-design/web-vue/dist/arco.css";
// 导入svg图标自动注册脚本
import "virtual:svg-icons-register";
4. 创建独立 Vue 应用实例
通过 createApp 基于根组件 App.vue 创建唯一的应用实例,此时仅初始化实例,未渲染页面。
js
const app = createApp(App);
5. 注册全局插件、组件、自定义指令
实例创建完成后,统一注册所有全局资源,包含 UI 插件、全局组件、自定义指令等。
js
// 注册ArcoDesign UI插件,统一设置组件默认尺寸
app.use(ArcoVue, {size: 'small'}).use(ArcoVueIcon);
// 执行自定义指令初始化函数,传入app实例批量注册指令
directive(app);
5.1 单指令直接注册(main.js 内原生写法)
直接在 main.js 中通过 app.directive 注册全局指令,以 v-copy 复制指令为例。
js
// 注册 v-copy 全局复制自定义指令
app.directive('copy', {
mounted(el, binding) {
// 绑定元素点击事件
el.addEventListener('click', async () => {
// 获取指令绑定的复制文本
const text = binding.value
if (!text) {
alert('暂无复制内容')
return
}
try {
// 浏览器原生剪贴板API
await navigator.clipboard.writeText(text)
alert('复制成功!')
} catch (err) {
console.error('复制失败', err)
alert('复制失败,请手动复制')
}
})
}
});
模板使用方式
vue
<template>
<span v-copy="value"> {{ value }} </span>
</template>
5.2 全局指令两种注册方式对比
方式一:main.js 直接注册(不抽离插件)
适合小型项目、少量指令,代码直观、无需新建额外文件。
js
import { createApp } from 'vue'
import App from './App.vue'
// 导入单个指令
import copy from './directives/copy'
const app = createApp(App)
// 直接全局注册指令
app.directive('copy', copy)
app.mount('#app')
方式二:封装插件 + app.use() 注册(工程化写法)
将所有指令统一封装为插件,通过 install 钩子批量注册,适合中大型项目。
1)新建指令插件文件 plugins/directive.js
js
import copy from '../directives/copy'
// 标准Vue插件格式:暴露install方法
export default {
install(app) {
// 底层依旧调用app.directive完成注册
app.directive('copy', copy)
// 可继续批量新增其他指令
}
}
2)main.js 引入并使用插件
js
import { createApp } from 'vue'
import App from './App.vue'
// 导入指令插件
import directivePlugin from './plugins/directive'
const app = createApp(App)
// 一键注册所有封装的全局指令
app.use(directivePlugin)
app.mount('#app')
5.3 底层原理
app.use(插件) 会自动执行插件暴露的 install(app) 函数,插件内部本质依然是调用 app.directive() 完成指令注册。
两种写法底层注册API完全一致,页面使用 v-copy 效果无任何区别。
5.4 两种注册方式优缺点与适用场景
1)main.js 直接注册
✅ 优点:代码直观,无需新增文件,小型项目开发更省事
❌ 缺点:
-
指令数量变多后,main.js 代码臃肿杂乱
-
全局指令、路由、状态管理、网络请求等逻辑全部堆砌在入口文件,不利于分类维护
-
指令无法单独复用,其他项目使用需要手动复制零散代码
适用场景:小型 demo、简单页面项目、仅1-2个自定义指令
2)插件封装 + app.use() 注册(企业项目推荐)
✅ 优点:
-
分层解耦:指令统一收纳在独立插件文件,保持 main.js 简洁清爽
-
批量管理:新增 focus、权限、拖拽等指令,仅需修改插件文件,无需改动入口
-
可复用性强:插件可单独抽离为工具模块,供多个项目复用
-
生态规范:Element Plus、Vant 等主流 Vue UI 库均采用该规范
❌ 缺点:需要新建层级文件,极简小项目略显繁琐
适用场景:后台管理系统、多页面项目、指令数量≥3个、长期迭代维护的项目
5.5 批量注册多指令效果对比
臃肿写法(直接写在main.js)
js
import copy from './directives/copy'
import focus from './directives/focus'
import permission from './directives/permission'
app.directive('copy', copy)
app.directive('focus', focus)
app.directive('permission', permission)
优雅写法(插件批量注册)
插件统一管理:
js
// directive插件统一批量注册所有指令
import copy from './copy'
import focus from './focus'
import permission from './permission'
export default {
install(app) {
app.directive('copy', copy)
app.directive('focus', focus)
app.directive('permission', permission)
}
}
main.js 仅一行代码完成所有指令注册:
js
app.use(directivePlugin)
5.6 核心总结
两种注册方式功能、渲染效果完全一致 ;少量简易指令可直接在 main.js 注册,多指令、工程化、长期迭代项目,推荐封装插件通过 app.use() 加载。
6. 挂载DOM,渲染根组件
所有全局资源注册完成后,执行挂载方法,将根组件 App.vue 渲染到页面 #app 容器中,完成页面初始化。
js
app.mount('#app')
(注:部分内容可能由 AI 生成)