第五节:Vue进阶

1 slot插槽 (内容分发)

a. 单个slot 
b. 具名slot
    *混合父组件的内容与子组件自己的模板-->内容分发
    *父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。

1.1 基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="box">
    <!-- 不使用插槽写的aaa不会显示,使用就会显示-->
    <child1>aaa</child1>

</div>
</body>
<script>
    var bus = new Vue() //new一个vue的实例,就是中央事件总线
    Vue.component('child1', {
        template: `<div>
          首页
          <slot></slot>
        </div>`,

    })
 var vm = new Vue({
        el: '#box',

    })
</script>
</html>

1.2 插槽应用场景1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<!--    写了一个轮播组件,用户想轮播什么就放什么-->
    <swiper>
        <p v-for="data in 4">{{data}}</p>
    </swiper>

       <swiper>
           <img :src="data" v-for="data in 5">
    </swiper>

</div>
</body>
<script>
    var bus = new Vue() //new一个vue的实例,就是中央事件总线
    Vue.component('swiper', {
        template: `<div>
          <slot></slot>
        </div>`,

    })
 var vm = new Vue({
        el: '#box',

    })
</script>
</html>

1.3 插槽应用场景2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="box">
    <!--通过插槽实现在一个组件中控制另一个组件的显示隐藏-->
    <navbar> <button @click="isShow=!isShow">点我显示隐藏</button></navbar>

    <swiper v-if="isShow"></swiper>
</div>
</body>
<script>
    Vue.component('navbar', {
        template: `<div>
          navbar
          <slot></slot>
        </div>`,

    })
    Vue.component('swiper', {
        template: `<div>
          <p>111</p>
          <p>222</p>
          <p>333</p>
        </div>`,

    })
    var vm = new Vue({
        el: '#box',
        data:{
            isShow:true
        }

    })
</script>
</html>

1.4 具名插槽

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<!--    具名插槽,把p标签给a插槽,div标签给b插槽-->
    <navbar>
        <p slot="a">pppp</p>
        <div slot="b">bbbb</div>
    </navbar>
</div>
</body>
<script>
    Vue.component('navbar', {
        template: `<div>
        <slot name="a"></slot>
          navbar
          <slot name="b"></slot>
        </div>`,

    })
var vm = new Vue({
        el: '#box',
        data:{

        }

    })
</script>
</html>

2 transition过渡

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
(1)单元素/组件过渡  * css过渡  * css动画  * 结合animate.css动画库
(2) 多个元素过渡(设置key) 
     *当有相同标签名的元素切换时,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。  
      mode:in-out ; out-in
(3)多个组件过渡
(4)列表过渡(设置key) 
     *<transition-group>不同于 transition, 它会以一个真实元素呈现:默认为一个 <span>。你也可以通过tag 特性更换为其他元素。  
     * 提供唯一的 key 属性值

3 生命周期

    i. 生命周期各个阶段https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA
    ii. 生命周期钩子函数的触发条件与作用

4 swiper学习

https://www.swiper.com.cn/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>

    <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css">
    <script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
    <!--    <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.css">  -->
    <!--<script src="https://unpkg.com/swiper/swiper-bundle.js"> </script>  -->
    <style>
        .swiper-container {
            width: 80%;
            height: 600px;
        }
    </style>

</head>
<body>
<div id="box">

    <div class="swiper-container">
        <div class="swiper-wrapper">
            <div class="swiper-slide" v-for="data in datalist">

                {{data}}
                <img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608145297276&di=dd396caeaa0bb6a2a50609a109cd3120&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2Fday_110915%2F1109151356c0717d7e6a91e985.jpg" alt="">
            </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>
    var vm = new Vue({
        el: '#box',
        data: {
            datalist: [],
        },
        mounted() {
            setTimeout(() => {
                this.datalist = ['111', '222', '333']
            }, 2000)
            //轮播图初始化不是放在这,因为数据变化和dom更新是异步的
            //需要放在updated中
        },
        updated() {
            var mySwiper = new Swiper('.swiper-container', {
                // direction: 'vertical', // 垂直切换选项
                loop: true, // 循环模式选项
                // 如果需要分页器
                pagination: {
                    el: '.swiper-pagination',
                },
                // 如果需要前进后退按钮
                navigation: {
                    nextEl: '.swiper-button-next',
                    prevEl: '.swiper-button-prev',
                },

                // 如果需要滚动条
                scrollbar: {
                    el: '.swiper-scrollbar',
                },

            })
        },

    })
