插槽与生命周期

  • 2.5 slot slot-scope

    • 具名插槽
    • slot-scope
  • 2.6 v-slot

    • v-slot
  • slot:插槽作用

    • 开辟一个空间,给未来元素使用
    • 名词解释:未来元素–就是组件内容

    注:组件的内容 会被组件模板覆盖 想要这个内容保留下来 就用slot插槽

<div id="app">
        <Hello>
                <p>这里是组件内容</p>
        </Hello>
    </div>
    
    <template id="hello">
        <div>
            <p>这是组件模板</p>
            <slot></slot>
        </div>
    </template>

    <script src="../../lib/vue.js"></script>
    <script>
        Vue.component("Hello",{
            template:"#hello"
        })
        // new Vue({
        //     el:"#app"//自动挂载
        // })

        new Vue({
        }).$mount('#app')  //手动挂载
    </script>
具名插槽:
<div id="app">
        <Con>
            <header slot="heard">头部</header><!--具名插槽  有具体的名子的插槽  -->
            <footer>尾部</footer>
        </Con>
    </div>

    <template id="con">
        <div>
            <slot name="heard"></slot><!--具名插槽  有具体的名子的插槽  -->
            <p>这里是中间内容</p>
            <slot></slot>
        </div>
    </template>


<script src="../../lib/vue.js"></script>
    <script>
        Vue.component("Con",{
            template:"#con"
        })

        new Vue({
            el:"#app"
        })
    </script>
 作用域插槽:
 <div id="app">
        <Con>
          <template v-slot:default="info">  <!-- v-slot只能绑定在template标签上 -->
            {{info.aa}}
           </template>
        </Con>       
                
    </div>

    <template id="con">
        <div>
         <p>这里是组件模板</p>
         <slot :aa="msg"></slot>
        </div>
    </template>


<script src="../../lib/vue.js"></script>
    <script>
        // v-slot的目的是将slot组件身上的数据传递给绑定的未来元素
        Vue.component("Con",{
            template:"#con",
            data(){
                return{
                    msg:"这里是数据"
                }
            }
        })

        new Vue({
            el:"#app"
        })
    </script>
  1. 组件的生命周期 【 组件的钩子有哪些? 】

    • 为什么要使用生命周期?
    • 想要使用组件,那么就得在组件的特定阶段完成特定的任务 【 特定时间点,完成特定任务 】
    • 名词: 钩子:
      • 钩子:特点时间点,触发的一个方法

