一.什么是生命周期?
在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);}}});