vue生命周期函数(钩子函数)

    科技2022-07-17  103

    生命周期函数(钩子函数)

    https://segmentfault.com/a/1190000008010666 https://segmentfault.com/a/1190000011381906

    https://cn.vuejs.org/v2/guide/instance.html#生命周期图示(图)

    beforeCreate:组件实例刚被创建,无属性 created:组件实例创建完成,有属性,没有DOM(el没有被挂载), data已经完成,el生成了,还没有挂载。 beforeMount:模板编译之前,有DOM,并没有把DOM挂载 mounted:模板编译之后,数据都加载到页面上 beforeUpdate:组件更新之前,数据已经更新了,但是没有挂载 updated:组件更新之后,数据已经更新了,并且挂载 activated: keep-alive,组件被激活时 deactivated: keep-alive,组件被激活完成 beforeDestroy:销毁之前,实例仍然完全可用 destroyed:销毁完成,调用后,Vue 实例指示的所有东西都会解绑定, 所有的事件监听器会被移除,所有的子实例也会被销毁 执行了destroy操作,原来样式保留,后续就不再受vue控制了。

    组件生命周期

    组件生命周期指的是组件从创建到销毁的过程,在这个过程中的一些不同的阶段,vue 会调用指定的一些组件方法

    基本生命周期函数有下面几个阶段:

    创建阶段挂载阶段更新阶段卸载阶段

    每一个阶段都对应着 之前 和 之后 两个函数

    <!DOCTYPE html> <html lang="en"> <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"> <title>Document</title> </head> <body> <div id="app"> <h1>{{title}}</h1> <button @click="show=!show">隐藏</button> <hr> <template v-if="hasError"> <h4>有错误发生了</h4> </template> <template v-else> <kkb-component v-if="show" :t="title"></kkb-component> </template> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> const kkbComponent = { props: ['t'], template: ` <div> <h1>kkbComponent - {{t.a.b}}</h1> </div> `, beforeCreate() { console.log('kkbComponent:beforeCreate'); console.log('data', this.$data); console.log('el', this.$el); console.log('='.repeat(100)); }, created() { console.log('kkbComponent:created'); console.log('data', this.$data); console.log('el', this.$el); console.log('='.repeat(100)); }, beforeMount() { console.log('kkbComponent:beforeMount'); console.log('data', this.$data); console.log('el', this.$el); console.log('='.repeat(100)); }, mounted() { console.log('kkbComponent:mounted'); console.log('data', this.$data); console.log('el', this.$el); console.log('='.repeat(100)); }, beforeUpdate() { console.log('kkbComponent:beforeUpdate'); console.log('props', this.$props); console.log('='.repeat(100)); }, updated() { console.log('kkbComponent:updated'); console.log('='.repeat(100)); }, beforeDestroy() { console.log('kkbComponent:beforeDestroy'); console.log('this', this); console.log('='.repeat(100)); }, destroyed() { console.log('kkbComponent:destroyed'); console.log('this', this); console.log('='.repeat(100)); } } let app = new Vue({ el: '#app', data: { title: '开课吧', show: true, hasError: false }, components: { 'kkb-component': kkbComponent }, beforeCreate() { console.log('beforeCreate'); console.log('data', this.$data); console.log('el', this.$el); console.log('='.repeat(100)); }, created() { console.log('created'); console.log('data', this.$data); console.log('el', this.$el); console.log('='.repeat(100)); }, beforeMount() { console.log('beforeMount'); console.log('data', this.$data); console.log('el', this.$el); console.log('='.repeat(100)); }, mounted() { console.log('mounted'); console.log('data', this.$data); console.log('el', this.$el); console.log('='.repeat(100)); }, beforeUpdate() { console.log('beforeUpdate'); console.log('props', this.$props); console.log('='.repeat(100)); }, updated() { console.log('updated'); console.log('='.repeat(100)); }, beforeDestroy() { console.log('beforeDestroy'); console.log('this', this); console.log('='.repeat(100)); }, destroyed() { console.log('destroyed'); console.log('this', this); console.log('='.repeat(100)); }, errorCaptured(err, vm, info) { console.log('errorCaptured'); console.log(err, vm, info); console.log('='.repeat(100)); this.hasError = true; return false; } }); </script> </body> </html>

    创建阶段

    beforeCreate()

    初始化阶段,应用不多

    created()

    在实例创建完成后被立即调用,该阶段完成了对 data 中的数据的 observer,该阶段可以处理一些异步任务

    挂载阶段

    beforeMount()

    在挂载开始之前被调用,应用不多

    mounted()

    该阶段执行完了模板解析,以及挂载。同时组件根组件元素被赋给了 $el 属性,该阶段可以通过 DOM 操作来对组件内部元素进行处理了

    更新阶段

    beforeUpdate()

    数据更新时调用,但是还没有对视图进行重新渲染,这个时候,可以获取视图更新之前的状态

    updated()

    由于数据的变更导致的视图重新渲染,可以通过 DOM 操作来获取视图的最新状态

    卸载阶段

    beforeDestroy()

    实例销毁之前调用,移除一些不必要的冗余数据,比如定时器

    destroyed()

    Vue 实例销毁后调用

    errorCaptured()

    当捕获一个来自子孙组件的错误时被调用,此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

    ref 与 $refs

    如果我们希望获取组件节点,进行 DOM 相关操作,可以通过 ref 和 $refs 来完成

    <!DOCTYPE html> <html lang="en"> <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"> <title>Document</title> </head> <body> <div id="app"> <h1>{{title}}</h1> <button @click="getBoxHeight">获取 box 的高度</button> <button @click="getKKBComponent">获取自定义组件实例及内部方法</button> <hr> <div ref="box"> 这是内容<br>这是内容<br>这是内容<br>这是内容<br>这是内容<br> </div> <hr> <kkb-component ref="kkb" :t="title"></kkb-component> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> const kkbComponent = { props: ['t'], data() { return { isShow: true } }, template: ` <div v-if="isShow"> <h1>kkbComponent - {{t}}</h1> </div> `, methods: { hide() { this.isShow = false; } } } let app = new Vue({ el: '#app', data: { title: '开课吧' }, components: { 'kkb-component': kkbComponent }, mounted() { console.log(this.$refs.kkb); }, methods: { getBoxHeight() { console.log( this.$refs.box.clientHeight ); }, getKKBComponent() { this.$refs.kkb.hide(); } } }); </script> </body> </html>

    ref

    给元素或组件添加 ref 属性,则该元素或组件实例对象将被添加到当前组件实例对象的 $refs 属性下面

    $refs

    该属性的是一个对象,存储了通过 ref 绑定的元素对象或者组件实例对象

    nextTick

    当数据更新的时候,视图并不会立即渲染,这个时候我们期望获取到视图更新后的数据,可以通过 nextTick 来进行操作

    <!DOCTYPE html> <html lang="en"> <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"> <title>Document</title> </head> <body> <div id="app"> <h1>{{title}}</h1> <button @click="setBoxContent">设置新的内容</button> <hr> <div ref="box" style="background: red" v-html="content"></div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> let app = new Vue({ el: '#app', data: { title: '开课吧', n: 1 }, computed: { content() { return new Array(this.n).fill(this.title).join('<br>'); } }, methods: { setBoxContent() { this.n++; this.$nextTick(_=>{ console.log( this.$refs.box.clientHeight ); }) } } }); </script> </body> </html>

    nextTick 方法将在更新队列循环结束之后立即调用

    Processed: 0.009, SQL: 8