组件的生命周期

  • 生命周期分为三个阶段:初始化,运行中,销毁,一共8个钩子

    • 生命周期钩子不允许使用箭头函数,因为箭头函数会改变this指向

    • 初始化 (4个钩子)

      • beforeCreat(){}

        • 组件即将创建

        • 任务:初始化事件,并为整个生命周期做准备

        • 意义:

          • 无法获取数据,无法获取的真实的dom
          • 可以进行数据请求,和修改数据
      • created(){}

        • 创建组件结束
        • 任务:进行数据的注入和数据的反应(数据反应就是数据的修改)
        • 意义:
          • 获取到数据,但未获取到真实dom
          • 可以进行数据的请求和数据的修改时
      • beforeMount(){}

        • 组件即将挂载
        • 任务:判断组件是否含有el/template选项,如果含有,直接使用render函数将template模板中的jsx转换成VDOM对象模型,如果没有,需要我们使用$mount(对应el)/outerHTML(对应template)进行手动挂载,–(outerHTML也可以类似于innerHTML作为补办结构书写,但是他会把外层结构消除掉)
        • 意义:
          • 更多的是内部完成任务,外部就不干预了
          • 可以进行数据请求和数据修改
      • mountde(){}

        • 组件挂载完成
        • 任务:将vdom渲染成真实的dom,然后挂载到页面上,这时候可以在页面中看到内容了
        • 意义:
          • 拿到真实的dom,操作真实的dom 【可以进行第三方库实例化】
          • 可以进行数据请求和数据修改
      • 总结:

        • 将数据请求放在created里面,因为created是第一次获取到数据的地方
        • mounted钩子函数可以进行DOM操作【可以进行第三方库实例化【静态数据】】
    <div id="app">
            <p>{{msg}}</p>
    </div>
    
    <script src="../../lib/vue.js"></script>
    <script>
    new Vue({
        el:'#app',
        data:{
            msg:'你好  今天周三'
        },
        // 组件即将创建
        beforeCreate(){
            console.log('1-beforeCreate')//1-beforeCreate
            console.log(this.msg)   //undfined     数据未获取
            console.log(document.querySelector('#app'))  //<p>{{msg}}</p>   此时是Vdom  真实dom没拿到
            fetch('./data/data1.json')
                .then(res=>res.json())
                .then(data=>{
                    // console.log(data)
                    // console.log(this.msg)   //??
                    this.msg=data.name      //??
                //    console.log(this.msg=data.name) 
                })
                .catch(error=> console.log(error))
        },
        // 组件创建结束
        created(){
            console.log('2-created')     //2-created
            console.log(this.msg)       //拿到数据
            console.log(document.querySelector('#app'))//未获得真实dom 
            fetch('./data/data2.json')
                .then(res=>res.json())
                .then(data=>{
                    // console.log(data)
                    this.msg=data.name
                })
                .catch(error=>console.log(error))
        },
        beforeMount(){
            console.log('3-beforeMount')     //3-beforeMount
            console.log(this.msg)       //拿到数据
            console.log(document.querySelector('#app'))//未获得真实dom 
            fetch('./data/data2.json')
                .then(res=>res.json())
                .then(data=>{
                    // console.log(data)
                    this.msg='李四'
                })
                .catch(error=>console.log(error))
        },
        mounted(){
            console.log('4-Mount')     //3-beforeMount
            console.log(this.msg)       //拿到数据
            console.log(document.querySelector('#app'))//获得真实dom   <p>王五</p>    可以操作真实dom
            // 测试是否可以操作真实dom
            document.querySelector('p').style.background="red" 
    
            
            fetch('./data/data2.json')
                .then(res=>res.json())
                .then(data=>{
                    // console.log(data)
                    this.msg='王五'
                })
                .catch(error=>console.log(error))
        },
        // beforeUpdate(){
        //     // 触发条件 组件数据发生改变
        //     console.log(this.msg)
        //     console.log('beforeUpdate')
        //     console.log(this.flag)//获取到改变后的数据
        //     console.log(document.querySelector('#app'))//拿到真实dom
        // },
    })
    
    </script>
    
    • 运行中 (2个钩子)
      • beforeUpdate(){} 组件更新之前
        • 触发条件:逐渐的数据发生改变(这个数据指的是view层的数据变化 不是data中的数据改变https://www.cnblogs.com/xiaobaibubai/p/8383952.html)
        • 任务:VDOM重新生成,然后通过diff算法和以前的VDOM进行比对,生成patch补丁对象【内部进行】
      • updated(){} 组件更新之后
        • 触发条件:逐渐的数据发生改变(这个数据指的是view层的数据变化 不是data中的数据改变https://www.cnblogs.com/xiaobaibubai/p/8383952.html)
        • 任务:将patch补丁对象渲染成真实dom
        • 意义:
          • 可以操作dom【第三方库的实例化【 动态数据 】】
      • 总结: 使用updated进行第三方库实例化
     <div id="app">
                <button @click="flag=!flag">确定</button>
                <p v-if="flag">你好</p><!--   (这个数据指的是view层的数据变化   不是data中的数据改变-->
     </div>
    
    <script src="../../lib/vue.js"></script>
    <script>
        new Vue({
        el:'#app',
        data:{
            msg:'sss',
            flag:false
        },
        // mounted(){
        //     fetch('./data/data2.json')
        //         .then(res=>res.json())
        //         .then(data=>{
        //             // console.log(data)
        //             this.msg='王五'
        //         })
        //         .catch(error=>console.log(error))
        // },
        beforeUpdate(){
            // 触发条件 组件数据发生改变
            console.log(this.msg)
            console.log('beforeUpdate')
            console.log(this.flag)//获取到改变后的数据
            console.log(document.querySelector('#app'))//拿到真实dom
        },
        updated(){
            console.log('update')
            console.log(this.flag)//获取到改变后的数据
            console.log(document.querySelector('#app'))//拿到真实dom
        }
        })
    </script>
    
    • 销毁

      • 意义: 用来完成善后工作 【 计时器, 第三库实例, window.onscroll 】

      • 组件的销毁有两种形式

        • 内部销毁 $destroy
          • 组件会被销毁掉,但是组件的DOM外壳还在
        <div id="app">
                <button @click="remove">销毁</button>
        </div>
        
        <script src="../../lib/vue.js"></script>
        <script>
            new Vue({
                el: '#app',
                created(){//组件创建完成   所以都会走这一步  
                    this.dsq=setInterval(()=>{
                        console.log('hello')   //组件和组件的dom都已经销毁了   但是   定时器还在继续执行   所以需要将定时器销毁
                    },1000)
        
                    this.obj={   //在内存的堆里开辟一个内存存储这个对象    但是销毁组件时这个内存并没有销毁   所以需要销毁这个内存
                        name:"sss"
                    }
                },
                methods:{
                    remove(){
                        //组件的销毁会触发钩子函数beforeDestroy
                       this.$destroy() //内部销毁  只能销毁组件   但是组件的dom外壳并没有被销毁
                    }
                },
                beforeDestroy(){
                    console.log(document.querySelector('#app'))
                    document.querySelector('#app').remove()  //删除组件dom外壳
                    clearInterval(this.dsq)//清除计时器
                    delete this.obj
                }
            })
        </script>
        
        • 外部销毁
          • 通过开关销毁 【 推荐 】
          • 组件会被销毁掉,组件的DOM外壳一起被销毁
        <div id="app">
                <button @click="flag=!flag">销毁</button><!--  外部销毁   直接将组件销毁  并且组件的dom一起被销毁  -->
                <Hello v-if="flag"></Hello>
            </div>
        </body>
        <script src="../../lib/vue.js"></script>
        <script>
            Vue.component("Hello",{
                template:"<p>你好</p>" , 
                destroyed(){
                console.log('destroyed')
            }
            })
            new Vue({
                el: '#app',
                data:{
                    flag:true
                }
            })
        </script>
        
        • 组件的销毁会触发两个钩子函数
          • beforeDestroy () {} 销毁前
          • destroyed () {} 销毁结束

    案例:

    ​ 1:swiper动态渲染

     <link href="https://cdn.bootcss.com/Swiper/4.5.0/css/swiper.css" rel="stylesheet">
      <script src="https://cdn.bootcss.com/Swiper/4.5.0/js/swiper.js"></script>
    <style>
        .swiper-container {
          width: 600px;
          height: 300px;
        }
      </style>
    </head>
    
    <body>
      <div id="app">
        <input type="text" name="" id="" v-model="num">
        <div class="swiper-container">
          <div class="swiper-wrapper">
            <div class="swiper-slide" v-for="item in banner" :key="item.id">
              <img :src="item.img" style = "width: 100%;height: 100%;">    <!--  动态数据      -->
            </div>
          </div>
          <!-- 如果需要分页器 -->
          <div class="swiper-pagination"></div>
    
          <!-- 如果需要导航按钮 -->
          <div class="swiper-button-prev"></div>
          <div class="swiper-button-next"></div>
    
          <!-- 如果需要滚动条 -->
          <div class="swiper-scrollbar"></div>
        </div>
      </div>
    </body>
    <script src="../../lib/vue.js"></script>
    <script>
      new Vue({
        el: "#app",
        data:{
          banner:[],
          num:12
        },
        created(){
          fetch('./data/data3.json')//fetch异步请求
            .then(res=>res.json())
            .then(data=>{
              this.banner=data
              console.log(this.banner)
              console.log(data)
            })
            .catch(error=>console.log(error))
        },
        updated() {//此时数据是动态的   所以需要使用updated
          console.log('数据改变   触发updated')//数据改变   触发updated,触发一次updated就会重新实例化mySwiper  消耗性能
            // 解决方案1  
            if(this.mySwiper)  return false
    
    
          this.mySwiper = new Swiper('.swiper-container', {    //这里获取了真实的dom   能够获取都真实dom有两个钩子   这是上面是动态数据  所以使用updated
            loop: true, // 循环模式选项
    
            // 如果需要分页器
            pagination: {
              el: '.swiper-pagination',
            },
    
            // 如果需要前进后退按钮
            navigation: {
              nextEl: '.swiper-button-next',
              prevEl: '.swiper-button-prev',
            },
    
            // 如果需要滚动条
            scrollbar: {
              el: '.swiper-scrollbar',
            },
          })
        },
        destroyed(){
          delete this.mySwiper
        }
      })
    </script>
    

    2:swiper静态渲染

    <link href="https://cdn.bootcss.com/Swiper/4.5.0/css/swiper.css" rel="stylesheet">
      <script src="https://cdn.bootcss.com/Swiper/4.5.0/js/swiper.js"></script>
      <style>
        .swiper-container {
          width: 600px;
          height: 300px;
        }
      </style>
    </head>
    
    <body>
      <div id="app">
        <div class="swiper-container">
          <div class="swiper-wrapper">
            <div class="swiper-slide">Slide 1</div>
            <div class="swiper-slide">Slide 2</div>
            <div class="swiper-slide">Slide 3</div><!--   静态数据      -->
          </div>
          <!-- 如果需要分页器 -->
          <div class="swiper-pagination"></div>
    
          <!-- 如果需要导航按钮 -->
          <div class="swiper-button-prev"></div>
          <div class="swiper-button-next"></div>
    
          <!-- 如果需要滚动条 -->
          <div class="swiper-scrollbar"></div>
        </div>
      </div>
    </body>
    <script src="../../lib/vue.js"></script>
    <script>
      new Vue({
        el: "#app",
        mounted() {//此时数据是静态的
          this.mySwiper = new Swiper('.swiper-container', {    //这里获取了真实的dom   能够获取都真实dom有两个钩子   这是上面是静态数据  所以使用mounted
            loop: true, // 循环模式选项
    
            // 如果需要分页器
            pagination: {
              el: '.swiper-pagination',
            },
    
            // 如果需要前进后退按钮
            navigation: {
              nextEl: '.swiper-button-next',
              prevEl: '.swiper-button-prev',
            },
    
            // 如果需要滚动条
            scrollbar: {
              el: '.swiper-scrollbar',
            },
          })
        },
        destroyed(){
          delete this.mySwiper
        }
      })
    </script>
    

5:自定义过滤器

  • 注意点:

    • 是对已有数据进行格式化
    • 过滤器也可以传递参数
    • 过滤器要使用管道符才能起作用
  • 分类

    • 全局过滤器 Vue.filter(过滤器名称,回调函数)

    • 局部过滤器 filters选项

      filters: {
          //过滤器名称: 回调函数
          'dateFilter': ( val,type) => {
                var date = new Date( val )
                return date.getFullYear() + type + ( date.getMonth() + 1 ) +type+ date.getDate()
            }
      }
      
  • 使用:

    • {{ 要格式化的数据 | 过滤器名称 }}
    • | 管道符
    • Vue.filter(过滤器名称,过滤器的回调函数 )或者filters:{过滤器名称:过滤器的回调函数 )}
    • 注:回调函数中的返回值是什么,格式化后的数据就是什么
 局部过滤器
<div id="app">
        <p>{{time|dateFilter("-")}}</p>
 </div>
 <script src="../../lib/vue.js"></script>
 <script>
    new Vue({
        el:"#app",
        data:{
            time:Date.now()//Date.now()时间戳或者 date.getTime()
        },
        filters:{
            "dateFilter":(val,type)=>{
            var date = new Date( val ) //val就是要过滤的数据
            return date.getFullYear() + type + ( date.getMonth() + 1 ) +type+ 			date.getDate()
        }
        }
    })
</script>
全局过滤器:
<div id="app">
         <p>{{time|dateFilter("-")}}</p> <!--dateFilter("-")  函数的实参   可以没有 -->
    </div>
</body>
<script src="../../lib/vue.js"></script>
<script>
 Vue.filter("dateFilter",(val,type)=>{//val就是要过滤的数据
            var date = new Date( val )
            return date.getFullYear() + type + ( date.getMonth() + 1 ) +type+ date.getDate()
        })
    
    new Vue({
        el:"#app",
        data:{
            time:Date.now()
        }
    })

</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值