Vue-swiper组件封装

Vue-swiper组件封装

Vue封装swiper组件的方法

方法一:添加v-if判断是否创建DOM结构

在发送ajax请求回数据之前不创建DOM结构,等ajax请求回数据后创建DOM结构

<div id="box">
    <swiper v-if="datalist.length" :loop="true">
        <swiper-item v-for="data in datalist" :key="data">
            <img :src="data" />
        </swiper-item>
    </swiper>
</div>
<script>
    Vue.component("swiperItem", {
        template: `
                <div class="swiper-slide">
                    <slot></slot>
                </div>
                `
    })
    Vue.component("swiper", {
        props: {
            loop: {
                type: Boolean,
                default: true
            }
        },
        template: `
                <div class="swiper-container kerwin">
                    <div class="swiper-wrapper">
                    <slot></slot>
                    </div>
                    <div class="swiper-pagination"></div>
                </div>`,
        mounted() {
            // console.log("mounted")
            new Swiper(".kerwin", {
                // direction:"vertical", //垂直
                // 如果需要分页器
                pagination: {
                    el: '.swiper-pagination',
                },
                loop: this.loop,
                autoplay: {
                    delay: 2500,
                    disableOnInteraction: false,
                }
            })
        },
        destroyed() {
            // console.log("destroy")
        }
    })
    new Vue({
        el: '#box',
        data: {
            datalist: []

        },
        mounted() {
            setTimeout(() => {
                this.datalist = ["https://static.maizuo.com/pc/v5/usr/movie/e856bdc65507b99800f22e47801fa781.jpg",
                    "https://static.maizuo.com/pc/v5/usr/movie/47aa5a3ad2ebff403d073288e4365694.jpg",
                    "https://static.maizuo.com/pc/v5/usr/movie/8b0755547313706883acc771bda7709d.jpg"
                ]
            }, 2000)
        }
    })
</script>

方法二:添加key值,将轮播图数组的长度作为key值

原理:数组长度一开始是0(走一次mounted钩子函数),通过ajax请求回来数据后,数据发生改变,数组长度也发生了改变;新旧虚拟DOM进过diff算法对比的时候,两个组件名都叫swiper,本应该复用的,但是因为swiper的key值不一样,所以旧的swiper会被删除(会走一次destroy钩子函数),而新的swiper即将被创建出来(再走一次mouted钩子函数),这样swiper就会重新根据数组的长度,创建出来swiper组件。

即先旧swiper执行一次mounted,然后经过数据变换进行diff算法对比,通过key的不同,旧swiper会被删除,新swiper经过diff算法对比后穿件,走一遍mounted。

<div id="box">
    <swiper :key="datalist.length" :loop="true">
        <swiper-item v-for="data in datalist" :key="data">
            <img :src="data" />
        </swiper-item>
    </swiper>
</div>
<script>
    Vue.component("swiperItem", {
        template: `
                <div class="swiper-slide">
                    <slot></slot>
                </div>
                `
    })
    Vue.component("swiper", {
        props: {
            loop: {
                type: Boolean,
                default: true
            }
        },
        template: `
                <div class="swiper-container kerwin">
                    <div class="swiper-wrapper">
                    <slot></slot>
                    </div>
                    <div class="swiper-pagination"></div>
                </div>`,
        mounted() {
            // console.log("mounted")
            new Swiper(".kerwin", {
                // direction:"vertical", //垂直
                // 如果需要分页器
                pagination: {
                    el: '.swiper-pagination',
                },
                loop: this.loop,
                autoplay: {
                    delay: 2500,
                    disableOnInteraction: false,
                }
                //封装时通过属性传值来控制想要的效果,例如自动播放
            })
        },
        destroyed() {
            // console.log("destroy")
        }
    })
    new Vue({
        el: '#box',
        data: {
            datalist: []

        },
        mounted() {
            setTimeout(() => {
                this.datalist = ["https://static.maizuo.com/pc/v5/usr/movie/e856bdc65507b99800f22e47801fa781.jpg",
                    "https://static.maizuo.com/pc/v5/usr/movie/47aa5a3ad2ebff403d073288e4365694.jpg",
                    "https://static.maizuo.com/pc/v5/usr/movie/8b0755547313706883acc771bda7709d.jpg"
                ]
            }, 2000)
        }
    })