</script>
</html>

5 自定义组件的封装

​ 自定义封装swiper组件(基于swiper)
​ 注意: 防止swipe初始化过早

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>

    <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css">
    <script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
    <!--    <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.css">  -->
    <!--<script src="https://unpkg.com/swiper/swiper-bundle.js"> </script>  -->
    <style>
        .swiper-container {
            width: 80%;
            height: 600px;
        }
    </style>

</head>
<body>
<div id="box">
    {{name}}
<!--    diff算法检测到key变化了,会把swipper删掉,重新创建,触发组件的mounted执行,完成swipper实例化,不在updated中初始化-->
<!--    子组件的mounted在根组件的mounted之前执行,所有组件挂载完成后,根组件才挂载-->
    <swipper :key="datalist.length">
<!--    <swipper>-->
        <div class="swiper-slide" v-for="data in datalist">
            <img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608145297276&di=dd396caeaa0bb6a2a50609a109cd3120&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2Fday_110915%2F1109151356c0717d7e6a91e985.jpg" alt="">
        </div>
    </swipper>
</div>
</body>
<script>

    Vue.component('swipper',{
        template:`
        <div class="swiper-container">
        <div class="swiper-wrapper">
          <slot></slot>
        </div>
        <div class="swiper-pagination"></div>
        <div class="swiper-button-prev"></div>
        <div class="swiper-button-next"></div>
        <div class="swiper-scrollbar"></div>
    </div>
        `,
        mounted(){
            console.log('子组件mounted')
            var mySwiper = new Swiper('.swiper-container', {
                // direction: 'vertical', // 垂直切换选项
                loop: true, // 循环模式选项
                // 如果需要分页器
                pagination: {
                    el: '.swiper-pagination',
                },
                // 如果需要前进后退按钮
                navigation: {
                    nextEl: '.swiper-button-next',
                    prevEl: '.swiper-button-prev',
                },

                // 如果需要滚动条
                scrollbar: {
                    el: '.swiper-scrollbar',
                },

            })
        },

        // updated(){//如果跟组件中有数据变化,就会导致swipper组件触发update(vm.name='ss'测试一下),导致多次执行,影响效率,所以使用key+mounted方式
        //     console.log('子组件update')
        //     var mySwiper = new Swiper('.swiper-container', {
        //         // direction: 'vertical', // 垂直切换选项
        //         loop: true, // 循环模式选项
        //         // 如果需要分页器
        //         pagination: {
        //             el: '.swiper-pagination',
        //         },
        //         // 如果需要前进后退按钮
        //         navigation: {
        //             nextEl: '.swiper-button-next',
        //             prevEl: '.swiper-button-prev',
        //         },
        //
        //         // 如果需要滚动条
        //         scrollbar: {
        //             el: '.swiper-scrollbar',
        //         },
        //
        //     })
        // }

    })
    var vm = new Vue({
        el: '#box',
        data: {
            name:'lqz',
            datalist: [],
        },
        mounted() {
            setTimeout(() => {
                this.datalist = ['111', '222', '333']
            }, 2000)
            //轮播图初始化不是放在这,因为数据变化和dom更新是异步的
            //需要放在updated中
        },

    })
</script>
</html>

6 自定义指令

(1)自定义指令介绍 directives
(2)钩子函数* 参数 el,binding,vnode(vnode.context)* bind,inserted,update,componentUpdated,unbind
(3)函数简写
(4)自定义指令-轮播
    *inserted 插入最后一个元素时调用(vnode.context.datalist.length-1)
    *this.$nextTick()

6.1 基本使用

联系管理员微信tutu19192010,注册账号

上一篇
下一篇
Copyright © 2022 Egon的技术星球 egonlin.com 版权所有 帮助IT小伙伴学到真正的技术