vue组件的生命周期
我们知道要使用vue,一开始是需要创建的,也就是new一个vue出来(包括我们创建的局部组件),在这个创建的过程当中,到底经历了哪些过程,这个过程就是我们需要掌握的vue组件的生命周期
生命周期
生命周期(lifeCycle)指的是从出生到死亡的过程,vue的生命周期就是从创建到销毁的过程
在整个过程中分为4个阶段
创建create -----> 挂载mount -----> 更新 update -----> 销毁 destroy
同时这4个阶段还被分成了8个过程,每个阶段2个过程,不同的阶段有不同的状态不同的操作,而每个阶段的过程都会执行一个特殊函数,这个函数叫做钩子函数
钩子函数
所谓的钩子函数就是在vue的不同周期情况下vue会自动调用的函数
1、 beforeCreate vue创建之前
2、 created vue创建之后
3、beforeMount 挂载之前(vue接管页面之前)
4、mounted 挂载之后 (vue接管页面之后)
5、beforeUpdate vue内部更新之前
6、Updated vue内部更新之后
7、beforeDestrory vue销毁之前
8、destroyed vue销毁之后
vue在这8个状态下,对应了8个钩子函数,在不同钩子函数里面要执行不同的操作
周期名称 | data | computed | methods | $refs |
---|---|---|---|---|
beaforeCreate | 否 | 否 | 否 | 否 |
created | 是 | 是 | 是 | 否 |
beforeMount | 是 | 是 | 是 | 否 |
mounted | 是 | 是 | 是 | 是 |
在vue的组件中也有这8个钩子函数,因为我们之前讲过vue组件就是一个小型的vue对象
1、夸生命周期调用
vue应该是在不同的生命周期里面执行不同的操作,所有的阶段都有自己的限制条件,但是某些情况下我们需要跨生命周期调用,怎么办?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h2 ref="hh"></h2>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el:"#app",
created() {
},
mounted(){
console.log("我是created");
//将原来的年龄加上一个20以内的随机数,然后设置在h2标签上面,但是要通过DOM操作完成
let newAge = this.age + parseInt(Math.random() * 20);
console.log(newAge);
this.$refs["hh"].innerText = newAge;
},
data:{
age:20
}
})
</script>
</html>
代码分析:
在上面的代码里面,我们在created生命周期里面创建了一个变量,然后再用ref为h2的元素写入变量值
问题:我们不能再created里面操作$refs
解决方案
<body>
<div id="app">
<h2 ref="h2"></h2>
</div>
</body>
<script src="js/vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
age:20
},
created() {
console.log("我是created");
//将原来的年龄加上一个20以内的随机数,然后设置在h2标签上面,但是要通过DOM操作完成
let newAge = this.age + parseInt(Math.random() * 20);
this.$nextTick(() => {
this.$refs["hh"].innerText = newAge;
})
},
mounted(){
}
})
</script>
这个时候我们使用到了一个方法 $nextTick()
这个方法的作用:
他会做一个判断,判断当前作为回调函数传入的表达式是否可以在当前生命周期中执行,如果不能,则会顺延到下一个生命周期,如果还不行则继续顺延,知道可以执行为止
v-if及v-show的区别
之前讲过,v-if是通过注释的方式让元素消失,而v-show是通过css属性display:none 来操作的,但是他的真实的本质其实在生命周期里面
v-show不会触发生命周期,因为本质它是把元素隐藏了,而不是销毁了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<one v-show="flag"></one>
<button type="button" @click="flag=!flag">切换</button>
</div>
<template id="temp1">
<div>
<h2>我是一个数:{{num}}</h2>
</div>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var one = {
template:"#temp1",
data(){
return {
num: 18
}
},
created(){
console.log("我是组件内部的created" + new Date().toLocaleString());
}
}
new Vue({
el:"#app",
data:{
flag:true
},
components:{
one
}
})
</script>
</html>
v-show的情况下生命周期并没有重新执行
换成v-if之后,每次的切换都会重新执行生命周期
<one v-if="flag"></one>
keep-alive
vue的组件在正常情况都是会经历4个阶段的,但是又一个特殊情况,如果有一个组件不想死,这种情况下我们叫上keep-alive
在vue的内部,有一个vue系统自带的组件叫做 <keep-alive></keep-alive>
在这个组件里面的内容是不会被销毁得到,也就是说不会执行destroy这个阶段
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<keep-alive>
<one v-if="flag"></one>
</keep-alive>
<button type="button" @click="flag=!flag">切换</button>
</div>
<template id="temp1">
<div>
<h2>我是一个数:{{num}}</h2>
</div>
</template>
</body>
<script src="js/vue.js"></script>
<script>
var one = {
template:"#temp1",
data(){
return {
num: 18
}
},
created(){
console.log("我是组件内部的created" + new Date().toLocaleString());
},
activated() {
console.log("我被激活显示了")
},
deactivated() {
console.log("我被隐藏了")
},
}
new Vue({
el:"#app",
data:{
flag:true
},
components:{
one
}
})
</script>
</html>
代码分析:
在上面的代码里面,因为one组件被keep-alive嵌套,所以one就跳出了生命周期,即使我们用v-if去销毁它也销毁不掉,所以每次切换之后不会重新执行created
当一个组件被keep-alive嵌套以后,它不会被销毁,同时还会多两个特殊的生命周期钩子函数
1、activated() 被激活时(显示)
2、deactivated()当休眠时(隐藏)
关于组件的属性传值的注意事项
<one userName="zhangsan"></one>
<!-- 向组件内部传递一个属性userName,值为“zhangsan” -->
<one age="18"></one>
<!-- 向组件内部传递一个属性age,值为“18”,这里注意是字符串的“18” -->
<one :age="18"></one>
<!-- 向组件内部传递一个属性age,值为18,这里注意是数值类型的18 -->
<one show-back="true"></one>
<!-- 向组件内部传递一个属性show-back,值为“true”,请注意这是字符串的“true” -->
<one :show-back="true"></one>
<!-- 向组件内部传递一个属性show-back,值为true,请注意这是布尔类型的true -->
易错点
<one :show-back="false"></one>
<!-- 内部如果接收的是布尔类型的值,但是我们传递的是字符串“false”,在转换的时候“false”字符串会被转换成true -->
总结:
自定义属性在传值的时候默认都是字符串,如果是其他类型请使用动态绑定