记于vue生命周期的学习
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
比如我们经常用到的created钩子:
export default {
created() {
...在这里我们通常发起异步请求,得到数据
}
}
<!--注意-->
<!--
这里的created函数不能使用箭头函数,因为箭头函数中的this指向的是上一级的this。
-->
复制代码
接下来我们看一下有哪些钩子函数:
方法 | 作用 |
---|---|
beforeCreate | 组件实例刚被创建,在data属性之前。 |
created | 组件实例创建完成,data属性、computed、props、methods、watch已绑定,但DOM还未生成。 |
beforeMount | |
mounted | DOM已生成,但不保证已全部挂载在document中(用this.$nextTick 可以保证已经在document中) |
beforeUpdate | |
updated | 更新时触发 |
beforeDestroy | 组件销毁之前触发 (可以用于清除定时器,取消全局的注册事件),此时的this还是指向vue实例 |
destroyed | 此时的this不指向vue实例 |
单个组件的生命周期
<template lang="html">
<div class="life-cycle">
<h1 ref="title">lifr-cycle</h1>
<h2>{{ a }} {{watchVal}}</h2>
<ul>
<li v-for="(item, index) in data" ref="item" @click="setNumber(index)">{{ item }}</li>
</ul>
<button type="button" name="button" @click="setData">设置item的个数</button>
<!--<child-file-cycle :data="data"></child-file-cycle>-->
</div>
</template>
<script>
let oDDEven = true;
import {mapGetters} from "vuex"
import childFileCycle from "./childFileCycle"
export default {
data() {
return {
number: 1,
watchVal: 1,
data: ["Hellow"]
}
},
computed: {
...mapGetters([
"value"
]),
},
// 组件实例刚被创建,在data属性之前。
beforeCreate() {
this.a = "a"
console.log(this.$el, "---", this.data, "---", "beforeCreate", "---", this.$refs.title, "---", this.value);
},
// 组件实例创建完成,data属性、computed、props、methods、watch已绑定,但DOM还未生成。
created() {
setTimeout(() => {
this.data = ["Javascript", "Java", "PHP"];
}, 3000);
console.log(this.watchVal);
console.log(this.$el, "---", this.data, "---", "created", "---", this.$refs.title, "---", this.value);
},
beforeMount() {
console.log(this.$el, "---", this.data, "---", "beforeMount", "---", this.$refs.title, "---", this.value);
},
// DOM已生成,但不保证已全部挂载在document中(用this.$nextTick 可以保证已经在document中)
mounted() {
this.$nextTick(() => {
console.log(this.$el, "---", this.data, "---", "mounted", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
})
console.log(this.$el, "---", this.data, "---", "mounted", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
},
beforeUpdate() {
console.log(this.$el, "---", this.data, "---", "beforeUpdate", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
},
// 更新时触发
updated() {
console.log(this.$el, "---", this.data, "---", "update", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
},
beforeDestroy() {
console.log(this.$el, "---", this.data, "---", "beforeDestory", "---", this.$refs.title);
},
destroyed() {
console.log(this.$el, "---", this.data, "---", "destroyed", "---", this.$refs.title);
},
methods: {
setNumber(index) {
this.number = index;
console.log(index);
},
setData() {
if (oDDEven) {
this.data = ["hellow"];
oDDEven = false;
return;
}
this.data = ["Javascript", "Java", "PHP"];
oDDEven = true;
}
},
watch: {
watchVal: function(newVal, oldVal) {
return newVal;
}
},
components: {
childFileCycle
}
}
</script>
<style lang="css">
</style>
复制代码
由上述执行结果:
我们可以得出,每一个vue实例都会执行beforeCreat、created、beforeMount、mounted这四个钩子并且只执行一次,
再有数据(必须是与视图绑定的数据)更新的时候才会执行beforeUpdate、updated这两个钩子,
beforeDestroy、destroyed在视图销毁的时候触发。
复制代码
子组件
<template lang="html">
<div class="child-file-cycle">
<h2>child-file-cycle</h2>
<div class="">
child - {{ number }}
</div>
<button type="button" name="button" @click="setNumber">setNumber</button>
<ul>
<li v-for="(item, index) in data" ref="item" @click="setNumber(index)">child - {{ item }}</li>
</ul>
</div>
</template>
<script>
export default {
props: {
data: {
type: Array,
default: []
}
},
data() {
return {
number: Math.random()
}
},
computed: {
},
// 组件实例刚被创建,在data属性之前。
beforeCreate() {
console.log("beforeCreate");
},
// 组件实例创建完成,data属性、computed、props、methods、watch已绑定,但DOM还未生成。
created() {
console.log("created", this.data);
},
beforeMount() {
console.log("beforeMount");
},
// DOM已生成,但不保证已在document中(用this.$nextTick 可以保证已经在document中)
mounted() {
console.log("mounted");
},
beforeUpdate() {
console.log("beforeUpdate");
},
// 更新时触发
updated() {
console.log("update");
},
beforeDestroy() {
console.log("beforeDestory");
},
destroyed() {
console.log("destroyed");
},
methods: {
setNumber() {
this.number = Math.random();
}
}
}
</script>
<style lang="css">
</style>
复制代码
在父组件的beforeMount钩子之后会执行子组件一系列的钩子函数,将子组件挂载在父组件之后,再将父组件挂载。
更新props影响的钩子函数
更新props的值的时候,会触发父组件的beforeUpdate,同时也会触发子组件的beforeUpadte、updated钩子,最后触发父组件的updated钩子。
再一次感谢您花费时间阅读这份稿!
作者 [@xinwuliu][2]
2018 年 05月 08日