×

VUE 钩子函数

前端技术网 前端技术网 发表于2024-02-03 15:57:25 浏览1561 评论0

抢沙发发表评论

一、Vue生命周期及钩子函数

其实生命周期就是指Vue实例创建的过程,从开始到销毁的过程。在这个过程中呢又分:开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列...在这个过程中呐,有一些方法(函数)会被触发执行,也就是给了我们可以去编写逻辑的机会。

VUE 钩子函数

下面附一张Vue生命周期图

Vue生命周期一共有11个钩子函数,图中一共有8个钩子函数。在Vue实例被创建之后,Vue挂载元素阶段会有4个钩子函数,它们是自动执行的且只执行一次,数据更新阶段有2个钩子函数会被执行,销毁阶段有2个钩子会被执行,下面我们来详细看一看这8个钩子函数。

在实例初始化之后,数据观测(dataobserver)和 event/watcher事件配置之前被调用。访问不到数据

在实例创建完成后被立即调用可以获取数据(常用作发送异步请求获取数据)

VUE 钩子函数

在挂载开始之前被调用可以访问数据编译模板结束,虚拟dom已经存在

可以拿到节点和数据 常用实例被挂载后调用.

注意: mounted 不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted 内部使用 Vue实例.$nextTick:在Vue实例上有一个方法,它会延迟执行,直到Dom加载完成.

补充:ref表示节点this.$refs.ref的标识就可以拿到节点了

数据更新时调用,发生在虚拟DOM打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

常用的监控数据的变化由于数据更改导致的虚拟DOM重新渲染和打补丁

补充:watch是监控特定数据的变化,updated是监控组件里所有数据的变化

实例销毁之前调用,在这一步,实例仍然完全可用。 常用于清理资源,防止内存的泄露

实例销毁后调用。该钩子被调用后,对应 Vue实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。

 被keep-alive缓存的组件激活时调用。

被keep-alive缓存的组件停用时调用。

当捕获一个来自子孙组件的错误时被调用。

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

那么Vue的11个声明周期函数就给大家简单介绍完毕了!你学会了嘛!!!

【详情请参照】 https://cn.vuejs.org

二、vue钩子函数有哪些含义

Vue的钩子函数是Vue.js组件生命周期中的特定阶段,在这些阶段中,可以通过调用特定的钩子函数来执行代码。

详细解释:

一、Vue.js的钩子函数概述

在Vue.js中,组件的生命周期是由一系列的阶段组成的,每一个阶段对应于组件的不同状态。在这些阶段中,Vue.js提供了一些特殊的函数,称为“钩子函数”,允许开发者在特定的阶段执行特定的代码。这就是钩子函数的基本含义。

二、Vue.js的钩子函数种类与含义

1. `beforeCreate`:实例初始化之后,数据观测(data observer)和事件/监听事件配置之前被调用。

2. `created`:实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算,`watch/event`事件回调。然而,挂载阶段还没开始,`$el`属性目前尚不可见。

3. `beforeMount`:在挂载开始之前被调用。相关的 `render`函数首次被调用。

4. `mounted`:`el`被新创建的 `vm.$el`替换,并挂载到实例上去之后调用该钩子。如果 `root`实例挂载了一个 `in-document`元素,当 `mounted`被调用时 `vm.$el`也在文档内。

5. `beforeUpdate`:数据更新时调用,发生在虚拟DOM打补丁之前。这里适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器。

6. `updated`:由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。

7. `beforeDestroy`:实例销毁之前调用。在这一步,实例仍然完全可用。

8. `destroyed`:Vue实例销毁后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。

三、钩子函数的使用示例

例如,我们可以在`created`钩子函数中初始化一些数据,或者发起网络请求获取初始化数据:

```javascript

new Vue({

data:{

items: []

},

created: function(){

axios.get('/api/items').then(response=>{

this.items= response.data;

});

}

})

```

在以上的例子中,我们在组件创建后,通过`axios`发起了网络请求,获取数据,并将获取到的数据赋值给了`items`。这就是在Vue.js中使用钩子函数的一个基本示例。

三、vue执行方法后如何不让钩子函数加载

每个Vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期,在这个过程中会有一些钩子函数会得到回调

Vue中能够被网页直接使用的最小单位就是组件,我们经常写的:

var vm= new Vue({

el:'#app',

......

}

是根组件,el指定了它挂载到哪里(id为app的元素包裹的部分)

也可以跟普通组件一样这样写:

var vm= new Vue({

......

}

vm.$mount("#app");

也可以跟普通组件一样在里面定义template属性指定模板,比如

new Vue({

el:'#app',

router,

components:{ App},

template:'<App/>',

methods:{

}

})

根组件里面可使用子组件,并起一个名字:

var vm= new Vue({

......

components:{

'my-components': child

}

}

vm.$mount("#app");

这样就可以在id为app的div中使用名字my-components来引用child组件

div id="app">

......

<my-components:msg="msg1" v-if="show"></my-components>

......

</div>

beforeCreate:在实例初始化之后,这时候el和 data并未初始化

created:实完成了 data数据的初始化,但Vue实例使用的根 DOM元素el还未初始化

beforeMount:data和el均已经初始化,el并没有渲染进数据,el的值为“虚拟”的元素节点

mounted:此时el已经渲染完成并挂载到实例上

使用keeplive缓存组件视图

有时候我们显示页面的时候不需要重新加载,使用上次的缓存页面即可,比如单页面应用使用路由进行页面切换时,再切回来,很多时候并不需要重新加载

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>Title</title>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

</head>

<body>

<div id="app">

<p>{{message}}</p>

<keep-alive>

<my-components msg="hello" v-if="show"></my-components>

</keep-alive>

</div>

</body>

<script>

var child={

template:'<div><input></input></div>',

props: ['msg'],

data: function(){

return{

childMsg:'child'

};

},

created: function(){

console.log('child reated!');

},

mounted: function(){

console.log('child mounted!');

},

deactivated: function(){

console.log('component deactivated!');

},

activated: function(){

console.log('component activated');

}

};

var app= new Vue({

el:'#app',

data: function(){

return{

message:'father',

show: true

};

},

components:{

'my-components': child

}

});

</script>

</html>

被keeplive包裹的组件会使用缓存,我们可以在input里输入文字

在控制台控制app.show=false,再app.show=true,可以发现前一次输入的文字还在,说明使用了缓存

deactivated、activated两个方法只在被keeplive包裹的组件中才会回调,deactivated在组件消失时调用,activated在组件显示时调用

综合示例

<!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>

<script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>

<style>

</style>

</head>

<body>

<div id="app">

<p>{{message}}</p>

<keep-alive>

<my-components:msg="msg1" v-if="show"></my-components>

</keep-alive>

</div>

</body>

<script>

var child={

template:'<div>from child:{{childMsg}}</div>',

props: ['msg'],

data: function(){

return{

childMsg:'child'

}

},

beforeCreate: function(){

debugger;

},

created: function(){

debugger;

},

beforeMount: function(){

debugger;

},

mounted: function(){

debugger;

},

deactivated: function(){

alert("keepAlive停用");

},

activated: function(){

console.log('component activated');

},

beforeDestroy: function(){

console.group('beforeDestroy销毁前状态===============》');

var state={

'el': this.$el,

'data': this.$data,

'message': this.message

}

console.log(this.$el);

console.log(state);

},

destroyed: function(){

console.group('destroyed销毁完成状态===============》');

var state={

'el': this.$el,

'data': this.$data,

'message': this.message

}

console.log(this.$el);

console.log(state);

},

};

var vm= new Vue({

el:'#app',

data:{

message:'father',

msg1:"hello",

show: true

},

beforeCreate: function(){

debugger;

},

created: function(){

debugger;

},

beforeMount: function(){

debugger;

},

mounted: function(){

debugger;

},

beforeUpdate: function(){

alert("页面视图更新前");

},

updated: function(){

alert("页面视图更新后");

},

beforeDestroy: function(){

console.group('beforeDestroy销毁前状态===============》');

var state={

'el': this.$el,

'data': this.$data,

'message': this.message

}

console.log(this.$el);

console.log(state);

},

destroyed: function(){

console.group('destroyed销毁完成状态===============》');

var state={

'el': this.$el,

'data': this.$data,

'message': this.message

}

console.log(this.$el);

console.log(state);

},

components:{

'my-components': child

}

});

</script>

</html>

debugger用于在chrome中加载时自动断点

根组件的调用中:

beforeCreate执行时,data和el均为undefined

created执行时,data已经初始化,el为undefined

beforeMount执行时,data和el均已经初始化,此时el并没有渲染进数据,

此时用console.log(this.$el);打印el,p元素内容还是{{message}},还没有替换为真实的数据

el指定组件挂载的地方,如果组件没有定义template,vue就会把el对应元素包裹的块拿出来渲染(比如data数据渲染)后再放回去,el对象可以操作里面的各个html子节点,如果指定了template,就会渲染template再挂载到el里面

mounted执行时,此时el已经渲染完成并挂载到实例上

加载渲染调用顺序:

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->子activated(如果是缓存视图)->父mounted->父activated(如果是缓存视图)

控制根组件更新

控制台输入vm.msg1="123"

数据变化之前会调用beforeUpdate,更新后调用updated,这两个方法只有在更新数据的时候才调用(包括隐藏或显示组件,不管是不是缓存视图)

控制子组件更新

vm.$children[0].childMsg="111"

只会调用自己的beforeUpdate和updated,跟父组件无关

控制子组件隐藏显示:

隐藏:

父beforeUpdate->子deactivated(如果是缓存视图)->父updated

显示:

父beforeUpdate->子activated(如果是缓存视图)->父updated

销毁流程

vm.$destroy()

父beforeDestroy->子deactivated(如果是缓存视图)->子beforeDestroy->子destroyed->父destroyed

四、vue生命周期11个钩子函数

vue生命周期11个钩子函数如下:

1、组件通过new Vue()创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载,无法访问到数据和真实的dom,一般不做操作。

2、挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取。

3、接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数。

4、一般可以在这里做初始数据的获取下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情。

5、当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事。

6、当更新完成后,执行updated(据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom)。

7、经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等,组件的数据绑定、监听……去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以。

好了,文章到这里就结束啦,如果本次分享的VUE 钩子函数和vue钩子函数有哪些含义问题对您有所帮助,还望关注下本站哦!