组件生命周期
组件生命周期指的是组件从创建到销毁的过程,在这个过程中的一些不同的阶段,vue
会调用指定的一些组件方法
基本生命周期函数有下面几个阶段:
- 创建阶段
- 挂载阶段
- 更新阶段
- 卸载阶段
每一个阶段都对应着 <u>之前</u> 和 <u>之后</u> 两个函数
创建阶段
beforeCreate()
初始化阶段,应用不多,创建之前调用
created()
在实例创建完成后被立即调用,该阶段完成了对 data
中的数据的 observer
,该阶段可以处理一些异步任务
挂载阶段
beforeMount()
在挂载开始之前被调用,应用不多
mounted()
该阶段执行完了模板解析,以及挂载。同时组件根组件元素被赋给了 $el
属性,该阶段可以通过 DOM 操作来对组件内部元素进行处理了
更新阶段
beforeUpdate()
数据更新时调用,但是还没有对视图进行重新渲染,这个时候,可以获取视图更新之前的状态
updated()
由于数据的变更导致的视图重新渲染,可以通过 DOM 操作来获取视图的最新状态
卸载阶段
beforeDestroy()
实例销毁之前调用,移除一些不必要的冗余数据,比如定时器
destroyed()
Vue 实例销毁后调用
errorCaptured()
当捕获一个来自子孙组件的错误时被调用,此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false
以阻止该错误继续向上传播。
<template>
<div id="app">
<button @click="n++">{{n}}</button>
<button @click="is = !is">{{is}}</button>
<HelloWorld v-if ="is" :num = n></HelloWorld>
</div>
</template>
<script>
//导出来的是一个对象, 不是组件
import HelloWorld from './components/HelloWorld.vue'
console.log(HelloWorld);
export default {
name: 'App',
components: {
//注册对象,属性名:属性值
HelloWorld
},
data(){
return{
n:0,
is:true
}
},
//组件的生命周期分为四个阶段
//1.创建阶段
// 初始化组件(准备组件自身的内容)
beforeCreate(){
console.log('创建之前');
},
created(){
console.log('创建之后');
console.log(this.$data)
},
//2.挂载阶段 挂载的是组件和DOM树数据 建立联系
beforeMount(){
console.log('挂载之前');
},
mounted(){
console.log('挂载之后');
console.log(this.$el)
},
//3.更新阶段(数据驱动视图)
beforeUpdate(){
console.log('数据更新之前');
},
updated(){
console.log('数据更新之后');
},
//4.卸载阶段
beforeDestroy(){
console.log('数据卸载之前');
},
destroyed(){
console.log('数据卸载之后 ');
},
errorCaptured:(err,vm,info) =>{
console.log("报错了");
console.log(err);
console.log(vm);
console.log(info);
return false;
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
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
来进行操作
nextTick
方法将在更新队列循环结束之后立即调用
<template>
<div id="app">
<HelloWorld></HelloWorld>
<button @click="info">{{n}}</button>
<input type = "text" ref = "user">
<button @click="post">提交</button>
</div>
</template>
<script>
//导出来的是一个对象, 不是组件
import HelloWorld from './components/HelloWorld.vue'
//console.log(HelloWorld);
export default {
name: 'App',
components: {
//注册对象,属性名:属性值
HelloWorld
},
data(){
return{
n:0,
is:true
}
},
methods:{
info(e){
this.n++;
//console.log(this.n, e.target.innerHTML);
this.$nextTick(()=>{
console.log(this.n,e.target.innerHTML);
});
},
post(){
if(this.$refs.user.value !=""){
console.log("提交",this.$refs.user.value)
}else{
console.log("不提交");
this.$refs.user.focus();
}
}
}
}
</script>
<style>
</style>