</script>

方法三:通过自定义指令

原理:在Vue中通过自定义指令知道什么时候DOM创建完成,从而进行依赖DOM的库的初始化工作。在指令中传值只能传单个,若想传多个可以以数组或者对象形式传递。

自定义指令的钩子函数:

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。
<div id="box">
    <div class="swiper-container kerwin">
        <div class="swiper-wrapper">
            <div 
                class="swiper-slide" 
                v-for="(data,index) in datalist" 
                :key="data" 
                v-swiper="{
                    index:index,
                    length:datalist.length
                }"
            >
                <img :src="data" />
            </div>
        </div>
        <!-- 如果需要分页器 -->
        <div class="swiper-pagination"></div>
    </div>
</div>
<script>
    Vue.directive("swiper", {
        inserted(el, binding) {
            //binding.value是传来的参数,el是绑定的元素
            // console.log(binding.value)
            let {
                index,
                length
            } = binding.value
            if (index === length - 1) {
                // new Swiper
                new Swiper(".kerwin", {
                    // direction:"vertical", //垂直
                    // 如果需要分页器
                    pagination: {
                        el: '.swiper-pagination',
                    },
                    loop: true,
                    autoplay: {
                        delay: 2500,
                        disableOnInteraction: false,
                    }
                })
            }
        }
    })

    new Vue({
        el: "#box",
        data: {
            datalist: [],
            myname: "kerwin"
        },
        mounted() {
            //ajax
            setTimeout(() => {
                    this.datalist = [
                            "https://static.maizuo.com/pc/v5/usr/movie/e856bdc65507b99800f22e47801fa781.jpg",
                            "https://static.maizuo.com/pc/v5/usr/movie/47aa5a3ad2ebff403d073288e4365694.jpg",
                            "https://static.maizuo.com/pc/v5/usr/movie/8b0755547313706883acc771bda7709d.jpg"
                        ]
                }, 2000)
        }
    })
</script>

方法四:通过$nextTick生命周期钩子

nextTick只会执行一次,比updated执行要晚。

this.$nextTick():将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。

Vue.nextTick():在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

缺点:无复用性

<div id="box">
    <div class="swiper-container kerwin">
        <div class="swiper-wrapper">
            <div class="swiper-slide" v-for="data in datalist" :key="data">
                <img :src="data" />
            </div>
        </div>
        <!-- 如果需要分页器 -->
        <div class="swiper-pagination"></div>
    </div>
</div>
<script>
    var vm = new Vue({
        el: "#box",
        data: {
            datalist: [],
            myname: "kerwin"
        },
        mounted() {
            //ajax
            setTimeout(() => {
                this.datalist = [
                    "https://static.maizuo.com/pc/v5/usr/movie/e856bdc65507b99800f22e47801fa781.jpg",
                    "https://static.maizuo.com/pc/v5/usr/movie/47aa5a3ad2ebff403d073288e4365694.jpg",
                    "https://static.maizuo.com/pc/v5/usr/movie/8b0755547313706883acc771bda7709d.jpg"
                ]
                this.$nextTick(() => {
                    //console.log("我比updated执行的都晚,而且只执行一次")
                    new Swiper(".kerwin", {
                        // direction:"vertical", //垂直
                        // 如果需要分页器
                        pagination: {
                            el: '.swiper-pagination',
                        },
                        loop: true,
                        autoplay: {
                            delay: 2500,
                            disableOnInteraction: false,
                        }
                    })
                })
            }, 2000)
        },
        updated() {
            //console.log("updated")
        }
    })
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hoki802

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值