每个Vue实例在被创建时都要经过一系列的初始化过程,需要设置数据监听、数据挂载、渲染dom、数据更新时更新DOM等,同时在这个过程中也会运行一些生命周期的钩子函数,这给了程序员在不同阶段添加自己代码的机会
什么是vue生命周期?
就是vue对象从创建,到使用再到销毁的过程
Vue生命周期经历了几个阶段?
四个阶段,八个钩子函数
- 钩子函数beforeCreated
- 数据挂载阶段:把传入的data属性内容,赋给vue对象
- 钩子函数Created
- 钩子函数beforeMount
- 模板渲染阶段:把Vue对象中data渲染到dom对象上
- 钩子函数mounted
- 钩子函数beforeUpdate
- 模板更新阶段:当模板上使用的数据发生变化时,会触发模板的更新,模板会重新渲染
- 钩子函数updated
- 钩子函数beforeDestroy
- 组件销毁阶段
- 钩子函数destroyed
模拟Vue的运行原理
class MyVue{
constructor(obj){
// 2、初始化事件和生命周期 init events 和 init cycle
this.beforeCreate = obj.beforeCreate;
this.created = obj.created;
this.beforeMount = obj.beforeMount;
this.mounted = obj.mounted;
// 3、beforeCreate函数:钩子函数
if(this.beforeCreate){
this.beforeCreate();
}
// 4、挂载数据(属性赋值)阶段
// 把data对象的所有键值对(属性)赋给vue对象本身
for(let key in obj.data){
this[key] = obj.data[key];
}
// 5、Created函数:
if(this.created){
this.created();
}
// 6、检查
if(obj.el){
this.$el = obj.el;
}
this.$data = obj.data;
this.$props = obj.props;
// 7、beforeMount函数:
// if(this.beforeMount){
// this.beforeMount();
// }
this.beforeMount && this.beforeMount();
// 8、模板编译阶段
// 把 数据(data里的内容等等)显示在模板上
this.render();
// 9、Mounted函数:
this.mounted && this.mounted();
}
render(){
let boxDom = document.querySelector(this.$el)
let htmlStr = boxDom.innerHTML;//
for(let key in this.$data){
htmlStr = htmlStr.replace(new RegExp("{{"+key+"}}","g"),this[key]);
}
boxDom.innerHTML = htmlStr;
}
}
如果组件包在<keep-alive></keep-alive>标签中时,那么组件在切换的时候不会销毁,而是调用activated和deactivated钩子函数
<body >
<div id="box">
<span @click="show(0)">娱乐</span>|
<span @click="show(1)">八卦</span>|
<span @click="show(2)">体育</span>
<div>
<keep-alive>
<component :is="currCom"></component>
</keep-alive>
</div>
</div>
</body>
</html>
<script src="./js/vue.js"></script>
<script>
let yuLe = {
template:"<div>娱乐新闻</div>",
beforeCreate(){
console.log("娱乐组件beforeCreate");
},
beforeDestroy(){
console.log("娱乐组件销毁前");
},
activated(){
console.log("娱乐activated");
},
deactivated(){
console.log("娱乐deactivated");
}
}
let eightGua = {
template:"<div>八卦新闻</div>",
beforeCreate(){
console.log("八卦组件beforeCreate");
},
beforeDestroy(){
console.log("八卦组件销毁前");
},
activated(){
console.log("八卦activated");
},
deactivated(){
console.log("八卦deactivated");
}
}
let sports = {
template:"<div>体育新闻</div>"
}
let vm =new Vue({
el:"#box",
// 局部注册组件
components:{
yuLe,eightGua,sports
},
data:{
coms:[yuLe,eightGua,sports],
currCom:yuLe
},
methods:{
show(index){
this.currCom = this.coms[index];
}
}
});
</script>
一般来说在beforeDestory钩子函数里清除定时器,定时器是window对象的,只要网页不关闭,定时器就不会关闭,所以组件销毁并不会清除定时器;而如果组件是被包在<keep-alive></keep-alive>标签里时组件就不会销毁,就需要在deactivated钩子函数中清除定时器