常用的生命周期钩子:
1.mounted: 挂载,vue完成模板解析,并把真实DOM放到页面后(挂载完毕),调用mounted,发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。
关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生DOM事件依然有效。
3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
组件:
非单文件组件:
一个文件有n个组件
单文件组件:
一个文件只有一个组件
一、定义组件(创建组件)
使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;
const vm1=Vue.extend(
template:"<div>
<标签一>{{key1}}</标签一>
<标签一>{{key2}}</标签一>
<div>"
data(){
return{
key1:value
key2:value
}
}
)
区别如下:
1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。
二、注册组件
1.局部注册:靠new Vue的时候传入components选项
new Vue(
el:“#id”
components:{
component(组件名):vm1
}
)
2.全局注册:靠Vue.component(‘组件名’,组件)
Vue.component(‘vm1’,vm1)
三、使用组件(写组件标签)
<div id="">
<component></component>
</div>
<body>
<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组件
const school = Vue.extend({
template:`
<div class="demo">
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名</button>
</div>
`,
// el:'#root', //组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
data(){
return {
schoolName:'XXXXX',
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',
data:{
msg:'你好啊!'
},
//第二步:注册组件(局部注册)
components:{
school,
student
}
})
new Vue({
el:'#root2',
})
</script>
四、注意
1.关于组件名:
一个单词组成:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
<school></school>
<script type="text/javascript">
Vue.config.productionTip = false
//定义组件
const s = Vue.extend({
name:'atguigu',
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
`,
data(){
return {
name:'张三',
address:'湖北'
}
}
})
new Vue({
el:'#root',
data:{
},
components:{
//school:s
School:s
}
})
</script>
多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)
<my-school></my-school>
<script type="text/javascript">
Vue.config.productionTip = false
//定义组件
const s = Vue.extend({
name:'xuexiao',
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
`,
data(){
return {
name:'张三',
address:'湖北'
}
}
})
new Vue({
el:'#root',
data:{
msg:'欢迎学习Vue!'
},
components:{
//school:s
'my-school':s
}
})
</script>
备注:
(1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
(2).可以使用name配置项指定组件在开发者工具中呈现的名字。
const vm1=Vue.extend(
name:‘xuexiao’
template:‘’
data(){
return{
}}
)
案例同上
2.关于组件标签:
第一种写法:
<school></school>
第二种写法:
<school/>
不用使用脚手架时,<school/>会导致后续组件不能渲染。
3.一个简写方式:
const school = Vue.extend(options) 可简写为:const school = options
五、组件嵌套
真实开发中只有一个vue实例,和多个组件搭配使用,组件之间,可以嵌套,通过component实现;最内层组件最先定义
<body>
<!-- 准备好一个容器-->
<div id="root">
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
const student=Vue.extend({
name:'student',
template:`<table>
<tr><td>学号</td><td>姓名</td></tr>
<tr v-for="(s,index) of students">
<td>{{s.sno}}</td>
<td>{{s.sname}}</td>
</tr>
</table>`,
data() {
return {
students:[
{sno:1, sname:"张三"},
{sno:2, sname:"李四"},
{sno:3, sname:"王五"}
]
}
},
})
const teacher=Vue.extend({
name:'teacher',
template:`<div>{{tname}}
<student></student>
</div>`,
data() {
return {
tname:"张老师"
}
},
components:{student}
})
new Vue({
el:"#root",
data:{classname:"班级名"},
template:`<div>{{classname}}<teacher></teacher></div>`,
components:{teacher}
})
</script>
六、VueComponent
组件的构造函数
<body>
<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>xuexiao</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>
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。
内置关系
VueComponent(组件)的实例对象不是vue实例对象
el这种根实例是vue实例特有的。
用Java语言来说就是vueComponent(组件)实例对象继承vue原型
1.一个重要的内置关系:VueComponent.prototype.proto === Vue.prototype
2.组件实例对象(VueComponent)通过这个内置关系可以访问到 Vue原型上的属性、方法。
<body>
<!-- 准备好一个容器-->
<div id="root">
<school></school>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
Vue.prototype.x = 99
//定义school组件
const school = Vue.extend({
name:'school',
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showX">点我输出x</button>
</div>
`,
data(){
return {
name:'学校',
address:'地址'
}
},
methods: {
showX(){
console.log(this.x)
}
},
})
//创建一个vm
const vm = new Vue({
el:'#root',
data:{
msg:'你好'
},
components:{school}
})
//定义一个构造函数
/* function Demo(){
this.a = 1
this.b = 2
}
//创建一个Demo的实例对象
const d = new Demo()
console.log(Demo.prototype) //显示原型属性
console.log(d.__proto__) //隐式原型属性
console.log(Demo.prototype === d.__proto__)
//程序员通过显示原型属性操作原型对象,追加一个x属性,值为99
Demo.prototype.x = 99
console.log('@',d) */
</script>
七、单文件组件
- 命名
单个单词:
纯小写:school.vue;
首字母大写:School.vue
多个单词:
纯小写,单词之间“-”连接:my-school.vue
每个首字母大写:MySchool.vue
2.三个主要标签
<template>
</template>
内部写组件的结构,类似html
<script></sript>
内部写组件交互相关代码,类似js
<style></style>
内部写组件样式,类似css外部样式
3.三种 暴露方式
分别暴露
<script>
export const teacher=Vue.extend({
data() {
return {
tname:"张老师"
}
},
}
)
</script>
统一暴露
<script>
const teacher=Vue.extend({
data() {
return {
tname:"张老师"
}
},
}
)
export{teacher}
</script>
默认暴露:
const teacher=Vue.extend({…})
export defaul teacher
或简写为:
<script>
export default {
name:teacher,
data() {
return {
tname:"张老师"
}
},
}
</script>
4.引入组件
<script>
import Teacher from './teacher.vue'
</script>