目录
1. 生命周期
1.1 引出生命周期
1.2 生命周期——挂载流程
1.3 生命周期——更新流程
1.4 生命周期——销毁流程
1.5 总结
2. 非单文件组件
2.1 对组建的理解
2.2 非单文件组件
2.3 组件的注意点
2.4 组件的嵌套
2.5 VueComponent构造函数
1. 生命周期
生命周期函数里得this都是vm
1.1 引出生命周期
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>引出生命周期</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 
				生命周期:
						1.又名:生命周期回调函数、生命周期函数、生命周期钩子。
						2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。
						3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
						4.生命周期函数中的this指向是vm 或 组件实例对象。
		-->
		<!-- 准备好一个容器-->
		<div id="root">
			<h2 v-if="a">你好啊</h2>
			<!-- style="{opacity}透明度是1 ,
	{opacity:opacity}第一个是css属性,第二个是数据的名(0/1不显示/显示)重名简写-->
			<h2 :style="{opacity}">欢迎学习Vue</h2>
		</div>
	</body>
	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		
		 new Vue({
			el:'#root',
			data:{
				a:false,
				opacity:1
			},
			methods: {
				
			},
			//Vue完成模板的解析并把初始的(只调这一次)真实DOM元素放入页面后(挂载完毕)调用mounted
			mounted(){
				console.log('mounted',this)
				//setInterval不是vue管理的函数,每隔一段时间透明度变化函数
				setInterval(() => {
					this.opacity -= 0.01
					if(this.opacity <= 0) this.opacity = 1
				},16)
			},
		})
		//通过外部的定时器实现(不推荐)
		/* setInterval(() => {
			vm.opacity -= 0.01
			if(vm.opacity <= 0) vm.opacity = 1
		},16) */
	</script>
</html> 
1.2 生命周期——挂载流程

 
这里头得叫挂载流程
1.3 生命周期——更新流程

1.4 生命周期——销毁流程


vm.$destroy属于自杀,下面带1得红圈是他杀
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>分析生命周期</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 准备好一个容器-->
		<div id="root" :x="n">
			<h2 v-text="n"></h2>
			<h2>当前的n值是:{{n}}</h2>
			<button @click="add">点我n+1</button>
			<button @click="bye">点我销毁vm</button>
		</div>
	</body>
	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		new Vue({
			el:'#root',
        //template不能做根标签使用
			
//用下面这种方式代表下面div里面的东西将全部替换上面<div id="root" :x="n">,会把x搞没
			// template:`用这个当模板了,最后又放在上面的div里面
			// 	<div> //h2和button必须两个包裹在div里面形成一个节点
			// 		<h2>当前的n值是:{{n}}</h2>
			// 		<button @click="add">点我n+1</button>
			// 	</div>
			// `,
			data:{
				n:1
			},
			methods: {
				add(){
					console.log('add')
					this.n++
				},
				bye(){
					console.log('bye')
					this.$destroy()
				}
			},
			watch:{
				//监视n变化
				n(){
					console.log('n变了')
				}
			},
			//8个生命周期钩子
			beforeCreate() {
				console.log('beforeCreate')
			},
			created() {
				console.log('created')
			},
			beforeMount() {
				console.log('beforeMount')
			},
			mounted() {
				console.log('mounted')
			},
			beforeUpdate() {
				console.log('beforeUpdate')
			},
			updated() {
				console.log('updated')
			},
			beforeDestroy() {
				console.log('beforeDestroy')
	//这里头可以用方法,但是对页面上所有数据改动都不执行了
			},
			destroyed() {
				console.log('destroyed')
			},
		})
	</script>
</html> 
1.5 总结

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>引出生命周期</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 
				常用的生命周期钩子:
						1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
						2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。
				关于销毁Vue实例
						1.销毁后借助Vue开发者工具看不到任何信息。
						2.销毁后自定义事件会失效,但原生DOM事件依然有效。
						3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
		-->
		<!-- 准备好一个容器-->
		<div id="root">
			<h2 :style="{opacity}">欢迎学习Vue</h2>
			<button @click="opacity = 1">透明度设置为1</button>
			<button @click="stop">点我停止变换</button>
		</div>
	</body>
	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		 new Vue({
			el:'#root',
			data:{
				opacity:1
			},
			methods: {
				stop(){
					this.$destroy()
					//暴力停下,不是简单得停下定时器
//点按钮时走stop.his.$destroy(),vm被干掉了,就开始走销毁流程beforeDestroy,然后定时器也被干掉了
				}
			},
	//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
			mounted(){
				console.log('mounted',this)
				this.timer = setInterval(() => {
					console.log('setInterval')
					this.opacity -= 0.01
					if(this.opacity <= 0) this.opacity = 1
				},16)
			},
			beforeDestroy() {
			//clearInterval清除定时器
				clearInterval(this.timer)
				console.log('vm即将驾鹤西游了')
			},
		})
	</script>
