Vue重学 Day3

335 阅读3分钟

上期,简单介绍了关于Vue基本指令。这期,来探讨下Vue生命周期

Vue生命周期

从创建到销毁的过程,称为生命周期。即创建、渲染、更新、销毁。
详细过程为创建前后、渲染前后、更新前后、销毁前后。
详情如图所示

1341218-20180726161418133-1878075753.png
结合上面图片和代码会将生命周期讲详细

new Vue

创建Vue实例。

init Event & Lifecycle

初始化事件与生命周期。data还未初始化

beforeCreate

生命周期开始的初期。此时无法访问实例对象中的数据
    <template>
        <div>
            {{msg}}
        </div>
    </template>
    
    <script>
        export default{
            data(){
                return{
                    msg:'Jsnewbie'
                }
            },
            beforeCreate(){
                console.log('beforeCreate',this)
                debugger
            }
        }
    </script>

be5af73d77af4564b0738d57db59af61_tplv-k3u1fbpfcp-no-mark_1280_960_0_0.awebp 图上所示,可以看到打印结果。输出了beforeCreate。但是this并没有打印出data中的数据。

init injections & reactivity

翻译为初始注入和反应性。这时候,仍然是初始化过程,是数据监测和数据代理的初始化过程。下一步才是created

created

实例创建完成。此时的this可以访问到data中的数据
    <script>
        export dafault{
            data(){
                return{
                    msg:'Jsnewbie'
                }
            },
            beforeCreate(){
                console.log('beforeCreate')
            },
            created(){
                console.log('created')
                console.log(this)
                debugger
            }
            
        }
    </script>

2.awebp 通过上述的图片显示,也可以对比下beforeCreate与created之间的变化。

beforeMount

挂载之前。在生命周期图中,created到beforeMount的过程,vue进行了许多判断事件。判断页面中的根标签、template选项等。目的只有一个:解析模板,在内存中生成虚拟DOM。
在这里,并没有将虚拟DOM插入到页面中真是DOM,页面中显示的也是没有编译过的结构
<body>
    <div id="root">
         <h2>data中的msg{{msg}}</h2>
    </div>
</body>
<script>
    export default{
        data(){
            return{
                msg:'Jsnewbie'
            }
        },
        beforeCreate(){
             console.log('beforeCreate')
        },
        created(){
              console.log('created')
        },
        beforeMount(){
               console.log('beforeMount')
               debugger
        }
    }
</script>

3.awebp 图片中显示,挂载前,原页面并没有将虚拟DOM插入到真实DOM中

mounted

挂载完成。虚拟DOM插入到页面真是DOM
<script>
    export default{
        data(){
            return{
                msg:'Jsnewbie'
            }
        },
        beforeCreate(){
             console.log('beforeCreate')
        },
        created(){
              console.log('created')
        },
        beforeMount(){
               console.log('beforeMount')
        },
        mounted(){
          console.log('mounted');
          debugger
        }
    }
</script>

6.awebp 此刻,vue初始化过程结束。在这个周期内,可以进行启动定时器,发送请求等

beforeUpdate

      data:{
            msg:"Jsnewbie"
        },
        methods:{
            changeMsg(){
                this.msg = "Jsnewbie666"
            }
        },
        beforeCreate(){
            console.log('beforeCreate')
        },
        created(){
            console.log("created")
        },
        beforeMount(){
            console.log("beforeMount")
        },
        mounted(){
            console.log("mounted")  
        },
        beforeUpdate(){
            console.log("beforeUpdate")
            console.log(this.msg)
            debugger
        }

7.awebp

updated

更新完成
    data:{ msg:"Jsnewbie" }, 
    methods:{ 
        changeMsg(){ 
                this.msg = "Jsnewbie666" 
            } 
           }, 
           beforeCreate(){ 
               console.log('beforeCreate') 
           }, 
           created(){ 
               console.log("created") 
           }, 
           beforeMount(){ 
               console.log("beforeMount") 
           }, 
           mounted(){ 
               console.log("mounted") 
           }, 
           beforeUpdate(){ 
               console.log("beforeUpdate") 
           }, 
           updated(){ 
               console.log("updated") 
               console.log(this.msg) 
               debugger 
           }

更新完成后,数据保持一致

boforeDestpry & destory

这两个也就是对实力销毁。可以在这里做下收尾效果:清除定时器。
需注意:如果调用实例对象的$destory,则会解除全部指令及事件监听器
    methods:{
        changeMsg(){
            consloe.log("数据被修改!!!")
            this.msg = "Jsnewbie666"
        },
        remove(){
            console.log("销毁Vue实例")
            this.$destory()
        }
    }

9.awebp 注意看图片,点击的销毁实例,触发了destroyed这个生命周期函数,然后点击的修改数据这个按钮,可以看到这个changeMsg方法依然被触发!这里要说明一下,官方给的解释是vue会解绑他的全部指令及事件监听器,官网的这个事件监听器指的是vue的自定义事件,并不是原生的DOM事件。button绑定的@click事件最终vue也会渲染成原生的DOM事件

vm实例上的属性和方法

  • this.$data:vm上的数据

  • this.$watch:监控

  • this.$el:当前el元素

  • this.$set:后加的属性实现响应式变化

  • this.$option:vm上的所有属性

  • this.refs:dom元素通过vfor循环出来的可以获取多个,是数组形式;不是通过vfor循环出来的,只能获取一个,相当于原生js中的idvue中使用refs: dom元素通过v-for循环出来的可以获取多个,是数组形式; 不是通过v-for循环出来的,只能获取一个,相当于原生js中的id,vue中使用refs更为优雅

  • this.$nextTick(( )=>{ // 异步方法,等待dom渲染完成后再获取vm })

$nextTick括号中的自执行函数是在dom渲染完成后执行的 dom渲染是异步的,如果数据变化后想立即获取真实dom中的最新内容,需要等待页面渲染完成后才能去获取,因此所有的操作dom方法最好放在nextTick中,mounted中常用。 例如:

<div id="app">
	<div ref="wrap">
		<div v-for="a in arr" ref="mydiv"></div>
	</div>
</div>
<script>
let vm = new Vue({
	el: '#app',
	data: {
	arr: [1, 2, 3]
},
mounted(){
	console.log(this.$refs.mydiv) // [div, div, div]
	this.arr = [1, 2, 3, 4];
	console.log(this.$refs.wrap) // [1, 2, 3]
	this.nextTick(() => {
		console.log(this.$refs.wrap); // [1, 2, 3, 4]
	})
}
})
</script>

10.awebp

总结

钩子函数触发的行为此阶段的事
beforeCreatevue实例的挂载元素$el和数据对象data都为undefined,还未初始化。加loading事件
createdvue实例的数据对象data有了,$el还没有结束loading、请求数据为mounted渲染做准备
beforeMountvue实例的$el和data都初始化了,但还是虚拟的dom节点,具体的data.filter还未替换。
mountedvue实例挂载完成,data.filter成功渲染配合路由钩子使用
beforeUpdatedata更新前触发
updateddata更新时触发数据更新时,做一些处理(此处也可以用watch进行观测)数据更新时,做一些处理(此处也可以用watch进行观测)
beforeDestroy组件销毁时触发
destroyed组件销毁时触发,vue实例解除了事件监听以及和dom的绑定(无响应了),但DOM节点依旧存在组件销毁时进行提示