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


















