您的位置:首页 > Web前端 > Vue.js

Vue中的生命周期概念及钩子函数

2019-08-02 22:20 851 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/weixin_45014444/article/details/98248051

1.概念

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
那么Vue为什么会提出生命周期的概念,或者说我们为什么要使用生命周期呢?
我们都知道Vue是由指令和组件系统构成,而我们要想使用组件,那么就得在组件的特定阶段完成特点的任务,而组件的生命周期分为三个阶段: 初始化、运行中、销毁 ,我们可以在生命周期对应的阶段,达成我们的需求。在这过程中会运行一些生命周期的钩子,所谓的钩子,其实就是一些函数,只不过这些函数,是在特定时间触发的方法。

2.生命周期图示

3.生命周期钩子函数

根据上面一个完整的生命周期过程,我们可以得知在生命周期的三个过程:初始化、运行中、销毁中共有八个钩子函数,如下。
● beforeCreate( ) { }
● created( ) { }
● beforeMount( ) { }
●mounted( ) { }
● beforeUpdate( ) { }
● updated( ) { }
● beforeDestroy( ) { }
● destroyed( ) { }
注意:
生命周期钩子的 this 上下文指向调用它的 Vue 实例。
生命周期钩子函数不允许写成箭头函数,因为箭头函数并没有 this,this会作为变量一直向上级词法作用域查找,直至找到为止,这与生命周期钩子的 this 的指向不同。

4.钩子函数使用及分析
根据生命周期过程可以将这些钩子函数进行如下划分。
初始化:
● beforeCreate( ) { }----组件即将创建
代码演示:

<body>
<div id="app">
<h3>{{msg}}</h3>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
msg:'Hello World!'
},
beforeCreate(){
console.log('--beforeCreate--');
console.log('data',this.msg),
console.log('DOM',document.querySelector('h3'))
fetch('./data/data.json')//此处的json数据为{ "ret":true,"content":"你好 世界!"}
.then(res=>res.json())
.then(data=>{
this.msg=data.content
})
.catch(error=>console.log(error))
}
})
</script>

运行结果:

【总结】
任务:
初始化事件,并且为整个生命周期的开始做准备
意义:
数据未获取,真实dom未获取(此处的数据指的是new Vue()中的数据)
可以实现数据请求并且可以进行数据修改

● created( ) { }----组件创建结束
代码演示:

<body>
<div id="app">
<h3>{{msg}}</h3>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
msg:'Hello World!'
},
created(){
console.log('--created--');
console.log('data',this.msg),
console.log('DOM',document.querySelector('h3'))
fetch('./data/data.json')//此处的json数据为{ "ret":true,"content":"你好 世界!"}
.then(res=>res.json())
.then(data=>{
this.msg=data.content
})
.catch(error=>console.log(error))
}
})
</script>

运行结果:

【总结】
任务: 进行数据的注入和数据的反应
意义:
数据可获取,真实dom没有拿到(此处的数据指的是new Vue()中的数据)
可以实现数据请求并且可以进行数据修改

● beforeMount( ) { }----组件即将挂载
代码演示:

<body>
<div id="app">
<h3>{{msg}}</h3>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
msg:'Hello World!'
},
beforeMount(){
console.log('--beforeMount--');
console.log('data',this.msg),
console.log('DOM',document.querySelector('h3'))
fetch('./data/data.json')//此处的json数据为{ "ret":true,"content":"你好 世界!"}
.then(res=>res.json())
.then(data=>{
this.msg=data.content
})
.catch(error=>console.log(error))
}
})
</script>

运行结果:

【总结】
任务:
判断组件是否有el/template选项,如果有那么使用render函数将template模板中的jsx转换成VDOM对象模型,如果没有,需要我们使用$mount/outerHTML手动挂载
意义:
更多的是内部完成任务,外部不进行干预;
数据可获取,真实dom没有拿到(此处的数据指的是new Vue()中的数据);
可以实现数据请求并且可以进行数据修改;

●mounted( ) { }----组件挂载结束
代码演示:

<body>
<div id="app">
<h3>{{msg}}</h3>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
msg:'Hello World!'
},
mounted(){
console.log('--mount--');
console.log('data',this.msg),
console.log('DOM',document.querySelector('h3'))
document.querySelector('h3').style.background='yellow'
fetch('./data/data.json')
.then(res=>res.json())
.then(data=>{
this.msg=data.content
})
.catch(error=>console.log(error))
}
})
</script>

运行结果:

【总结】
任务: 将vdom渲染为真实dom,然后挂载到页面中,此时我们在页面中可以看到内容
意义:
可以操作操作真实dom 【 可以进行第三方库实例化 】
可以实现数据请求并且可以进行数据修改;
【注意】
我们常将数据请求写在 created 中,因为created钩子是第一次获得数据的地方
mounted钩子函数可以进行DOM操作【 第三方库实例化【静态数据】 】

运行中:
● beforeUpdate( ) { }----组件更新前
代码演示:

<body>
<div id="app">
<button @click="click">点击</button>
<h3 v-if="flag">Hello World!</h3>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
flag:true
},
methods:{
click(){
this.flag=!this.flag
}
},
beforeUpdate(){
console.log('--beforeUpdate--')
console.log('data',this.flag)
console.log('DOM',document.querySelector('#app'))
}
})
</script>

运行结果:

【总结】
触发条件: 组件的数据发生改变
任务: VDOM重新生成,然后通过diff算法和以前的VDOM比对,生成patch补丁对象 【 内部进行 】
意义: 数据可获取,真实dom也可获取(此处的数据指的是new Vue()中的数据);

● updated( ) { }----组件更新结束
代码演示:

<body>
<div id="app">
<button @click="click">点击</button>
<h3 v-if="flag">Hello World!</h3>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
flag:true
},
methods:{
click(){
this.flag=!this.flag
}
},
updated(){
console.log('--updated--')
console.log('data',this.flag)
console.log('DOM',document.querySelector('#app'))
}
})
</script>

运行结果:

【总结】
触发条件: 组件的数据发生改变
任务: 将patch补丁对象进行渲染生成真实dom
意义:可以操作DOM 【 第三方库的实例化【 动态数据 】 】
【注意】:平时大家使用updated进行第三方库实例化

销毁:用来完成善后工作
组件的销毁会触发两个钩子函数 【 这两个钩子函数基本没区别, 任意选择一个使用 】
● beforeDestroy( ) { }
● destroyed( ) { }
组件的销毁有两种形式
(1)内部销毁($destroy)----组件会被销毁掉,但是组件的DOM外壳还在
$destroy只是完全销毁一个Vue实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。它并不是用来清除已有页面上的DOM的。

<body>
<div id="app">
<button @click="flag=!flag">点击</button>
<h3 v-if="flag">Hello World!</h3>
<button @click="remove">销毁</button>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
flag:true
},
methods:{
remove(){
this.$destroy()//
}
}
})
</script>

(2) 外部销毁----通过开关销毁 【 推荐 】
即销毁Vue组件,也销毁DOM元素

<body>
<div id="app">
<button @click="flag=!flag">点击</button>
<h3 v-if="flag">Hello World!</h3>
<button @click="remove1">销毁</button>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
flag:true
},
methods:{
remove(){
console.log(this)
this.$destroy()
}
},
destroyed(){
console.log('--destroyed--')
document.querySelector('#app').remove()//此处的remove是原生js中的方法,用来删除节点
}
})
</script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: