一.什么是生命周期?
在vue中,生命周期就是vue实例程序从创建到销毁的这个过程,在生命周期中,不同阶段我们可以做不同的事情。vue的生命周期是创建阶段、挂载阶段、更新阶段、销毁阶段
二.什么是钩子函数?
钩子函数就是生命周期中的回调函数,在vue中,有8个生命周期的钩子函数
------------>创建阶段
创建之前执行的钩子函数 beforeCreate
创建后执行的钩子函数 created 用来做初始化数据
------------->挂载阶段
挂载之前执行的钩子函数 beforeMount
挂载后执行的钩子函数 mounted 进行dom操作
------------------>更新阶段 数据发生改变才执行的回调函数
更新之前执行的钩子函数 beforeUpdate
更新之后执行的钩子函数 updated
------------------->销毁阶段 程序的卸载 ,显示和隐藏 v-if
销毁之前执行的钩子函数 beforeDestroy
销毁之后执行的钩子函数 destroyed
三.组件
1.什么是组件
组件就是一个功能 ,相当于vue实例,可复用的vue实例
定义全局组件
//1.全局定义组件
const ElButton = {
// 设置数据
data() {
return {
message: "这是一个按钮123"
}
},
// 渲染模板
template: `
<div>
<div>{{message}}</div>
<button @click="foo" style="padding: 10px 20px; border: 0; background-color: skyblue; color: white;">
点击按钮
</button>
</div>
`,
// 设置方法
methods: {
// 提示
foo(){
alert("您好,触发事件。。。")
}
}
}
2.注册全局组件
Vue.component('el-button',ElButton)
定义局部组件
new Vue({
//挂载容器
el: "#app",
// 注册组件(此处表示局部注册)
components: {
// 此处注册组件名称采用驼峰命名“ElSearch”,在使用的时候需要改成 “el-search”
// "el-search": {},
"ElSearch": {
data(){
return {
}
},
template: `
<div>
<input type="text" placeholder="请输入关键字" style="width: 90%;height: 40px;">
</div>
`
},
}
})
2.注册组件时需要注意的事项!!!
1.采用驼峰命名法注册组件名称时“ElSearch”,使用组件时需要改用短横线 “el-search”
2.不能使用html文档内置的标签名称作为组件名称例如 div hearder footer nav
可以采用自定义的 例如Elbutton ComHeader
3.组件 中的data 必须返回的是一个对象 data(){}
4.template 选项需要有根节点 <div></div>
5.组件中的属性计算、侦听、过滤以及生命周期的钩子函数和vue实例写法一致
3.组件嵌套关系 (父组件嵌套子组件)
//定义子组件
const ElementChild = {
template: `
<div>
<h3>子组件</h3>
</div>
`
}
//定义父组件
const ElementParent = {
template: `
<div>
<h2>父组件</h2>
<element-child></element-child>
</div>
`,
// !!!注意是在父组件中注册子组件
components: {
ElementChild
}
}
new Vue({
//挂载容器
el: "#app",
// 在vue实例中注册父组件
components: {
ElementParent
}
})
四.组件传值
1.父组件传值给子组件(自定义属性)
父组件传值给子组件,子组件通过props自定义属性,在父组件的template中的子组件中,通过v-bind绑定那个自定义属性,传入父组件的数据
const ElementChild = {
// 父组件传值需要子组件自定义属性
// 通过在props选项中自定义属性接收父组件传递的数据 props: ['xxx'],
props:{
xxx:{
// 未传参数
default:'默认值',
// 传递了参数
type:[String,Number]
}
},
template: `
<div>
<h3>子组件</h3>
<p>{{xxx}}</p>
</div>
`,
};
// 父组件
const ElementParent = {
// 设置数据
data(){
return {
// 传值数据可写可不写(但必须要有自定义的操作)
message: "这是父组件的数据"
}
},
template: `
<div>
<h2>父组件</h2>
<element-child v-bind:xxx="message"></element-child>
<element-child :xxx="100"></element-child>
<element-child></element-child>
</div>
`,
// 在父组件中注册子组件
components: {
ElementChild
}
}
2.子组件传值给父组件(事件)
子组件的数据,在初始化钩子函数中通过this.$emit(自定义事件,数据),在父组件中通过methods定义方法get(data){}接收该数据,在父组件的template子组件中使用该自定义的事件 @自定义事件="get"
// 要定义了子组件才能用在父组件上
const ElementChild = {
data(){
return {
num:100
}
},
template: `
<div>
<h3>子组件</h3>
<button @click="add">发送数据</button>
</div>
`,
methods:{
add(){
this.num--;
// 自定义事件把数据传入
// this.$emit('child-num',{cnum:this.num})
}
},//也可以采用钩子函数 不需要点击把数据传递给父组件
// 在初始化页面就传值
created(){
this.$emit('child-num',{cnum:this.num})
}
};
const ElementParent = {
data(){
return {
num:0
}
},
// 在模板中使用子组件自定义的事件
template: `
<div>
<h3>父组件</h3>
<p v-if="num!=0">{{num}}</p>
<element-child @child-num="jieshou"></element-child>
</div>
`,
components: {
ElementChild,
},
methods:{
// 子组件传递的数据自定义
jieshou(data){
this.num=data.cnum
}
}
};
3.兄弟传值 (桥梁)
通过创建一个新的vue实例,其中一个组件通过 新的实例名称.$emit('xxx',this.num) ,
// 通过桥梁传值,创建一个新的vue实例
const bridge=new Vue()
const CompA={
data(){
return{
num:100
}
},
// 2.可以通过事件进行使用该方法
template:`
<div>
<h3>A组件</h3>
<button @click="senda">点击发送</button>
</div>
`,
methods:{
// a发送的方法
senda(){
bridge.$emit('xxx',this.num)
}
},
// 1.通过初始化created钩子延迟函数异步传递使用方法
// 此处必须要用异步代码延迟,因为组件a与组件b是合并关系
created(){
setTimeout(()=>{
// this.senda()
},10)
}
}
const CompB={
data(){
return {
num:0
}
},
template:`
<div>
<h3>B组件</h3>
<p>{{num}}</p>
</div>
`,
// b接收a通过自定义属性传递的参数
created(){
bridge.$on('xxx',(value)=>{
this.num=value
})
}
}
4.Vue原型添加数据
挂载到原型的数据可以给构造函数的实例去使用,但是添加到原型上的数据没有响应式
//在此点击事件,num的值是不会有变化的,因为该num值是通过原型添加的
<button @click="changeNum">点击num++</button>
<comp-header></comp-header>
<comp-footer></comp-footer>
Vue.prototype.num = 100;
const CompHeader = {
template: `
<header>
<h3>头部组件</h3>
<p>{{num}}</p>
</header>
`,
};
const CompFooter = {
template: `
<footer>
<h3>尾部组件</h3>
<p>{{num}}</p>
</footer>
`,
};
new Vue({
//挂载容器
el: "#app",
components:{
CompHeader,
CompFooter
},
methods:{
changeNum(){
this.num++
console.log(this.num);
}
}
});