</html> 
2. 非单文件组件
2.1 对组建的理解




 
粉色框是实现js所需模块,红色框是组件


单文件组件,由vue实例创建
2.2 非单文件组件
<!DOCTYPE html>//基本使用
<html>
	<head>
		<meta charset="UTF-8" />
		<title>基本使用</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 
			Vue中使用组件的三大步骤:
					一、定义组件(创建组件)
					二、注册组件
					三、使用组件(写组件标签)
			一、如何定义一个组件?
						使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;
						区别如下:
								1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
								2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
						备注:使用template可以配置组件结构。
			二、如何注册组件?
							1.局部注册:靠new Vue的时候传入components选项
							2.全局注册:靠Vue.component('组件名',组件)
			三、编写组件标签:
							<school></school>
		-->
		<!-- 准备好一个容器-->
		<div id="root">
			<hello></hello>
			<hr>
			<h1>{{msg}}</h1>
			<hr>
			<!-- 第三步:编写组件标签 -->
			<school></school>
			<hr>
			<!-- 第三步:编写组件标签 -->
			<student></student>
		</div>
		<div id="root2">
			<hello></hello>
		</div>
	</body>
	<script type="text/javascript">
		Vue.config.productionTip = false
		//第一步:创建school组件,用vue里的extend
		const school = Vue.extend({
			//模板都用template表示了
			template:`
				<div class="demo">
					<h2>学校名称:{{schoolName}}</h2>
					<h2>学校地址:{{address}}</h2>
					<button @click="showName">点我提示学校名</button>	
				</div>
			`,
// el:'#root', //组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
//组件不能写el
              data(){
//组件data一定得用函数式,每次调用都会返回一个新值(两个变量同时调,其中一个变量里把它改了另一个不会有影响,但是用对象式会有影响)
				return {
					schoolName:'尚硅谷',
					address:'北京昌平'
				}
			},
			methods: {
				showName(){
					alert(this.schoolName)
				}
			},
		})
		//第一步:创建student组件
		const student = Vue.extend({
			template:`
				<div>
					<h2>学生姓名:{{studentName}}</h2>
					<h2>学生年龄:{{age}}</h2>
				</div>
			`,
			data(){
				return {
					studentName:'张三',
					age:18
				}
			}
		})
		
		//第一步:创建hello组件
		const hello = Vue.extend({
			template:`
				<div>	
					<h2>你好啊!{{name}}</h2>
				</div>
			`,
			data(){
				return {
					name:'Tom'
				}
			}
		})
		
		//第二步:全局注册组件(组件的名字,这个组件在哪)
		Vue.component('hello',hello)
		//创建vm
		new Vue({
			el:'#root',
	//创建vm时data可以写成一个对象,组件时不可以
			data:{
				msg:'你好啊!'
			},
			//第二步:注册组件(局部注册) 参数是key;value
			//school:school合并了,第二个school是上面的变量啥名都行
			components:{
				school,
				student
			}
		})
		new Vue({
			el:'#root2',
		})
	</script>
