Vue 的生命周期是控制组件 "从生到死" 的核心逻辑,工程化开发则是企业级项目的必备技能。
一、Vue 生命周期:组件的 "一生"
Vue 组件从创建→挂载→更新→销毁的过程,称为 "生命周期",每个阶段对应 "生命周期钩子函数",我们可以在特定阶段执行逻辑(如请求数据、清理资源)。
1. 生命周期的四个阶段
Vue 2 的生命周期分为 4 个核心阶段,共 8 个常用钩子函数:
- 创建阶段:
beforeCreate、created;组件实例创建后;初始化数据、请求接口(created) - 挂载阶段:
beforeMount、mounted;组件挂载到 DOM 后;操作 DOM、初始化第三方插件(mounted) - 更新阶段:
beforeUpdate、updated;组件数据更新后;监听数据变化后的 DOM 操作 - 销毁阶段:
beforeDestroy、destroyed;组件实例销毁前 / 后;清理定时器、取消请求
2. 常用生命周期钩子详解
(1)created:组件创建完成(最常用)
组件实例创建后立即执行,此时数据已初始化,但 DOM 还未挂载,适合做 "初始化数据、请求接口" 等操作。
html
<div id="app">
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: { message: '' },
created() {
// 组件创建后,请求接口数据
this.fetchData();
},
methods: {
fetchData() {
// 模拟接口请求
setTimeout(() => {
this.message = '从接口获取的数据';
}, 1000);
}
}
})
</script>
(2)mounted:组件挂载完成
组件已挂载到页面 DOM,此时可以操作 DOM 元素,适合初始化第三方插件(如 ECharts、地图)。
html
<div id="app">
<div id="chart" style="width: 400px; height: 300px;"></div>
</div>
<script src="https://unpkg.com/vue@2.7.14/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<script>
new Vue({
el: '#app',
mounted() {
// 挂载完成后,初始化ECharts图表
const myChart = echarts.init(document.getElementById('chart'));
myChart.setOption({
title: { text: '生命周期示例' },
series: [{ type: 'pie', data: [{ name: '创建', value: 2 }, { name: '挂载', value: 3 }] }]
});
}
})
</script>
(3)beforeDestroy:组件销毁前
组件销毁前执行,适合清理资源(如定时器、事件监听),避免内存泄漏。
html
<div id="app">
<button @click="isShow = !isShow">切换组件显示</button>
<child-component v-if="isShow"></child-component>
</div>
<script>
// 子组件
Vue.component('child-component', {
template: '<p>我是子组件</p>',
data() {
return { timer: null };
},
created() {
// 创建定时器
this.timer = setInterval(() => {
console.log('定时器运行中...');
}, 1000);
},
beforeDestroy() {
// 销毁前清理定时器
clearInterval(this.timer);
console.log('定时器已清理');
}
})
new Vue({
el: '#app',
data: { isShow: true }
})
</script>
3. 生命周期执行顺序总结
1.beforeCreate → 2. created → 3.beforeMount → 4.mounted
(数据更新时)→ 5. beforeUpdate → 6. updated
(组件销毁时)→ 7. beforeDestroy → 8. destroyed
二、工程化开发入门:从 "单文件" 到 "脚手架项目"
前面用的是 "CDN 引入 Vue" 的方式,实际企业开发用Vue CLI 脚手架创建工程化项目,支持组件化、热更新、打包优化等功能。
1. 工程化开发的核心优势
- 组件化:拆分页面为独立组件,复用性高;
- 自动化:自动编译、热更新、打包优化;
- 生态丰富:支持路由、状态管理等插件。
2. 快速创建 Vue 工程化项目
- 步骤 1:安装 Vue CLI
Vue CLI 是 Vue 官方的工程化工具,需先安装 Node.js(建议 14 + 版本),再执行:
bash
npm install -g @vue/cli
- 步骤 2:创建项目
执行以下命令,按提示选择配置(新手推荐 "Default ([Vue 2] babel, eslint)"):
bash
vue create vue-demo
- 步骤 3:启动项目
进入项目目录并启动开发服务:
bash
cd vue-demo
npm run serve
启动后访问http://localhost:8080,即可看到 Vue 默认页面。
3. 工程化项目的核心目录结构
创建完成后,项目目录结构如下(核心文件 / 目录):
plaintext
vue-demo/
├── node_modules/ # 第三方依赖包
├── public/ # 静态资源(如index.html)
├── src/ # 源码目录
│ ├── assets/ # 静态资源(图片、样式)
│ ├── components/ # 公共组件
│ ├── App.vue # 根组件
│ └── main.js # 入口文件(创建Vue实例)
├── package.json # 项目配置(依赖、脚本)
└── vue.config.js # Vue项目配置(可选)
4. 组件化开发:拆分页面为组件
工程化项目中,页面由单文件组件(.vue 文件) 组成,每个组件包含<template>(结构)、<script>(逻辑)、<style>(样式)三部分。
示例:创建并使用组件
(1)局部组件:仅在当前作用域可用
局部组件是在特定组件内部注册的组件,只能在注册它的父组件及其子组件中使用,外部组件无法访问。
① 局部组件的创建与使用步骤
- 步骤 1:定义局部组件
在src/components目录下创建HelloCard.vue:
vue
<!-- src/components/HelloCard.vue -->
<template>
<div class="card">
<h3>{{ title }}</h3>
<p>{{ content }}</p>
</div>
</template>
<script>
export default {
// 接收父组件传递的数据
props: {
title: { type: String, required: true },
content: { type: String, default: '默认内容' }
}
}
</script>
<style scoped>
/* scoped:样式仅作用于当前组件 */
.card {
padding: 20px;
border: 1px solid #eee;
border-radius: 8px;
margin: 10px;
}
</style>
- 步骤 2:在父组件中注册并使用
在需要使用该组件的父组件(如App.vue)中,通过components选项注册:
vue
<!-- src/App.vue -->
<template>
<div id="app">
<!-- 使用局部组件,传递props数据 -->
<HelloCard title="欢迎使用Vue" content="工程化开发更高效!" />
</div>
</template>
<script>
// 1. 引入局部组件
import HelloCard from './components/HelloCard.vue';
export default {
// 2. 注册局部组件
components: { HelloCard }
}
</script>
② 局部组件的特性与适用场景
- 作用域有限:仅在注册它的父组件内部可用,其他组件无法直接使用;
- 避免命名冲突:不同父组件中可注册同名局部组件,互不影响;
- 性能更优:未使用的局部组件不会被打包,减少资源体积;
- 适用场景:仅在某个页面或组件中使用的功能(如页面专属的筛选组件、弹窗组件)。
(2)全局组件:全项目通用
全局组件是在 Vue 实例全局注册的组件,注册后可在项目中所有组件(包括子组件、孙组件)中直接使用,无需重复引入和注册。
① 全局组件的创建与使用步骤
- 步骤 1:定义全局组件
在src/components目录下创建GlobalAlert.vue:
vue
<!-- src/components/GlobalAlert.vue -->
<template>
<div class="global-alert">
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
props: {
message: {
type: String,
required: true // 必须传递message参数
}
}
}
</script>
<style scoped>
.global-alert {
padding: 10px;
border: 1px solid #f0ad4e;
background: #fcf8e3;
color: #8a6d3b;
}
</style>
- 步骤 2:全局注册(在入口文件中)
在项目入口文件(通常是src/main.js)中,通过Vue.component()方法注册:
javascript
// src/main.js
import Vue from 'vue';
import App from './App.vue';
// 1. 引入全局组件
import GlobalAlert from './components/GlobalAlert.vue';
// 2. 全局注册(参数1:组件名,参数2:组件对象)
Vue.component('GlobalAlert', GlobalAlert);
// 创建Vue实例
new Vue({
el: '#app',
render: h => h(App)
});
- 步骤 3:在任意组件中直接使用
无需再次引入和注册,直接在模板中使用组件名:
vue
<!-- 任意组件(如src/views/Home.vue) -->
<template>
<div>
<!-- 直接使用全局组件 -->
<GlobalAlert message="这是全局提示组件" />
</div>
</template>
<script>
// 无需引入,直接使用
export default {
// 无需注册
}
</script>
② 全局组件的特性与适用场景
- 全项目可用:注册后在任何组件中都能直接使用,无需重复操作;
- 命名需唯一:全局组件名不能重复,否则会覆盖之前的组件;
- 打包体积较大:即使未使用,全局组件也会被打包到最终代码中;
- 适用场景:全项目通用的基础组件(如按钮、输入框、提示框、加载动画)。
(3)局部组件 vs 全局组件:核心区别对比
- 局部组件: 在父组件的
components选项中注册; 仅注册它的父组件及其子组件; 不同父组件可重名,无冲突; 未使用则不打包,体积小; 页面专属组件、低复用组件 - 全局组件: 通过
Vue.component()全局注册; 项目中所有组件; 全项目中名称必须唯一; 无论是否使用都会打包,体积较大; 全项目通用组件、高复用组件
(4)组件注册的最佳实践
- 优先使用局部组件:减少不必要的全局注册,避免打包体积过大;
- 全局组件命名规范:建议添加前缀(如
AppButton、BaseInput),避免命名冲突; - 通用组件库:项目中可创建
src/components/common目录存放全局组件,统一管理; - 按需引入:对于大型组件库(如 Element UI),即使是全局组件也建议按需引入,减少打包体积。