此学习教程是对官方教程的解析,

本章节主要涉及到的官方教程地址:

生命周期图示 — Vue.js

上一章 :vue生命周期实战(三)—— 实例更新并深刻理解nextTick、watch和生命周期的关系

本章节介绍实例更新阶段的生命周期钩子:beforeDestroy和destroyed

beforeDestroy和destroyed的区别

beforeDestroy和destroyed的区别不大,都在实例销毁时进行处理。

生命周期钩子可获取的对象常见应用场景
beforeDestroy和mounted可获取对象相同)常用于销毁定时器、解绑全局事件、销毁插件对象等操作
destroyed和mounted可获取对象相同做提示,写日志等

销毁实例的情况

外部销毁

外部销毁是从实例外部销毁实例。不但销毁实例本身,而且移除实例的DOM。

v-if

如果v-if的表达式为false的话,是会销毁组件的:

<!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>vue生命周期学习</title>
  <script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
  <div id="app">
  	  <template v-if="isShow">
          <v-ul :max="maxLen">
          </v-ul>
      </template>
      <button @click="toggle">切换</button>
  </div>


<script>
var v_ul_config = Vue.extend({
			template: '\
		 <ul>\
		   <li v-for="(item,index) in max" :key="index">{{item}}</li>\
		 </ul>\
	  ',
	  props: ['max'],
	  beforeCreate() {
		 console.log('ul beforeCreate')
	  },
	  created() { 
		 console.log('ul created')
	  },
	  beforeMount() { 
		console.log('ul beforeMount')
	  },
	  mounted() { 
		console.log('ul mounted')
	  },
	  beforeUpdate() {
		console.log('ul beforeUpdate')
	  },
	  updated(){ 
	    console.log('ul updated')
	  },
	  beforeDestroy() {
		console.log('ul beforeDestroy')
	  },
	  destroyed(){ 
	    console.log('ul destroyed')
	  }  
});

Vue.component('v-ul', v_ul_config)

var vm = new Vue({
  el: '#app',
  data: {
    maxLen: 3,
	isShow: true
  },
  methods: {
	  toggle() {
		this.isShow = !this.isShow
	  } 
  }
})
</script>
</body>
</html>

运行结果:
在这里插入图片描述
可以看到,刚进入页面时,isShow为true, v-ul组件进行了创建和挂载;点击切换按钮,isShow转为false时,v-ul组件销毁了。

组件切换

组件基础中的例子基础上,加上生命周期观察:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="example">
    <input type="button" value="A组件" @click="currentTabComponent='a_component'"/>
    <input type="button" value="B组件" @click="currentTabComponent='b_component'"/>

    <!--创建动态组件 <component :is="组件名称"></component> -->
    <component :is="currentTabComponent"></component>
</div>

<script>
new Vue({
	el: '#example',
	data:{
		currentTabComponent:'a_component'
	},
	components:{
		a_component:{
			template:'<h1>我是A组件</h1>',
			beforeCreate() {
				console.log('a_component beforeCreate')
			},
			created() { 
				console.log('a_component created')
			},
			beforeMount() { 
				console.log('a_component beforeMount')
			},
			mounted() { 
				console.log('a_component mounted')
			},
			beforeDestroy() {
				console.log('a_component beforeDestroy')
		  	},
		  	destroyed(){ 
				console.log('a_component destroyed')
		  	}  
		},
		b_component:{
			beforeCreate() {
				console.log('b_component beforeCreate')
			},
			created() { 
				console.log('b_component created')
			},
			beforeMount() { 
				console.log('b_component beforeMount')
			},
			mounted() { 
				console.log('b_component mounted')
			},
			template:'<h1>我是B组件</h1>',
			beforeDestroy() {
				console.log('b_component beforeDestroy')
		  	},
		  	destroyed(){ 
				console.log('b_component destroyed')
		  	} 
		}
	}
})
</script>
</body>
</html>

运行结果:
在这里插入图片描述
可以看到,刚进入页面时,A组件创建和挂载;点击B组件按钮,B组件创建和挂载,并在B组件创建后挂载完成前,A组件进行了销毁。

内部销毁

vm.$destroy()是组件内部销毁自已。和外部销毁的区别在于,内部销毁不会移除DOM。所以一般需要加上移除DOM的代码。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<test></test>
</div>
<template id="test-template">
    <button @click="destroy" class="testBtn">内部销毁</button>
</template>

<script>
Vue.component('test',{
	template: '#test-template',
	methods: {
		destroy() {
			this.$destroy()
			//this.$destroy()不会销毁DOM, 需对DOM进行处理
			//document.querySelector('.testBtn').remove()
		}
	},
	mounted () {
	},
	beforeDestroy () {
		console.log('beforeDestroy')
	},
	destroyed () {
		console.log('destroyed')
	}
})

new Vue({
	el: '#app',
	data: {
		flag: true
	}
})
</script>
</body>
</html>

运行结果:
在这里插入图片描述
可以看到,实例已经销毁了,但内部销毁这个按钮还在。要移除这个按钮还需要额外的DOM操作代码。

beforeDestroy应用

实例销毁前销毁定时器

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<test></test>
</div>
<template id="test-template">
    <button @click="destroy" class="testBtn">内部销毁</button>
</template>

<script>
Vue.component('test',{
	template: '#test-template',
	methods: {
		destroy() {
			this.$destroy()
			document.querySelector('.testBtn').remove()
		}
	},
	mounted () {
		this.time = setInterval ( () => {
			console.log( 'ping!' )
		},1000)
	},
	beforeDestroy () {
		console.log('beforeDestroy')
		clearInterval( this.time )
	},
	destroyed () {
		console.log('destroyed')
	}
})

new Vue({
	el: '#app',
	data: {
		flag: true
	}
})
</script>
</body>
</html>

运行结果:
在这里插入图片描述
可以看到,实例挂载后,开启一个定时器。等实例销毁时,在beforeDestory中将定时器销毁。

本章节教程结束。

全部教程地址:Vue入门实战教程 | 寒于水学习网

vue生命周期实战系列:

vue生命周期实战(一)—— 实例创建

vue生命周期实战(二)——实例挂载

vue生命周期实战(三)—— 实例更新并深刻理解nextTick、watch和生命周期的关系

vue生命周期实战(四)——实例销毁

Logo

前往低代码交流专区

更多推荐