目录
[1. 概念](#1. 概念)
[2. 特点](#2. 特点)
[3. 功能](#3. 功能)
[4. 常用生命周期函数及其用法](#4. 常用生命周期函数及其用法)
[5. 应用场景](#5. 应用场景)
[1. beforeCreate](#1. beforeCreate)
[2. created](#2. created)
[3. beforeMount](#3. beforeMount)
[4. mounted](#4. mounted)
[5. beforeUpdate](#5. beforeUpdate)
[6. updated](#6. updated)
[7. beforeDestroy](#7. beforeDestroy)
[8. destroyed](#8. destroyed)
一、生命周期介绍
1. 概念
生命周期函数是在Vue组件生命周期中的特定时间点执行的函数。Vue实例有一个完整的生命周期,从创建、挂载、更新到销毁。在这个过程中,Vue提供了一系列的钩子函数,让你能够在特定阶段执行自定义逻辑。
2. 特点
- 生命周期函数是一组特定的函数,它们按照特定的顺序在组件的生命周期中被调用。
- 这些函数允许你在组件的不同阶段添加自定义逻辑,例如在组件创建前进行初始化,或在组件销毁后进行清理工作。
- 生命周期函数的执行顺序是确定的,你可以依靠它们来确保你的逻辑按照预期的顺序执行。
3. 功能
- 初始化: 在组件实例初始化时执行一些操作。
- 渲染: 在组件渲染过程中执行一些操作,例如在数据更新时重新渲染。
- 销毁: 在组件销毁时执行一些清理操作,例如移除事件监听器或取消订阅。
4. 常用生命周期函数及其用法
- beforeCreate: 在实例初始化之后,数据观测和事件/watcher事件配置之前被调用。常用于初始化数据或在实例初始化之前执行一些异步操作。
- created: 在实例创建完成后被立即调用。常用于数据初始化、获取异步数据等操作。
- beforeMount: 在挂载开始之前被调用。常用于在模板编译完成后,但在挂载之前执行一些操作。
- mounted: 实例被挂载后调用。常用于获取DOM元素、初始化第三方库等操作。
- beforeUpdate: 数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。常用于在数据更新前执行一些操作。
- updated: 虚拟DOM重新渲染和打补丁后调用。常用于在数据更新后执行一些DOM操作。
- beforeDestroy: 实例销毁之前调用。常用于执行一些清理操作,如取消定时器或清理订阅。
- destroyed: 实例销毁后调用。常用于执行一些销毁操作,如释放资源或取消事件监听器。
5. 应用场景
- 数据初始化: 在
created
生命周期函数中初始化数据。 - DOM操作: 在
mounted
生命周期函数中执行DOM操作,如获取元素、绑定事件等。 - 数据更新: 在
beforeUpdate
生命周期函数中执行数据更新前的操作,如更新计算属性或进行异步操作。 - 清理操作: 在
beforeDestroy
生命周期函数中执行清理操作,如取消定时器、清理订阅等。
二、生命周期语法
1. beforeCreate
- 作用: 在实例初始化之后,数据观测和事件/watcher事件配置之前被调用。此时实例已经初始化,但是数据观测和事件/watcher事件尚未初始化。
- 用途: 在这个阶段可以进行一些初始化的操作,但无法访问实例中的数据和方法。
2. created
- 作用: 在实例创建完成后被立即调用。此时实例已经完成了数据观测、属性和方法的运算,但是尚未挂载到DOM中。
- 用途: 常用于数据的初始化、获取异步数据、初始化实例中的数据等操作。
3. beforeMount
- 作用: 在挂载开始之前被调用。此时模板编译已完成,但是尚未将编译好的模板挂载到DOM中。
- 用途: 可以在此阶段进行一些DOM操作,如修改模板结构或获取DOM元素。
4. mounted
- 作用: 实例被挂载后调用。此时实例已经挂载到了DOM中,可以访问到DOM元素。
- 用途: 常用于获取DOM元素、初始化第三方库、发送网络请求等操作。
5. beforeUpdate
- 作用: 数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。
- 用途: 可以在数据更新前执行一些操作,例如更新计算属性或进行异步操作。
6. updated
- 作用: 虚拟DOM重新渲染和打补丁后调用。
- 用途: 常用于在数据更新后执行一些DOM操作,例如更新DOM元素的样式或内容。
7. beforeDestroy
- 作用: 实例销毁之前调用。
- 用途: 可以在此阶段执行一些清理操作,如取消定时器、清理订阅等。
8. destroyed
- 作用: 实例销毁后调用。
- 用途: 常用于执行一些销毁操作,如释放资源或取消事件监听器。
javascript
Vue.component('my-component', {
beforeCreate() {
// 在实例初始化之后,数据观测和事件/watcher事件配置之前被调用
// 可以在这里进行初始化操作
},
created() {
// 在实例创建完成后被立即调用
// 可以在这里进行数据初始化、获取异步数据等操作
},
beforeMount() {
// 在挂载开始之前被调用
// 可以在模板编译完成后,但在挂载之前执行一些操作
},
mounted() {
// 实例被挂载后调用
// 可以在这里获取DOM元素、初始化第三方库等操作
},
beforeUpdate() {
// 数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前
// 可以在这里执行数据更新前的操作
},
updated() {
// 虚拟DOM重新渲染和打补丁后调用
// 可以在这里执行数据更新后的DOM操作
},
beforeDestroy() {
// 实例销毁之前调用
// 可以在这里执行一些清理操作,如取消定时器或清理订阅
},
destroyed() {
// 实例销毁后调用
// 可以在这里执行一些销毁操作,如释放资源或取消事件监听器
}
})
三、生命周期应用实例
1.计时器组件
当组件挂载时开始计时,当组件销毁时停止计时。
html
<!-- Timer.vue -->
<template>
<div>
<p>计时器: {{ timer }}</p>
</div>
</template>
<script>
export default {
data() {
return {
timer: 0,
intervalId: null
};
},
mounted() {
// 在组件挂载后开始计时
this.intervalId = setInterval(() => {
this.timer++;
}, 1000);
},
beforeDestroy() {
// 在组件销毁前停止计时
clearInterval(this.intervalId);
}
};
</script>
使用了 mounted
钩子函数来在组件挂载后开始计时,使用了 beforeDestroy
钩子函数来在组件销毁前停止计时。这样,我们就能够在组件的生命周期中添加自定义逻辑,实现了一个简单的计时器功能。
2.博客应用文章列表和文章详情页面
html
<!-- BlogList.vue -->
<template>
<div>
<h2>文章列表</h2>
<ul>
<li v-for="post in posts" :key="post.id" @click="showPost(post.id)">
{{ post.title }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
posts: []
};
},
mounted() {
// 在组件挂载后请求文章列表数据
this.fetchPosts();
},
methods: {
fetchPosts() {
// 模拟向服务器请求文章列表数据
setTimeout(() => {
this.posts = [
{ id: 1, title: '文章1' },
{ id: 2, title: '文章2' },
{ id: 3, title: '文章3' }
];
}, 1000);
},
showPost(postId) {
// 跳转到文章详情页面
this.$router.push(`/post/${postId}`);
}
}
};
</script>
html
<!-- BlogPost.vue -->
<template>
<div>
<h2>文章详情</h2>
<p>{{ post.title }}</p>
<p>{{ post.content }}</p>
</div>
</template>
<script>
export default {
data() {
return {
post: {}
};
},
mounted() {
// 在组件挂载后请求文章详情数据
this.fetchPost(this.$route.params.postId);
},
methods: {
fetchPost(postId) {
// 模拟向服务器请求单篇文章的详细内容
setTimeout(() => {
this.post = {
id: postId,
title: `文章${postId}`,
content: `这是文章${postId}的内容。`
};
}, 1000);
}
}
};
</script>
3.购物车
首先是商品列表组件:
html
<!-- ProductList.vue -->
<template>
<div>
<h2>商品列表</h2>
<ul>
<li v-for="product in products" :key="product.id">
{{ product.name }} - ¥{{ product.price }}
<button @click="addToCart(product)">加入购物车</button>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
products: [
{ id: 1, name: '商品1', price: 100 },
{ id: 2, name: '商品2', price: 200 },
{ id: 3, name: '商品3', price: 150 }
]
};
},
methods: {
addToCart(product) {
this.$emit('add-to-cart', product);
}
}
};
</script>
然后是购物车组件:
html
<!-- ShoppingCart.vue -->
<template>
<div>
<h2>购物车</h2>
<ul>
<li v-for="item in cart" :key="item.product.id">
{{ item.product.name }} - 数量: {{ item.quantity }} - 总价: ¥{{ item.totalPrice }}
<button @click="removeFromCart(item.product)">移除</button>
</li>
</ul>
<p>总计: ¥{{ total }}</p>
<button @click="checkout">结算</button>
</div>
</template>
<script>
export default {
props: {
cart: {
type: Array,
default: () => []
}
},
computed: {
total() {
return this.cart.reduce((acc, item) => acc + item.totalPrice, 0);
}
},
methods: {
removeFromCart(product) {
this.$emit('remove-from-cart', product);
},
checkout() {
// 结算逻辑
alert('结算成功!请付款。');
}
}
};
</script>
最后是根组件,用于组合商品列表和购物车:
html
<!-- App.vue -->
<template>
<div>
<product-list @add-to-cart="addToCart"></product-list>
<shopping-cart :cart="cart" @remove-from-cart="removeFromCart"></shopping-cart>
</div>
</template>
<script>
import ProductList from './components/ProductList.vue';
import ShoppingCart from './components/ShoppingCart.vue';
export default {
components: {
ProductList,
ShoppingCart
},
data() {
return {
cart: []
};
},
methods: {
addToCart(product) {
const existingItem = this.cart.find(item => item.product.id === product.id);
if (existingItem) {
existingItem.quantity++;
} else {
this.cart.push({ product: product, quantity: 1, totalPrice: product.price });
}
},
removeFromCart(product) {
const index = this.cart.findIndex(item => item.product.id === product.id);
if (index !== -1) {
this.cart.splice(index, 1);
}
}
}
};
</script>
四、总结
生命周期函数是在Vue组件实例化、挂载、更新、销毁等不同阶段触发的钩子函数,用于执行特定的操作。以下是Vue.js中常见的生命周期函数及其作用:
-
beforeCreate
: 在实例初始化之后,数据观测 (data observer) 和事件配置 (event/watcher setup) 之前被调用。在这个阶段,组件实例的选项对象已经被处理,但实例的数据和方法尚未初始化。 -
created
: 在实例创建完成后被立即调用。在这个阶段,实例已经完成了数据观测 (data observer),属性和方法的运算,但尚未挂载到DOM上。 -
beforeMount
: 在挂载开始之前被调用:相关的 render 函数首次被调用。 -
mounted
: 在挂载完成后被调用:相关的 render 函数已经创建并且挂载到DOM中。实例已经挂载到DOM上,可以访问到DOM节点。 -
beforeUpdate
: 在数据更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,但是不会触发附加的重新渲染过程。 -
updated
: 在数据更改导致的重新渲染完成后调用。该钩子函数被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。 -
beforeDestroy
: 在实例销毁之前调用。在这个阶段,实例仍然完全可用。 -
destroyed
: 在实例销毁之后调用。在这个阶段,Vue.js 实例指示的所有东西都被解绑定,所有事件监听器和子实例被移除。
这些生命周期函数使得开发者可以在不同的阶段执行特定的逻辑,例如在组件挂载时请求数据、在销毁时清理定时器等。