生命周期各阶段状态
总结:注意注释部分内容,各个阶段可以访问的属性
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
</style>
</head>
<body>
<div id="app">
<label>生日</label>
<input type="date" v-model="birthday"/>
<div>当前用户{{getAge}}周岁了</div>
<custom-el v-if="show">
<span>测试测试测试</span>
</custom-el>
</div>
<script>
//监听全局异常
Vue.config.errorHandler = function (err, vm, info) {
console.log(err)
}
//自定义元素,用于测试销毁元素生命周期
Vue.component("custom-el",{
data:function(){
return {
msg:'dddddddd'
}
},
created:function(){
//抛出错误,验证 异常捕获钩子
throw new Error("测试异常捕获钩子")
},
template:`
<div>
<span>{{msg}}</span>
<slot></slot></div>
`
})
var app = new Vue({
el:"#app",
data:function(){
return {
birthday:'2010-10-10',
show:true
}
},
beforeCreate:function(){
//创建之前,无法拿到 $data 与 $el
console.log("beforeCreate")
console.log(this.birthday)
console.log(this.$el)
},
created:function(){
//创建之前,只能拿到$data ,但无法拿到$el
console.log("created")
console.log(this.birthday)
console.log(this.$el)
},
beforeMount:function(){
//挂载之前,可以拿到$data与$el,但是$el是未解析的虚拟dom
console.log("beforeMount")
console.log(this.birthday)
console.log(this.$el)
},
mounted:function(){
console.log(this)
//挂载之后,可以拿到$data与$el,此时$el为已被解析的真实dom
console.log("beforeMount")
console.log(this.birthday)
console.log(this.$el)
},
beforeUpdate:function(){
//在$data已经修改,但是组件dom并未更新渲染时调用
console.log("beforeUpdate")
console.log(JSON.stringify(this.$data))//新的数据
console.log(this.$el.innerHTML)//原始dom
},
updated:function(){
//在$data已经修改,组件dom已被重新渲染之后调用
console.log("updated")
console.log(JSON.stringify(this.$data))//新的数据
console.log(this.$el.innerHTML)//新的dom,不能保证所有子组件被重新渲染
this.$nextTick(function(){
console.log(this.$el.innerHTML)//新的dom,可以保证所有子组件被重新渲染了
})
},
//此处存在问题,并未验证出来beforeDestroy与destroyed的区别
beforeDestroy:function(){
//实例销毁之前被调用,这一步,实例仍然完全可用
console.log("beforeDestroy")
this.birthday = '2014-11-11'
},
destroyed:function(){
//Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,
//所有的事件监听器会被移除,所有的子实例也会被销毁。
console.log("destroyed")
},
errorCaptured:function(err,vm,info){
//当捕获一个来自子孙组件的错误时被调用
console.error(err)
//如果返回false,则会阻止错误继续向上传播,否则会被全局errorHandler捕获
return true;
},
methods:{
},
computed:{
getAge:function(){
if(this.birthday){
let date = new Date();
let birth = new Date(this.birthday)
let m1 = date.getMonth()
let m2 = birth.getMonth()
let et = m1>m2?0:1
if(m1==m2 && data.getDate() > birth.getDate()){
et = 0;
}
return date.getFullYear() - birth.getFullYear() - et
}
return 0;
}
},
filters:{
}
})
</script>
</body>
</html>
生命周期钩子函数执行顺序
结论:
- 组件挂载维度:beforeMount、render、mounted
- 数据更新维度:beforeUpdate、render、updated
var vm = new Vue({
data: {
message: '111'
},
beforeMount() {
console.log("beforeMount");
},
mounted() {
console.log("mounted");
},
beforeUpdate() {
console.log("beforeUpdate");
},
updated() {
console.log("updated");
},
render(){
console.log("render");
}
})
父子组件嵌套钩子函数调用顺序
// father.vue示例代码
<script>
import son from './son.vue'
export default {
data () {
return {
fmsg: '我是父组件模板'
}
},
beforeCreate () {
console.log('father-beforeCreate');
},
created () {
console.log('father-created');
},
beforeMount () {
console.log('father-beforeMount');
},
mounted () {
console.log('father-mounted');
},
beforeUpdate () {
console.log('father-beforeUpdate');
},
updated () {
console.log('father-updated');
},
beforeDestroy () {
console.log('father-beforeDestroy');
},
destroyed () {
console.log('father-destroyed');
},
methods: {
fatherClick () {
this.fmsg = 'ffffff'
},
},
render () {
console.log('father-render');
return (
<div>
<div class="father" onClick={this.fatherClick}>{this.fmsg}</div>
<son />
</div>
)
}
}
</script>
// son.vue
<script>
export default {
data () {
return {
smsg: '我是子组件模板'
}
},
beforeCreate () {
console.log('son-beforeCreate');
},
created () {
console.log('son-created');
},
beforeMount () {
console.log('son-beforeMount');
},
mounted () {
console.log('son-mounted');
},
beforeUpdate () {
console.log('son-beforeUpdate');
},
updated () {
console.log('son-updated');
},
beforeDestroy () {
console.log('son-beforeDestroy');
},
destroyed () {
console.log('son-destroyed');
},
methods: {
sonClick () {
this.smsg = 'sssssss'
},
},
render () {
console.log('son-render');
return (
<div class="son" onClick={this.sonClick}>{this.smsg}</div>
)
}
}
</script>
// main.js
import Vue from "vue";
import father from './components/testFatherAndSonInvokeOrder/father.vue'
new Vue({
data () {
return {
}
},
components: {
father
},
render () {
return <father />
}
}).$mount("#app");