一. 钩子函数简要说明
- beforeCreate与created
(1) beforeCreate 为组件完全创建前调用的函数,使用不多,但常用于定时器;
(2) created 为组件完全创建后调用的函数,此时可以获取后端数据然后对组件中的数据属性进行赋值以渲染视图层;
(3) 案例:在组件Test中,beforeCreate中打印Test组件的testMsg的值显示undefined,但是在created中打印该值却能成功输出; - beforeMount与mounted
(1) beforeMount 为组件以及组件数据挂载到DOM之前调用的函数;
(2) mounted 为组件以及组件数据挂载到DOM后调用的函数
(3) 案例:组件App中包含了组件Test,在组件Test中,beforeMount和mounted中分别执行代码document.getElementById(‘app’)。beforeMount打印的内容中不包含Test组件,mounted中打印出的内容包含了Test组件。这是因为调用beforeMount之时Test组件还未被挂载到DOM - beforeUpdate与updated
(1) beforeUpdate 为更新DOM之前调用的函数,应用为获取原始DOM;
(2) updated 为更新DOM之后调用的函数,应用为获取最新的DOM;
(3) 案例:点击页面“修改”按钮实现对Test组件中testMsg数据属性的修改,在Test组件beforeUpdate中打印document.getElementById(‘app’)的结果是原始的DOM,但在updated中打印出的则是最新的DOM - beforeDestroy与destroyed
(1) beforeDestroy 为组件销毁之前调用的函数,不常用;
(2) destroyed 为组件销毁之后调用的函数,常用在页面定时器的销毁;
(3) 案例:在App组件中通过按钮控制Test组件的创建和销毁。beforeDestroy和destroyed中分别执行对document.getElementById(‘app’)的输出。结果是,beforeDestroy种输出的结果中包含了Test组件,而destroyed输出结果中已经不包含Test组件 - activated与deactivated
若页面中某一组件频繁的被创建和销毁,这将非常消耗性能。因此我们考虑将销毁的组件状态缓存起来,Vue中提供了keep-alive标签对,在使用组件的时候直接将组件标签嵌套在该标签中,则能防止组件在频繁创建和销毁的时候不会重复的渲染DOM。一旦使用了这一标签对后,组件的创建便成了激活,销毁则成了停用。组件在激活的时候调用的钩子函数是activated,在停用时调用的函数则是deactivated。
二. 各钩子函数对应的案例实现
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Vue中的生命周期</title>
</head>
<body>
<div id='app'>
<App/>
</div>
<script type='text/javascript' src='node_modules/vue/dist/vue.js'></script>
<script type='text/javascript'>
Vue.component('Test',{
data:function() {
return {
testMsg :'Test全局组件中的数据:Vue生命周期中涉及到的一些钩子函数'
}
},
// 在其他地方使用到了Test组件,但该组件却无template的话,则会存在warning
template:`
<div>
<p>{{testMsg}}</p>
<button @click='changeHandler'>点我修改以上数据</button>
</div>
`,
methods:{
changeHandler: function() {
this.testMsg = '我是修改后的testMsg'
}
},
beforeCreate:function() {
//输出为undefined 因为Test组件在此时还未被创建
console.log(this.testMsg)
},
created: function() {
//下面注释形式打印出的是[object HTMLDivElement],如果去掉字符串连接的话,打印出的则是HTML对应的标签对
//console.log('created:'+ document.getElementById('app'))
//输出为实在的内容,因为Test组件此时已经被创建
console.log(this.testMsg)
},
beforeMount:function (){
// 第一种情况:若是将App组件放置在Vue对象的template下,这个时候组件数据虽然被创建但还未挂载到Dom中,所以此时输出的是页面空壳id为app的组件
// 第二种情况,若是将局部组件App直接放置在HTML页面下,这个时候因为Test作为App下的子组件虽然被创建但还没被挂载到Dom,所以打印出的结果显示App下不包含Test组件
console.log(document.getElementById('app'))
},
mounted:function() {
//第一种情况:若是将App组件放置在Vue对象的template下,以下输出为null,因为Vue对象中的template中存在内容,于是将HTML中的内容覆盖了,找不到id=app的元素,所以输出为null
// 第二种情况,若是将局部组件App直接防止在HTML页面下,因为这个时候Test组件不仅被创建而且已经被挂载到App组件下,所以打印出的页面结构是全面的
console.log(document.getElementById('app'))
},
// beforeUpdate和updated中若是直接输出this.testMsg则都是输出最新的数据,两个方法的区别只是获得更新前的DOM和更新后的DOM,而不是更新前的数据属性和更新后的数据属性
beforeUpdate:function() {
console.log(document.getElementById('app').innerHTML)
},
updated:function() {
console.log(document.getElementById('app').innerHTML)
},
beforeDestroy: function() {
console.log('Test组件销毁之前调用的函数')
},
destroyed: function() {
console.log('Test组件销毁之后调用的函数')
},
activated:function() {
console.log('组件被激活了')
},
deactivated:function() {
console.log('组件被停用了')
}
})
let App = {
data:function() {
return {
isShow:true
}
},
template:`
<div class='app'>
<keep-alive>
<Test v-if='isShow'/>
</keep-alive>
<button @click='changeIsShow'>点我实现Test组件的创建和消除</button>
</div>
`,
methods:{
changeIsShow:function() {
this.isShow = !this.isShow
}
}
}
let vm = new Vue({
el:'#app',
data:function() {
return {
}
},
components:{
App
},
template:``
})
</script>
</body>
</html>
此时只默认调用了beforeCreate、created、beforeMount以及mounted这四个钩子函数,无任何操作情况下页面截图以及控制台对应的输出截图:
点击“点我修改以上数据”按钮,控制台对应的输出:
使用Test组件时外部未嵌套keep-alive标签时,点击"点我实现Test组件的创建和消除"按钮后控制台对应的输出:
使用Test组件时外部嵌套keep-alive标签时,点击"点我实现Test组件的创建和消除"按钮之前和之后控制台对应的输出: