Vue生命周期和钩子函数及使用keeplive缓存页面不重新加载

vue

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 >

......

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

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

<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生命周期和钩子函数及使用keeplive缓存页面不重新加载 的全部内容, 来源链接: utcz.com/z/376078.html

回到顶部