</html> 
2.3 组件的注意点
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>几个注意点</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 
			几个注意点:
					1.关于组件名:
								一个单词组成:
											第一种写法(首字母小写):school
											第二种写法(首字母大写):School
								多个单词组成:
											第一种写法(kebab-case命名):my-school
											第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
								备注:
										(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
										(2).可以使用name配置项指定组件在开发者工具中呈现的名字。
					2.关于组件标签:
								第一种写法:<school></school>
								第二种写法:<school/>  得用脚手架环境
								备注:不用使用脚手架时,<school/>会导致后续组件不能渲染。
					3.一个简写方式:
								const school = Vue.extend(options) 可简写为:const school = options
		-->
		<!-- 准备好一个容器-->
		<div id="root">
			<h1>{{msg}}</h1>
			<school></school>
		</div>
	</body>
	<script type="text/javascript">
		Vue.config.productionTip = false
		
		//定义组件
		const s = Vue.extend({
//这得name定义的是开发者工具显示的名字,这个name不定义的话就用注册名
			name:'atguigu',
			template:`
				<div>
					<h2>学校名称:{{name}}</h2>	
					<h2>学校地址:{{address}}</h2>	
				</div>
			`,
			data(){
				return {
					name:'尚硅谷',
					address:'北京'
				}
			}
		})
		new Vue({
			el:'#root',
			data:{
				msg:'欢迎学习Vue!'
			},
			components:{
				school:s
	//注册的时候叫什么名,用的时候标签就得叫什么名儿
			}
		})
	</script>
</html> 
2.4 组件的嵌套

 
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>组件的嵌套</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 准备好一个容器-->
		<div id="root">
<!-- 容器里面干干净净,完全靠下面的代码往里面放 -->
		</div>
	</body>
	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
//套娃:将student定义为school的子组件,在school定义组件的里面定义:components:{student}
//由于要在school组件里面调用student子组件,所以student子组件必须先定义
//两个都是局部注册,school注册给了vm,但是student注册给了school
		//定义student组件
		const student = Vue.extend({
			name:'student',
			template:`
				<div>
					<h2>学生姓名:{{name}}</h2>	
					<h2>学生年龄:{{age}}</h2>	
				</div>
			`,
			data(){
				return {
					name:'尚硅谷',
					age:18
				}
			}
		})
		
		//定义school组件
		const school = Vue.extend({
			name:'school',
			template:`
				<div>
					<h2>学校名称:{{name}}</h2>	
					<h2>学校地址:{{address}}</h2>	
	//由于student组件注册给了school组件,所以vm里面没有student,调用需要从注册地调
	  //注册给谁就去谁的结构里面写
					<student></student>
				</div>
			`,
			data(){
				return {
					name:'尚硅谷',
					address:'北京'
				}
			},
			//注册组件(局部)
			components:{
				student
			}
		})
		//定义hello组件
		const hello = Vue.extend({
			template:`<h1>{{msg}}</h1>`,
			data(){
				return {
					msg:'欢迎来到尚硅谷学习!'
				}
			}
		})
		
//定义app组件,里面有所有组件(vm之下,所有组件之上,管理者),包括了子组件
//所以下面的vm里面可以只写一个app
		const app = Vue.extend({
			template:`
				<div>	
		//这么写意味着页面中hello比school先显示
					<hello></hello>
					<school></school>
				</div>
			`,
			components:{
				school,
				hello
			}
		})
		//创建vm
		new Vue({
	//要是html的div里面连<app></app>都不想写就在vm里面配置template(要带引号)
//最后结果是上面容器里的
	       template:'<app></app>',
			el:'#root',
			//注册组件(局部)
			components:{app}
		})
	</script>
</html> 
2.5 VueComponent构造函数
组件实质就是一个构造函数
每一次调用Vue.extend,都是现定义 VueComponent再返回的,所以组件之间不影响,如下
vm管理着一个个vc
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>VueComponent</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 
			关于VueComponent:
						1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。
						2.我们只需要写<school/>或<school></school>,Vue解析时会帮我们创建school组件的实例对象,
							即Vue帮我们执行的:new VueComponent(options)。
						3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!
						4.关于this指向:
								(1).组件配置中:
											data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。
								(2).new Vue(options)配置中:
											data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。
						5.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。
							Vue的实例对象,以后简称vm。
				vm在管理着一个个vc
		-->
		<!-- 准备好一个容器-->
		<div id="root">
			<school></school>
			<hello></hello>
		</div>
	</body>
	<script type="text/javascript">
		Vue.config.productionTip = false
		
		//定义school组件
		const school = Vue.extend({
			name:'school',
			template:`
				<div>
					<h2>学校名称:{{name}}</h2>	
					<h2>学校地址:{{address}}</h2>	
					<button @click="showName">点我提示学校名</button>
				</div>
			`,
			data(){
				return {
					name:'尚硅谷',
					address:'北京'
				}
			},
			methods: {
				showName(){
					console.log('showName',this)
				}
			},
		})
		const test = Vue.extend({
			template:`<span>atguigu</span>`
		})
		//定义hello组件
		const hello = Vue.extend({
			template:`
				<div>
					<h2>{{msg}}</h2>
					<test></test>	
				</div>
			`,
			data(){
				return {
					msg:'你好啊!'
				}
			},
			components:{test}
		})
		// console.log('@',school)
		// console.log('#',hello)
		//创建vm
		const vm = new Vue({
			el:'#root',
			components:{school,hello}
		})
	</script>
</html>
                

 单文件组件,由vue实例创建























